2017-02-20 68 views
1

我的java和objective c加密方法產生不同的輸出 - AES128,CBC模式。AES128 Java和Objective C中的CBC加密提供不同的輸出

鍵:YnA+lracf9xaiJO1oA/bTQ==
IV:190Dt3MNeL32o9Kd37HZlQ==
明文:text to encrypt

爪哇輸出:mHZpz52LOK2K76t3B/EUuA==
的OBJ C的輸出:Fb0D46H4tN+ukgI05x/Dbg==

Java代碼:

public static String AESEncrypt(String text, String key, String iv) throws Exception { 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    byte[] keyBytes = new byte[16]; 
    byte[] b = key.getBytes("UTF-8"); 
    int len = b.length; 
    if (len > keyBytes.length) 
     len = keyBytes.length; 
    System.arraycopy(b, 0, keyBytes, 0, len); 

    byte[] keyBytesiv = new byte[16]; 
    byte[] biv = iv.getBytes("UTF-8"); 
    int leniv = biv.length; 
    if (leniv > keyBytesiv.length) 
     leniv = keyBytesiv.length; 
    System.arraycopy(biv, 0, keyBytes, 0, len); 
    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); 
    IvParameterSpec ivSpec = new IvParameterSpec(keyBytesiv); 

    cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); 

    byte[] results = cipher.doFinal(text.getBytes("UTF-8")); 
    BASE64Encoder encoder = new BASE64Encoder(); 
    return encoder.encode(results); 
} 

目標C代碼

+ (NSData *)AESOperation:(CCOperation)operation OnData:(NSData *)data key:(NSData *)key iV:(NSData *) iv { 

    NSUInteger dataLength = [data length]; 
    size_t bufferSize = dataLength + kCCBlockSizeAES128; 
    void *buffer = malloc(bufferSize); 

    size_t numBytesEncrypted = 0; 
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, 
             kCCAlgorithmAES128, 
             kCCOptionPKCS7Padding, 
             [key bytes], 
             kCCBlockSizeAES128, 
             [iv bytes], 
             [data bytes], 
             dataLength, 
             buffer, 
             bufferSize, 
             &numBytesEncrypted); 
    if (cryptStatus == kCCSuccess) { 
    return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 
    } 

    free(buffer); 
    return nil; 
} 
+1

您需要的base64解碼密鑰和IV AES128 CBC模式,並檢查你的'arraycopy's Java代碼中,有一個在錯誤第二個。 – matt

+0

IV必須是不可預知的(閱讀:隨機)。不要使用靜態IV,因爲這會使密碼具有確定性,因此在語義上不安全。觀察密文的攻擊者可以確定何時之前發送了相同的消息前綴。 IV不是祕密的,所以你可以把它和密文一起發送。通常,它只是在密文前面加上,然後在解密之前切掉。 –

+0

最好是驗證你的密文,以便像[填充oracle攻擊](http://crypto.stackexchange.com/q/18185/13022)這樣的攻擊是不可能的。這可以通過驗證模式(如GCM或EAX)或[加密 - 然後MAC](http://crypto.stackexchange.com/q/202/13022)方案完成。 –

回答

0

由於上述建議,我能夠解決Java代碼上的問題。這裏是爲我工作,以實現對Java和Objective C的

public static String AESEncrypt(String text, String key, String iv) throws Exception { 

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    byte[] keyBytes = new byte[16]; 
    byte[] b = new BASE64Decoder().decodeBuffer(key); 
    int len = b.length; 
    if (len > keyBytes.length) 
     len = keyBytes.length; 
    System.arraycopy(b, 0, keyBytes, 0, len); 

    byte[] keyBytesiv = new byte[16]; 
    byte[] biv = new BASE64Decoder().decodeBuffer(iv); 
    int leniv = biv.length; 
    if (leniv > keyBytesiv.length) 
     leniv = keyBytesiv.length; 
    System.arraycopy(biv, 0, keyBytesiv, 0, len); 

    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); 
    IvParameterSpec ivSpec = new IvParameterSpec(keyBytesiv); 

    cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); 

    byte[] results = cipher.doFinal(text.getBytes("UTF-8")); 
    BASE64Encoder encoder = new BASE64Encoder(); 
    return encoder.encode(results); 
} 
4

有兩種方法來這樣的問題,這可以結合:

  • 作爲一個全面的檢查,試圖解密加密的文本,看看它是否符合原件,在兩種語言。

  • 嘗試使用另一個庫(第三個庫),並與前兩個值進行比較。

所以我試圖用一個在線工具解密密文,並能恢復原來的文本(「文本加密」)與Objective C的輸出。它表明Java代碼有問題。我懷疑它可能與輸入(key,iv)是base64編碼的事實有關,但它似乎只是被視爲UTF-8編碼(調用getBytes())。

相關問題