Java(Android)解密带附加IV的消息

我生成一个随机IV,这个IV连接(以普通字节)到加密的msg的前面,如下所示;

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.java:52)

04-04 14:55:05.790:W / System.err(9847):at 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; } 

当使用带填充的分组密码时,加密文本总是大于解密文本。 但是,您只能将解密文本中的字节数复制到要发送的消息中。 因此,您的加密邮件不完整。

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