使用密码短语的带有CBC的Java AES



我想用Java实现带有CBC加密的256密钥AES。收件人将256位密码作为字符串"absnfjtyrufjdngjvhfgksdfrtifghkv"发送给我,使用以下openssl命令可以完美工作:

 echo test | openssl enc  -aes-256-cbc -a -k 'absnfjtyrufjdngjvhfgksdfrtifghkv'

base64格式的输出为:U2FsdGVkX1/yA4J8T+i1M3IZS+TO/V29rBJNl2P88oI=

当我描述它时,它返回原始输入字符串:

 echo U2FsdGVkX1/yA4J8T+i1M3IZS+TO/V29rBJNl2P88oI= | openssl enc -d -aes-256-cbc -a -k 'absnfjtyrufjdngjvhfgksdfrtifghkv'     

我的问题是,我无法使我的加密在java中工作,并用上面的命令解密它。我知道我的密钥应该使用我的密码短语生成。下面是我的代码示例,其中IV是随机生成的,密钥是使用密码短语和随机salt生成的。

byte[] input = "test".getBytes();
String passphrase = "absnfjtyrufjdngjvhfgksdfrtifghkv";
int saltLength = 8; 
SecureRandom random = new SecureRandom();
//randomly generate salt
byte[] salt = new byte[saltLength];
random.nextBytes(salt);
// generating key from passphrase and salt
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), salt, 1024, 256);
SecretKey key = factory.generateSecret(spec);
SecretKey kspec = new SecretKeySpec(key.getEncoded(), "AES");
// randomly generate IV
byte iv[] = new byte[16];
random.nextBytes(iv);
IvParameterSpec ips = new IvParameterSpec(iv);
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, kspec, ips);
byte[] encryptedData = c.doFinal(input);
System.out.println(new String(Base64.encodeBase64(encryptedData)));

我的java base64输出是XimWIM+8UewzobFOMfevaw==,当我尝试运行这个时:

echo XimWIM+8UewzobFOMfevaw= | openssl enc -d -aes-256-cbc -a -k   'absnfjtyrufjdngjvhfgksdfrtifghkv'

我得到"坏魔术数字"错误。java加密的哪一步我做错了?

根据这个答案,OpenSSL使用的密钥派生算法与您在Java代码中使用的算法不同。因此,用于加密的密钥在OpenSSL命令和Java程序中会有所不同,因此输出会有所不同且不兼容。

您还应该查看OpenSSL中密钥派生函数的文档。显然,它在算法中使用了MD5,而您的Java代码使用的是SHA1。他们不会输出相同的密钥。

您必须指定完全相同的密钥派生函数,或者直接指定密钥,而不是从密码短语派生。

最后,如果安全性是一个问题,请避免为自己创建密钥派生函数(使用bash和Java可以很容易地实现),并坚持标准(如果不是,为什么要使用加密呢?);算法很可能会被破坏。

相关内容

  • 没有找到相关文章

最新更新