Java (Android) 解密带有 IV 的 msg

标签 java aes

我生成一个随机 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);

关于Java (Android) 解密带有 IV 的 msg,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29447412/

相关文章:

java - Freemarker、PDF、页眉/页脚和分页符

java - 理解AES加密代码的解释

javascript - 如何在javascript中解密由JAVA使用AES加密的文件

cryptography - 带有 WinCrypt 和 CryptImportKey 的硬编码 AES-256 key

android - 如何使用 crypto-js 以与在 Angular 中相同的方式在 android 中加密数据

iphone - OpenSSL AES256 cbc 加密

java - 在 OpenGL 中渲染场景阴影的最简单方法是什么?

Java 从文件中读取对象 vector 仅读取 vector 中的第一个对象

在android中使用 "gpuImage"和 "javacv"时,java.lang.UnsatisfiedLinkError : org. bytedeco.javacpp.avutil

java - Java编译器如何允许这样的类定义