Falsche Schlüsselgröße bei der Portierung von Crypto ++ AES-Verschlüsselung auf PHP mcrypt

StackOverflow https://stackoverflow.com/questions/4052594

Frage

Früher konnte ich in den Hafen einige C ++ CryptoPP Rijndael_128 CBC-Code MCrypt PHP, aber jetzt bin ich Probleme mit CFB-Modus. Die C ++ und PHP Ergebnisse nicht übereinstimmen (auch das erste Byte Matches aber dieser Zufall sein könnte, tut alles andere nicht). Bei einiger Diagnostik, es sieht aus wie mcrypt PHP ist nicht die Schlüssellänge richtig einstellen?

Hier ist die C ++ (Diagnose und sundries der Einfachheit halber entfernt):

CFB_Mode<AES>::Encryption encryptor(g_encrypt_key, AES::DEFAULT_KEYLENGTH, g_encrypt_iv);

StringSource ss( sInput.c_str(), true, 
        new StreamTransformationFilter( encryptor, 
            new HexEncoder( new StringSink( sEncryptedOut ) )
        ));

Und hier ist die PHP:

$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CFB, '')
mcrypt_generic_init($cipher, $g_encrypt_key, $g_encrypt_iv);

$sEncryptedOutput = mcrypt_generic( $cipher, $sInput);
mcrypt_generic_deinit($cipher);
mcrypt_module_close($cipher);

g_encrypt_key und g_encrypt_iv sind beide 16 Bytes lang, und das Bytes entspricht für die C ++ und PHP-Versionen. Für die PHP-Version ist es eine binäre Zeichenfolge aus dem Bytes aufgebaut (ja, ich habe überprüft, diese sind identisch).

Ich habe Anrufe an die PHP-Version zu überprüfen $cipher die Blockgröße hinzugefügt, Schlüsselgröße usw. Die Blockgröße und iv Größe sind beide 16; unterstützte Schlüsselgrößen als 16 gemeldet, 24 und 32 -. alle wie erwartet

Wo ich denke, das Problem ist, dass die keysize als 32 Byte gemeldet wird. Mit Blick auf die mcrypt docs, der einzige Weg, um die keysize der Einstellung ist durch einen Schlüssel der erforderlichen Größe zu liefern. Aber ich vorbei einen 16-Byte-Schlüssel! Warum also meldet es das Vorhandensein eines 32-Byte-Schlüssel? Wenn CFB-Modus ein 32-Byte-Schlüssel verwenden müssen, warum dann nicht CryptoPP es als in Ordnung akzeptieren? Was ist die Lösung? Kann ich PHP zwingen, den 16-Byte-Schlüssel zu verwenden, die zur Verfügung gestellt wurde? Oder gibt es einen Parameter, dass ich fehle, die zu einer anderen Einstellung in CryptoPP in Verzug ist als in MCrypt?

Ich bin mit dem CFB-Modus, weil ich die Länge der resultierenden verschlüsselten Daten minimieren möchten. Die wenige Bytes, dass padding einführen würde, tun Materie in dieser Anwendung.

Ich muß in der Lage sein, zum Verschlüsseln / Entschlüsseln in C ++, aber nur verschlüsselt in PHP. AES ist wohl übertrieben für meine Anwendung -. Das Minimum was ich brauche „ein gute Scrambling des Bytes“, so dass die Funktion des einzelnen Bytes in den Daten ist nicht auf der Hand

War es hilfreich?

Lösung

Es ist eine Weile gewesen, aber ich hatte einige ähnliche Probleme mit mcrypt und openSSL CFB mit ein paar Jahren. Am Ende habe ich entdeckt, mcrypt eine andere Standard Feedback Kettengröße als openssl in CFB-Modus verwendet. Das heißt, glaube ich, eine Blockgröße und Feedback-Größe von 128 Bits, ein openSSL AES128 in CFB verwendet, während mcrypt eine Blockgröße von 128 Bit und eine Rückkopplungsgröße von 8 Bits verwendet. Ich habe keine Möglichkeit, dies zu bestätigen, es war nur Spekulation zu der Zeit, basierend auf einige alten Forum-Beiträge lesen. Unabhängig von der Wahrheit dieser Theorie war ich nicht die einzige Person, oder erste diese Frage haben.

Die Lösung für mich war nofb wie dich selbst zu verwenden. Gemäß der PHP mcrypt Library Reference MCRYPT_MODE_NOFB Kräfte der Rückkopplungskette in diesem Fall ein 128-Bit-Block / Feedback für AES128 (Rijndael), um gleich die Blockgröße des Algorithmus, der mit dem, was paßt manpage für die mcrypt Modulstati über nofb. Das ist gut, da alles fand ich sagte nofb Rückmeldung an die Blockgröße synchron ist. Somit können sowohl mcrypt und OpenSSL in nofb waren nun 128-Bit-Schlüssel / iv / Block / Feedback Größen für AES128 und alles hat gut funktioniert.

Was PHP Reporting 256bit Schlüsselgrößen (32 Byte), die Funktion, dass die Renditen der aktuelle Chiffre-Algorithmus Schlüsselgröße die maximale Schlüsselgröße tatsächlich zurückgibt, die nicht eindeutig in der Dokumentation angegeben ist. Ich weiß das, weil meine kleine Klasse ich die ganze Zeit jetzt für verschiedene Projekte verwenden funktioniert völlig in Ordnung mit openSSL und alle anderen AES-Bibliotheken in CBC oder nofb. Dies wäre nicht der Fall sein, wenn mcrypt wurde meinen 128bit (16 Zeichen) Schlüssel mit einem zusätzlichen 128-Bit von Null-String Klotzen, oder was auch immer, und wäre technisch nicht ohnehin korrekt sein.

Nicht wirklich eine gute Antwort, aber das Beste, was ich habe auf einem sehr dilettantisch Vorstoß in die Kryptographie vor einigen Jahren.

Andere Tipps

Überprüfen Sie heraus phpseclib:

http://phpseclib.sourceforge.net/

Sie können die Schlüsselgröße und Blockgröße festlegen, was Sie wollen.

zB. $ AES-> setKeyLength (128) oder $ AES-> setKeyLength (256);

Ich hatte dieses Problem - paar Punkte. Standardmäßig setzt der PHP-Rijndael-Modus die Rückkopplungsschleife zu 8bits - sein AES Bedürfnisse ist die gleiche Länge wie die IV / Key sein

.

Sie können dies tun, indem Sie den Modus ‚NCFB‘ anstelle von ‚CFB‘ oder MCRYPT_MODE_CFB.

Ausführliche Informationen über aes_cfb_128 kompatibel PHP sind bei dieser Sicherheitsstack Frage schreiben: aes CFB 128 Entschlüsselung / Verschlüsselung Problem zwischen Erlang und PHP . Die kurze davon ist (von Tom Leek):

  

... für beide CFB und OFB (die voneinander verschieden sind und nicht untereinander ausgetauscht werden kann), müssen Sie Sorge über die „Rückkopplungslänge“, die mit hohen Klarheit in verschiedenen Krypto-Bibliotheken nicht unbedingt dokumentiert ist. Sowohl die Verschlüsselung und Entschlüsselung müssen die gleiche Rückkopplungslänge zusammenarbeiten verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top