【问题标题】:Java, error when decoding AES-256Java,解码 AES-256 时出错
【发布时间】:2015-08-04 03:21:22
【问题描述】:

解密时收到错误消息:(javax.crypto.BadPaddingException: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt)

我的代码加密/解密:

private static byte[] password = null; //  this.password = editText.getBytes();
static final byte[] ivBytes = {'6','g','6','o','d','a','0','u','4','n','w','i','6','9','i','j'};

public static byte[] encrypt(String text) throws Exception {
    byte[] clear = text.getBytes("UTF-8");
    IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    sr.setSeed(password);
    kgen.init(256, sr); // 192 and 256 bits may not be available
    SecretKey skey = kgen.generateKey();
    byte[] key = skey.getEncoded();

    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);
    byte[] encrypted = cipher.doFinal(clear);
    return encrypted;
}

public static String decrypt(byte[] encrypted) throws Exception {
    IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    sr.setSeed(password);
    kgen.init(256, sr); // 192 and 256 bits may not be available
    SecretKey skey = kgen.generateKey();
    byte[] key = skey.getEncoded();

    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
    String decrypted = new String(cipher.doFinal(encrypted));
    return decrypted;
}

我怀疑这个bug generateKey。

【问题讨论】:

标签: java android cryptography aes


【解决方案1】:

你做错了两件事:

  • 通过使用密钥播种 PRNG 从密码生成密钥是一个坏主意。请改用基于密码的加密。 Java 有一个 PKCS#5 的实现,它将根据密码生成密钥。

  • 您需要为每次加密使用新的强随机 IV:

    • 加密时,不要在 cipher.init() 中指定 IV。将为您生成一个新的。
    • encrypt() 需要将 IV (cipher.getIV()) 和密文都序列化为字节数组。
    • decrypt():将 IV 从密文中分离出来,从中构建一个 IvParameterSpec 并像现在一样输入 cipher.init()。

【讨论】:

    【解决方案2】:

    您的问题是,当您解密时,您会生成一个新的密钥,而不是从密码中派生它。查看this blog post 了解如何实施基于密码的加密。有加解密函数的例子。

    【讨论】:

      【解决方案3】:

      替换下面的行:

      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      

      下面一行:

      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding","BC");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多