6

openssl ライブラリ (DES 暗号化) を使用して暗号化/復号化を提供するレガシー C++ モジュールがあります。そのコードを Java に変換しようとしていますが、DLL や JNI などに依存したくありません... C++ コードは次のようになります。

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 コードは次のようになります。

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

したがって、Java で DES 暗号化をかなり簡単に行うことができますが、まったく異なる方法で上記のコードと同じ結果を得るにはどうすればよいでしょうか? 特に気になるのは、C++ バージョンは 2 つのキーを使用するのに対し、Java バージョンは 1 つのキーしか使用しないという事実です。CBC モードでの DES に関する回答は非常に満足のいくものですが、まだ動作させることはできません。元のコードの詳細は次のとおりです。 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);
...

私が読んだことから、キーは 56 (または 64、私にはわかりません) ビット長である必要がありますが、ここでは 48 バイト長です。

4

3 に答える 3

1

私はOpenSSLの専門家ではありませんが、C ++コードはCBCモードでDESを使用しているため、IVが必要だと思います(これがinitKeyである可能性が高いため、2つのキーが必要だと思います)。私が正しい場合は、CBCモードでもDESを使用するようにJavaコードを変更する必要があります。そうすると、Javaコードにも暗号化キーとIVが必要になります。

于 2008-09-18T14:16:35.420 に答える
1

Also, keep in mind that you really shouldn't use sun.misc.* classes in your code. This could break in other VMs as these are not public APIs. Apache Commons Codecs (among others) have implementations of Base64 that don't bear this problem.

I'm not really sure why single DES would ever use multiple keys. Even if you were using Triple-DES, I believe you would use a single key (with more bytes of data) rather than using separate keys with the Java Cryptography API.

于 2008-09-18T14:39:00.233 に答える
0

アルゴリズムは一致する必要があります。異なる結果が得られる場合は、キーとテキストの処理方法に関係している可能性があります。また、Java 文字の長さは 2 バイトで、C++ の文字は 1 バイトであるため、何らかの関係がある可能性があることに注意してください。

于 2008-09-18T13:32:05.747 に答える