2015-04-04 45 views
0

我生成一個隨機IV,這個IV附加(以普通字節表示)到加密味精的前面,如下所示;Java(Android)解密附帶IV的味精

public String encrypt(String plainText, byte[] encryptionKey) throws Exception { 
    SecretKeySpec key = new SecretKeySpec(encryptionKey, "AES");   
    cipher.init(Cipher.ENCRYPT_MODE, key, iV); 
    byte[] data = new byte[iV.getIV().length + plainText.getBytes("UTF-8").length]; 
    // Merge together plain IV and encrypted cipher text 
    System.arraycopy(iV.getIV(), 0, data, 0, iV.getIV().length); 
    System.arraycopy(cipher.doFinal(plainText.getBytes("UTF-8")), 0, data, iV.getIV().length, plainText.getBytes("UTF-8").length); 

    return Base64.encodeToString(data, Base64.DEFAULT); 

} 

該消息在使用WiFi Direct的設備之間發送。這在我的MainActivity中處理;

case MESSAGE_READ: 
    byte[] readBuf = (byte[]) msg.obj; 

    crypto.iV = new IvParameterSpec(Arrays.copyOf(readBuf, 16)); 
    // Construct a string from the valid bytes in the buffer 
    String readMessage = new String(readBuf, 0, msg.arg1); 
    Log.d(TAG, readMessage); 

    try { 
     String decryptMsg = crypto.decrypt(readMessage, SECRET_KEY); 
     // Present the message 
     (chatFragment).pushMessage("Buddy (decrypt): " + decryptMsg); 

     Log.d(TAG, decryptMsg); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    // Present the message (comment out after testing!) 
    //(chatFragment).pushMessage("Buddy (encrypt): " + readMessage); 
    break; 

在解密期間,它會失敗並顯示警告;

04-04 14:55:05.770:W/System.err的(9847):javax.crypto.IllegalBlockSizeException:最後的塊在解密不全

04-04 14:55:05.789:W/System.err(9847):at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:850)

04-04 14:55:05.790:W/System .err(9847):at javax.crypto.Cipher.doFinal(Cipher.java:1340)

04-04 14:55:05.790:W/System.err(9847):at com.example.cryptochat。 Crypto.decrypt(Crypto.jav一:52)

04-04 14:55:05.790:W/System.err的(9847):在com.example.cryptochat.MainActivity.handleMessage(MainActivity.java:463)

的問題在於解密方法,但我不確定我做錯了什麼。該方法在下面;

public String decrypt(String cipherText, byte[] encryptionKey) throws Exception { 
    SecretKeySpec key = new SecretKeySpec(encryptionKey, "AES");   
    cipher.init(Cipher.DECRYPT_MODE, key, iV); 
    String decrypt = new String(cipher.doFinal(Base64.decode(cipherText, Base64.DEFAULT))); 
    decrypt = new String(Arrays.copyOfRange(decrypt.getBytes(), 16, decrypt.getBytes().length)); 

    return decrypt; 
} 

回答

2

當使用具有填充的分組密碼時,加密的文本始終大於解密的文本。但是,您只能將與解密文本一樣多的字節複製到要發送的消息中。因此,您的加密郵件不完整。

byte[] encryped = cipher.doFinal(plainText.getBytes("UTF-8")); 
byte[] data = new byte[iV.getIV().length + encrypted.length]; 
System.arraycopy(iV.getIV(), 0, data, 0, iV.getIV().length); 
System.arraycopy(encrypted, 0, data, iV.getIV().length, encrypted.length); 
+0

感謝您的幫助robert!我可以用附加的IV解密文本,但它在解密「cipherTextWithoutIv」時不起作用。解密後應該怎樣刪除Iv? – Danran 2015-04-04 14:37:01

+0

不要對base64編碼的字符串進行字符串操作。解碼並執行操作。 – Robert 2015-04-04 15:03:51

+0

我仍然無法從解密的消息中成功刪除IV。 CopyOfRange()似乎不工作,對我應該做什麼的任何建議? (*更新代碼) – Danran 2015-04-04 20:10:10