【问题标题】:exception: wrong final block length...aes decryption异常:错误的最终块长度...aes解密
【发布时间】:2015-06-30 01:20:11
【问题描述】:

我想要实现的是 AES CBC 解密 like this in android 使用online tool

我并不是真正的安卓开发者,以下代码不一定是 100% 安全的(仅作为示例) 加密工作得很好,但我真的坚持解密:

与:AESCrypt.decrypt(key2, ivBytes, todecode); 的行 抛出异常 我认为问题在于“key2”和“todecode”变量的实际数据转换......有人知道我错过了什么吗?

设置:

private static final String TAG = "AESCrypt";

// AESCrypt-ObjC uses CBC and PKCS7Padding
private static final String AES_MODE = "AES/CBC/PKCS7Padding";
private static final String CHARSET = "UTF-8";

// AESCrypt-ObjC uses SHA-256 (and so a 256-bit key)
private static final String HASH_ALGORITHM = "SHA-256";





    byte[] key = hexStringToByteArray("E0E1E2E3E5E6E7E8EAEBECEDEFF0F1F2");
    SecretKeySpec key2 = new SecretKeySpec(key, 0, key.length, "AES");
    byte[] ivBytes = hexStringToByteArray("12CEC438810CFA399A81139AF7D648BC");
    byte[] todecode = Base64.decode("CD46009A232420B2CBF6E4148EE17AA4",
            Base64.NO_WRAP);
    try {

        resultbytes = AESCrypt.decrypt(key2, ivBytes, todecode);
        result = resultbytes.toString();

    } catch (Exception e) {

        // TODO Auto-generated catch block
        feedbackBody.append("catch blok \n");
        e.printStackTrace();

    }
    feedbackBody.append(result + " \n");



public static byte[] decrypt(final SecretKeySpec key, final byte[] iv,
        final byte[] decodedCipherText) throws GeneralSecurityException {
    final Cipher cipher = Cipher.getInstance(AES_MODE);
    IvParameterSpec ivSpec = new IvParameterSpec(iv);
    cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
    byte[] decryptedBytes = cipher.doFinal(decodedCipherText);

    log("decryptedBytes", decryptedBytes);

    return decryptedBytes;
}

编辑:似乎输入数据是这里的错误:

如果我加密原始数据并在此之后立即解密,它就可以正常工作... 但我从别处得到解密文件

从字符串中怀疑编码周围的错误:Base64.decode("CD46009A232420B2CBF6E4148EE17AA4", Base64.NO_WRAP);

【问题讨论】:

  • 您的 AES_MODE 是否包含填充?我认为这个错误表明加密消息太短,你确定加密消息被正确保存为 Base64。如果您包含堆栈跟踪,那将是显而易见的。导致错误的密钥将具有堆栈跟踪包括 cipher.init,而错误消息将从 cipher.doFinal 开始
  • 您自己的答案在查看问题时没有任何意义。请编辑您的问题以包含完整的加密/解密周期。

标签: java android encryption


【解决方案1】:

请尝试使用以下方法进行AES加密和解密,经过长期测试:

 public static String encrytData(String text) throws Exception {

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
    byte[] static_key = Constants.AES_KEY.getBytes();

    SecretKeySpec keySpec = new SecretKeySpec(static_key, "AES");
    IvParameterSpec ivSpec = new IvParameterSpec(Constants.IV_VECTOR);
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

    byte[] results = cipher.doFinal(text.getBytes());

    String result = Base64.encodeToString(results, Base64.NO_WRAP|Base64.DEFAULT);
    return result;

}


public static String decryptData(String text)throws Exception{

    byte[] encryted_bytes = Base64.decode(text, Base64.DEFAULT);

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
    byte[] static_key = Constants.AES_KEY.getBytes();

    SecretKeySpec keySpec = new SecretKeySpec(static_key, "AES");
    IvParameterSpec ivSpec = new IvParameterSpec(Constants.IV_VECTOR);
    cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

    byte[] decrypted = cipher.doFinal(encryted_bytes);
    String result = new String(decrypted);

    return result;
}

【讨论】:

  • 1. 始终将getBytes()new String() 与相同的附加字符集字符串一起使用,因为不同的系统可能使用不同的默认值。 2. 生成一个新的随机 IV 并将其添加到密文中,否则它在语义上是不安全的。 3. 增加密文认证。这可以作为先加密后 MAC 方案(即 HMAC-SHA256)或使用像 GCM(java 支持)、CCM、EAX 这样的认证模式来完成。
【解决方案2】:

AES_MODE 的 ZeroBytePadding 起到了神奇的作用!!

private static final String AES_MODE = "AES/CBC/ZeroBytePadding";

还有: 第 4 行的 Base64.decode(...) 出现了一些问题,改为 hexStringToByteArray(...) 现在可以正常工作了:D

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2014-02-13
    • 2014-05-02
    • 1970-01-01
    • 2017-03-17
    • 2017-12-20
    相关资源
    最近更新 更多