我需要在Java中生成与使用Ruby encrypted_strings库生成的加密字符串相同的加密字符串。我尝试了很多不同的方法,但是我的Java代码一直返回不同的输出结果,我无法理解我做错了什么。按照加密方法从encrypted_strings加密Java中的字符串ruby lib
下面是生成所需输出的ruby脚本,我无法在Java中正确使用它。
#!/usr/bin/ruby
require 'encrypted_strings'
data = 'Whackabad'
password = 'bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ'
encrypted_data = data.encrypt(:symmetric, :password => password)
printf "Data: #{data}\n"
printf "Encrypted Data: #{encrypted_data}"
输出:
Data: Whackabad
Encrypted Data: AEsDXVcgh2jsTjlDgh+REg==
我看了一下图书馆,它好像是用DES-EDE3-CBC
作为加密的默认算法。我从这里推断出我应该使用DESede
或TripleDES
算法和CBC
模式。作为填充选项,我使用的是PKCS5Padding
,导致库调用pkcs5_keyivgen
。
下面是尝试重现相同输出失败的Java代码。
package ...
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
public class SymmetricDESedeCipher {
private static final String DATA = "Whackabad";
private static final String key = "bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ";
private static final String ALGORITHM = "DESede";
private static final String XFORM = "DESede/CBC/PKCS5Padding";
private static byte[] iv = new byte[8];
private static byte[] encrypt(byte[] inpBytes,
SecretKey key, String XFORM) throws Exception {
Cipher cipher = Cipher.getInstance(XFORM);
IvParameterSpec ips = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ips);
return cipher.doFinal(inpBytes);
}
public static void main(String[] unused) throws Exception {
byte[] keyBytes = key.getBytes();
DESedeKeySpec desKeySpec = new DESedeKeySpec(keyBytes);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(ALGORITHM);
SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
byte[] dataBytes = DATA.getBytes();
byte[] encBytes = encrypt(dataBytes, secretKey, XFORM);
System.out.println("Data: " + DATA);
System.out.println("Encrypted Data: " + new BASE64Encoder().encode(encBytes));
}
}
输出
Data: Whackabad
Encrypted Data: ScPTKQBsR9Ni1nJ1tsMaaQ==
我见过人们从Java加密数据从Ruby和反之亦然用不同的算法进行解密,所以我认为这是可以实现的,但我看不出有什么错误。你有好主意吗?如果是这样,那会有很大的帮助!
感谢
开始通过确保您使用的是相同的字节。字符串表示在不同语言之间差别很大 – chrylis
您确定要使用该红宝石加密库吗?该文档似乎表明它从密码派生初始化向量,这是一个可怕的想法 - [IV应该是随机的](http://crypto.stackexchange.com/a/82) – dnault
是的@dnault,它的遗产是什么我试图翻译成Java,因此这个方法就是这个时候使用的方法,也是我想要复制的方法。 – rakemous