2013-10-23 8 views
6

Soweit ich verstehe, sollte ich in der Lage sein, RSA zu verwenden, um Authentizität oder Privatsphäre zu gewährleisten, wie ich es wünsche. In meinem Fall möchte ich die Authentizität sicherstellen, also verschlüssle ich die Daten mit dem privaten Schlüssel und erlaube jedem, sie mit dem öffentlichen Schlüssel zu entschlüsseln. Die Daten sind nicht wirklich geheim, aber ich muss garantieren, dass sie vom Besitzer des öffentlichen (und privaten) Schlüssels erstellt wurden. Wenn ich versuche, mit PyCrypto zu entschlüsseln, bekomme ich Kein privater Schlüssel Fehler von PyCrypto. Der Code ist dies:Entschlüsseln mit einem öffentlichen RSA-Schlüssel mit PyCrypto

def _decrypt_rsa(decrypt_key_file, cipher_text): 
    from Crypto.PublicKey import RSA 
    from base64 import b64decode 

    key = open(decrypt_key_file, "r").read() 
    rsakey = RSA.importKey(key) 
    raw_cipher_data = b64decode(cipher_text) 
    decrypted = rsakey.decrypt(raw_cipher_data) 
    return decrypted 

ich es mit dem Pfad zu dem öffentlichen Schlüssel Aufruf der Datei Die verschlüsselten Daten werden von mir nicht erzeugt, und es wurde nicht mit Python aber PHP getan (in OpenSSH-Format.). In PHP gibt es eine Funktion, die diese Daten leicht entschlüsselt.

Ist es überhaupt möglich, mit dem öffentlichen Schlüssel mit PyCrypto zu entschlüsseln?

+1

Sie haben es umgekehrt. Der öffentliche Schlüssel wird zum Verschlüsseln und der private Schlüssel zum Entschlüsseln verwendet. – jchysk

+1

Öffentliche Entschlüsselung ist die gleiche wie verschlüsseln. Ihr Problem kann auf diese Weise behoben werden: 'decrypted = rsakey.encrypt (raw_cipher_data, 0)' – Helio

+0

Wenn die Quelle wirklich mit dem privaten Schlüssel verschlüsselt ist, dann haben sie die Daten effektiv signiert. Mit einigen Tools, wie Java, können Sie dies tun. Um die Signatur zu entschlüsseln, können Sie einen öffentlichen Schlüssel (oder den öffentlichen Teil eines privaten Schlüssels) verwenden. Siehe: https://stackoverflow.com/questions/48280670/pycrypto-how-to-view-raw-rs-a-signature-data –

Antwort

5

Das ist völlig unsicher, weil Sie rohe RSA ohne Padding verwenden.

Ihre Anwendung benötigt eine Signatur, Sie sollten also nicht mit Verschlüsselung und Entschlüsselung zu tun haben. Zum Beispiel ist PKCS # 1 v1.5 ein gutes Protokoll, obwohl die Signatur ein Datenstück ist, das an das angehängt werden muss, was Sie als authentisch bestätigen möchten.

Um eine PKCS # 1 v1.5 Signatur in Python zu überprüfen, was Sie tun:

from Crypto.PublicKey import RSA 
from Crypto.Signature import PKCS1_v1_5 
from Crypto.Hash import SHA 

rsa_key = RSA.importKey(open(verification_key_file, "rb").read()) 
verifier = PKCS1_v1_5.new(rsa_key) 
h = SHA.new(data_to_verify) 
if verifier.verify(h, signature_received_with_the_data): 
    print "OK" 
else: 
    print "Invalid" 

ich stark, so würde empfehlen, den PHP-Code zu ändern, dass es eine solche Signatur erzeugt.

+0

Danke für Ihren Vorschlag, ich werde es zweifellos in Betracht ziehen. Könnten Sie näher erläutern, was bei der Verwendung eines öffentlichen Schlüssels zur Entschlüsselung eines nicht geheimen Datenstücks zur Bestätigung der Authentizität unsicher ist? Willst du sagen, dass es gefälscht werden kann, weil ich keine Polsterung habe? – sergiopereira

+0

Eine Person ohne den geheimen Schlüssel ist immer noch in der Lage, etwas zu schmieden, das wie eine gültige Nachricht aussieht, die vom wirklichen Besitzer kommt. Das liegt an der Tatsache, dass RSA ein ziemlich formbarer Algorithmus ist, wenn er nicht mit einem bewährten Padding kombiniert wird. Was Sie beschreiben, ist wirklich eine Signatur mit sogenannter vollständiger Nachrichtenwiederherstellung: Ein Beispiel ist der ISO 9796-1-Standard, der vollständig gebrochen ist. – SquareRootOfTwentyThree

+0

sollte "importieren" nicht "importKey" sein? –

0

Ihre Funktion ist korrekt. Sie müssen nur den Pfad zu Ihrem privaten Schlüssel angeben, um anstelle Ihres öffentlichen Schlüssels entschlüsseln zu können. Der öffentliche Schlüssel dient zum Verschlüsseln, der private Schlüssel dient zum Entschlüsseln.

def _decrypt_rsa(decrypt_key_file, cipher_text): 
    ''' 
    Decrypt RSA encrypted package with private key 
    :param decrypt_key_file: Private key 
    :param cipher_text: Base64 encoded string to decrypt 
    :return: String decrypted 
    ''' 
    from Crypto.PublicKey import RSA 
    from base64 import b64decode 

    key = open(decrypt_key_file, "r").read() 
    rsakey = RSA.importKey(key) 
    #optionally could use OAEP 
    #from Crypto.Cipher import PKCS1_OAEP 
    #rsakey = PKCS1_OAEP.new(rsakey) 
    raw_cipher_data = b64decode(cipher_text) 
    decrypted = rsakey.decrypt(raw_cipher_data) 
    return decrypted 
+1

Dann könnte ich nicht garantieren, wer die Nachricht verschlüsselt hat. Ich folgte dem Vorschlag in der angenommenen Antwort und zog stattdessen Signaturen ein. Außerdem war mein Problem mit OAuth-Tokens verbunden und letztendlich sind wir zu JWT gewechselt, wo auch Signaturen verwendet werden. – sergiopereira

+0

Richtig, Sie wären nicht in der Lage, die Authentizität zu bestimmen, es sei denn, die Person, die die Nachricht gesendet hat, signierte die Nachricht mit ihrem privaten Schlüssel, und Sie hatten ihren öffentlichen Schlüssel, den Sie separat verifiziert haben. Mit JWT können Sie immer noch RSA zum Signieren mit einem Algorithmus wie RS512 verwenden.Wenn Sie sich darauf konzentrieren, die Authentizität des Absenders zu gewährleisten, sollten Sie sich auf das Issuer-Attribut konzentrieren. – jchysk