Question

J'ai un module C ++ hérité qui propose le cryptage / décryptage à l'aide de la bibliothèque openssl (cryptage DES). J'essaie de traduire ce code en java, et je ne veux pas compter sur une DLL, JNI, etc. Le code C ++ ressemble à:

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));

Le code Java ressemble à:

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 {
    // ...
}

Je peux donc faire le chiffrement DES en Java assez facilement, mais comment puis-je obtenir le même résultat qu'avec le code ci-dessus avec des méthodes complètement différentes? Ce qui me dérange en particulier, c'est que la version C ++ utilise 2 clés alors que la version Java n'en utilise qu'une. La réponse à propos de DES en mode CBC est très satisfaisante mais je ne peux pas le faire fonctionner pour le moment. Voici plus de détails sur le code original:     clé de caractère non signée1 [10] = {0};     clé de caractère non signé2 [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);
...

D'après ce que j'ai lu, la clé devrait comporter 56 bits (ou 64, ce n'est pas clair pour moi), mais ici, elle compte 48 octets.

Était-ce utile?

La solution

Je ne suis pas un expert OpenSSL, mais je suppose que le code C ++ utilise DES en mode CBC, nécessitant ainsi un IV (c'est probablement ce que initKey est, et c'est pourquoi vous pensez avoir besoin de deux clés). Si je ne me trompe pas, vous devez modifier votre code Java pour qu'il utilise également DES en mode CBC. Le code Java nécessitera également une clé de chiffrement et un IV.

Autres conseils

N'oubliez pas non plus que vous ne devriez pas utiliser les classes sun.misc. * dans votre code. Cela pourrait se produire sur d'autres ordinateurs virtuels, car ils ne sont pas des API publiques. Les codecs Apache Commons (entre autres) ont des implémentations de Base64 qui ne supportent pas ce problème.

Je ne sais pas vraiment pourquoi un seul DES utiliserait plusieurs clés. Même si vous utilisiez Triple-DES, je pense que vous utiliseriez une seule clé (avec plus d'octets de données) plutôt que des clés séparées avec l'API Java Cryptography.

Les algorithmes doivent correspondre; Si vous obtenez des résultats différents, cela peut être dû à la façon dont vous manipulez les touches et le texte. Notez également que les caractères Java ont une longueur de 2 octets et que les caractères C ++ ont un octet. Cela peut donc avoir un rapport avec cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top