2013-08-06 53 views
0

嗨我想加密和解密在2個系統中使用的數據(一個是C++和另一個Java)我從代碼項目中找到了一個Demo項目:Encryption this是C++加密解密功能,當我使用函數實現的代碼它的工作原理:C++加密解密函數(Cryptix工具箱)的Java實現

void main() 
{ 
    try 
    { 
     CRijndael oRijndael; 
     oRijndael.MakeKey("abcdefghabcdefgh", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, 16); 
     char szDataIn[] = "Password12345678"; 

     char szDataOut[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 

     oRijndael.EncryptBlock(szDataIn, szDataOut); 

     cout << "[" << szDataIn << "]" << endl; 
     cout << "[" << szDataOut << "]" << endl; 
     memset(szDataIn, 0, 16); 

     oRijndael.DecryptBlock(szDataOut, szDataIn); 
     cout << "[" << szDataIn << "]" << endl; 

    } 
    catch(exception& roException) 
    { 
     cout << roException.what() << endl; 
    } 
} 

這使我在控制檯以下輸出:

enter image description here

對數據進行加密結束解密..

任何人都可以幫我指點一下Java實現的正確方向,以加密和解密獲得相同結果的相同數據(在C++中進行加密,然後在Java中進行解密,然後在C++中使用java進行加密)?在帖子中,他們討論Cryptix工具包?

在此先感謝。

+0

Rijndael也被稱爲AES。儘管您可能需要深入研究CRijndael以找出它正在使用的參數(比特,密碼模式,填充,IV?)等等,但Java的AES還有很多實現。 – Rup

回答

2

此Java代碼將加密/解密並生成與編碼爲十六進制的示例相同的輸出。輸出看起來是相同的(也應該是),但要100%確定您需要在C++示例中對輸出進行十六進制編碼。

請注意,雖然您的示例只會加密和解密單個塊(16個字節)。如果你想要更多,你需要使用CRijndaelEncryptDecrypt方法(而不是EncryptBlockDecryptBlock)。下面的Java代碼可以同時使用,不需要修改它。

public static void main(String[] args) throws DecoderException, InvalidKeyException, 
     NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, 
     IllegalBlockSizeException, BadPaddingException { 
    //Hex encoding/decoding done with Apache Codec 
    byte[] key = "abcdefghabcdefgh".getBytes(); 
    String text = "Password12345678"; 

    byte[] encrypted = encrypt(key, text.getBytes()); 
    byte[] decrypted = decrypt(key, encrypted); 

    System.out.println("Text: " + text); 
    System.out.println("Encrypted: " + Hex.encodeHexString(encrypted)); 
    System.out.println("Decrypted: " + new String(decrypted)); 
} 

public static byte[] encrypt(byte[] key, byte[] unencrypted) throws NoSuchAlgorithmException, 
     NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, 
     IllegalBlockSizeException, BadPaddingException{ 
    //Set up the cipher and encrypt 
    Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); 
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES")); 
    byte[] encrypted = cipher.doFinal(unencrypted); 

    return encrypted; 
    } 

public static byte[] decrypt(byte[] key, byte[] encrypted) throws NoSuchAlgorithmException, 
     NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, 
     IllegalBlockSizeException, BadPaddingException{ 
    //Decrypt the encrypted text 
    Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); 
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES")); 
    byte[] decrypted = cipher.doFinal(encrypted); 

    return decrypted; 
} 

輸出

Text: Password12345678 
Encrypted: 6c7d800fad2bb8593db92847bbbdbeff 
Decrypted: Password12345678 

雖然警告你的大詞,這種加密(ECB,沒有填充)是極不安全的,你不應該在實際系統中使用它。你應該真的在使用初始化矢量和PKCS5填充的CBC。

1

請務必不要直接從字符數組中導出加密數據。要麼使用固定大小的輸出,要麼使用字節緩衝區。這是強制性的,因爲在加密的字符串中,可能有字節組合,可以解釋爲控制字符f.e. \0馬克。如果是這樣,使用...<< szDataOut;打印輸出到文件可能會破壞你的加密字符串,並且無法通過第二個應用程序完全讀取它(不管是否是java或C++)。