Java (Android) 正在解密附加了 IV 的消息
Java (Android) Decrypting msg with IV attached
我生成一个随机 IV,该 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: last block incomplete in decryption
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);
我生成一个随机 IV,该 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: last block incomplete in decryption
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);