【发布时间】:2017-02-22 23:35:19
【问题描述】:
我需要在 Java 中生成与使用 Ruby encrypted_strings 库构建的加密字符串相同的加密字符串。我尝试了许多不同的方法,但我的 Java 代码不断返回不同的输出,我无法理解我做错了什么。
以下是生成所需输出的 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 解密,反之亦然,使用不同的算法,所以我认为这可以实现,但我看不出有什么问题。你有想法吗?如果是这样,那将有很大帮助!
谢谢
【问题讨论】:
-
首先确保您使用相同的字节。不同语言之间的字符串表示形式差异很大。
-
您确定要使用那个 ruby 加密库吗?文档似乎表明它从密码中派生了初始化向量,这是一个糟糕的主意——IV's should be random
-
是的@dnault,这是我试图翻译成 Java 的遗留方法,因此该方法是目前正在使用的方法,也是我想要复制的方法。
-
如果你想要 bug-for-bug 兼容性,我会研究 ruby 库如何派生 IV,然后在 Java 中做同样的事情(而不是像现在的代码那样使用全零的 IV )。
-
3DES(一种超越质数的算法)采用 24 字节密钥,您提供的是 50 个字符的字符串,这是不正确的。
标签: java ruby encryption des