Frage

Ich habe ein Vermächtnis C ++ Modul, das die Verschlüsselung / Entschlüsselung mit der OpenSSL-Bibliothek (DES-Verschlüsselung) bietet. Ich versuche, diesen Code in Java zu übersetzen, und ich will nicht auf einer DLL verlassen, JNI, etc ... C ++ Code wie folgt aussieht:

des_string_to_key(reinterpret_cast<const char *>(key1), &initkey);
des_string_to_key(reinterpret_cast<const char *>(key2), &key);
key_sched(&key, ks);
// ...
des_ncbc_encrypt(reinterpret_cast<const unsigned char *>(tmp.c_str()), 
reinterpret_cast< unsigned char *>(encrypted_buffer), tmp.length(), ks, &initkey, 
DES_ENCRYPT);

return base64(reinterpret_cast<const unsigned char *>(encrypted_buffer),    strlen(encrypted_buffer));

Java-Code wie folgt aussieht:

Cipher ecipher;
try {
    ecipher = Cipher.getInstance("DES");
    SecretKeySpec keySpec = new SecretKeySpec(key, "DES");      
    ecipher.init(Cipher.ENCRYPT_MODE, keySpec);         
    byte[] utf8 = password.getBytes("UTF8");
    byte[] enc = ecipher.doFinal(utf8);
    return new sun.misc.BASE64Encoder().encode(enc);
}
catch {
    // ...
}

So kann ich die DES-Verschlüsselung ziemlich leicht in Java tun, aber wie kann ich das gleiche Ergebnis wie mit dem obigen Code mit Methoden erhalten, die völlig unterschiedlich sind? Was insbesondere stört mich ist die Tatsache, dass die C ++ Version arbeitet mit 2 Tasten, während die Java-Version nur 1 Schlüssel verwendet. Die Antwort über DIE im CBC-Modus ist sehr befriedigend, aber ich kann es noch nicht an der Arbeit. Hier sind weitere Details über den Original-Code:     unsigned char Key1 [10] = {0};     unsigned char key2 [50] = {0};

int i;
for (i=0;i<8;i++)
    key1[i] = 31+int((i*sqrt((double)i*5)))%100;
key1[9]=0;

for (i=0;i<48;i++)
    key2[i] = 31+int((i*i*sqrt((double)i*2)))%100;
key2[49]=0;
...
// Initialize encrypted buffer
memset(encrypted_buffer, 0, sizeof(encrypted_buffer));

// Add begin Text and End Text to the encrypted message
std::string input;
const char beginText = 2;
const char endText = 3;
input.append(1,beginText);
input.append(bufferToEncrypt);
input.append(1,endText);    

// Add padding
tmp.assign(desPad(input));

des_ncbc_encrypt(reinterpret_cast<const unsigned char *>(tmp.c_str()),     
reinterpret_cast< unsigned char *>(encrypted_buffer), tmp.length(), ks, &initkey, 
DES_ENCRYPT);
...

Von dem, was ich gelesen habe, sollte der Schlüssel 56 (oder 64, es ist mir nicht klar) Bits lang, aber hier ist es 48 Byte lang.

War es hilfreich?

Lösung

Ich bin kein OpenSSL-Experte, aber ich würde das C ++ Code erraten wird mit DEM im CBC-Modus somit ein IV benötigen (das ist, was die initKey wahrscheinlich ist, und das ist, warum Sie denken, Sie brauchen zwei Schlüssel). Wenn ich Recht habe, müssen Sie Ihren Java-Code ändern DIE im CBC-Modus zu verwenden, dann zu dem Java-Code wird einen Verschlüsselungsschlüssel und ein IV benötigen.

Andere Tipps

Auch im Auge behalten, dass Sie wirklich nicht sun.misc verwenden sollten. * Klassen in Ihrem Code. Dies könnte in anderen VMs brechen, da diese nicht öffentliche APIs. Apache Commons Codecs (ua) hat Implementierungen von Base64, dass dieses Problem nicht tragen.

Ich bin nicht wirklich sicher, warum einzelne DIE jemals mehrere Schlüssel verwenden würde. Auch wenn Sie Triple-DEN verwendet hat, glaube ich Ihnen einen Schlüssel (mit mehr Bytes von Daten) und nicht über separate Tasten mit dem Java Cryptography API verwenden würden.

Die Algorithmen sollten übereinstimmen; wenn Sie unterschiedliche Ergebnisse bekommen kann es haben mit der Art und Weise zu tun, sind Sie die Schlüssel der Handhabung und den Text. Denken Sie auch daran, dass Java Zeichen 2 Bytes lang ist, die C ++ Zeichen 1 Byte sind, so dass etwas damit zu tun haben kann.

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