使用BouncyCastle和Unlimited JCE的InvalidKeyException

时间:2014-07-03 15:24:33

标签: java encryption bouncycastle

我正在尝试使用AES-256-CBC和BouncyCastle加密/解密字符串。我已经为长度为16字节(128位)但 的密钥完成了此操作,以使用128字节的密钥(1024位)。

我已经阅读了很多有关SO的建议,并发现我正在使用的JVM的受限策略文件尚未安装。从理论上讲,应该允许使用大于的密钥而不是128位。但是,在将Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction policy files安装到我的jdk(1.6.0.jdk/Contents/Home/lib/security)后,问题仍然存在。

我用来加密String的代码如下:

String my_key =  "2bc7fa12d..." // String of length 128

Security.addProvider(new BouncyCastleProvider());

byte[] original = my_key.getBytes();
key = new SecretKeySpec(original, "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
byte[] encryptedValue = Base64.encode(encrypted);

return new String(encryptedValue);

但在更换了Unlimited JCE下载中发现的.jar后,我仍然遇到错误:

java.security.InvalidKeyException: Key length not 128/192/256 bits.
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(Unknown Source)
    at javax.crypto.Cipher.init(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at EncyrptionTest.encrypt(EncyrptionTest.java:58)
    at EncyrptionTest.main(EncyrptionTest.java:33)

对此问题的任何建议或解决方案将不胜感激。

编辑:

根据要求,我试图从Ruby移植到Java的代码如下:

 WithCred.entials_for(:to_encrypt) do |c|
    attr_encrypted :my_key,
      :algorithm => 'aes-256-cbc',
      :key => c[:key]
  end

它用来加密的宝石(我相信)是attr_encypted。 (恐怕我对Ruby知之甚少)

1 个答案:

答案 0 :(得分:0)

您需要执行OpenSSL中使用的(旧的,已弃用的)MD5密钥生成。您的Ruby代码指向this源文件。所以密钥不是真正的密钥,它是一个转换为密钥的密码。请注意,它使用MD5,不使用salt,默认情况下使用2000次迭代。

最后,它回到了这个:

EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
               (unsigned char *)RSTRING_PTR(vpass), RSTRING_LEN(vpass), iter, key, iv);

当然,您需要使用Java中的OpenSSL专有密钥派生选项。幸运的是,您不会是第一个要求OpenSSL兼容性的人:

How to decrypt file in Java encrypted with openssl command using AES?

我事先道歉,我没有在答案中发布我的面向对象的实现:)