将字符串加密从 Ruby 迁移到 Java
Migrate String encryption from Ruby to Java
我需要在 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 解密数据,反之亦然,所以我认为这是可以实现的,但我看不出有什么问题。你有好主意吗?如果是这样,那将有很大帮助!
谢谢
首先要做的是从给定的密码。
从上面的link,你会得到一个编码后的IV和KEY分别对应"VDiJjncs4ak="
和"s9e42J3PpmQv8n5T8L3zzuFaGdrzK/wU"
。
这意味着 Java 代码中使用的密钥和 IV 向量是错误的,正如评论中所说的那样。
下面是生成的 Java 代码:
public class SymmetricDESedeCipher {
private static final String DATA = "Whackabad";
private static final String ALGORITHM = "DESede";
private static final String XFORM = "DESede/CBC/PKCS5Padding";
private static final String KEY = "s9e42J3PpmQv8n5T8L3zzuFaGdrzK/wU";
private static final String IV = "VDiJjncs4ak=";
private static byte[] encrypt(String data,
SecretKey key, String XFORM, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance(XFORM);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(data.getBytes());
}
public static void main(String[] unused) throws Exception {
DESedeKeySpec spec = new DESedeKeySpec(new BASE64Decoder().decodeBuffer(KEY));
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(ALGORITHM);
SecretKey secretKey = secretKeyFactory.generateSecret(spec);
byte[] encBytes = encrypt(DATA, secretKey, XFORM, new BASE64Decoder().decodeBuffer(IV));
System.out.println("Data: " + DATA);
System.out.println("Encrypted Data: " + new BASE64Encoder().encode(encBytes));
}
}
输出:
Data: Whackabad
Encrypted Data: AEsDXVcgh2jsTjlDgh+REg==
我需要在 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 解密数据,反之亦然,所以我认为这是可以实现的,但我看不出有什么问题。你有好主意吗?如果是这样,那将有很大帮助!
谢谢
首先要做的是从给定的密码
从上面的link,你会得到一个编码后的IV和KEY分别对应"VDiJjncs4ak="
和"s9e42J3PpmQv8n5T8L3zzuFaGdrzK/wU"
。
这意味着 Java 代码中使用的密钥和 IV 向量是错误的,正如评论中所说的那样。
下面是生成的 Java 代码:
public class SymmetricDESedeCipher {
private static final String DATA = "Whackabad";
private static final String ALGORITHM = "DESede";
private static final String XFORM = "DESede/CBC/PKCS5Padding";
private static final String KEY = "s9e42J3PpmQv8n5T8L3zzuFaGdrzK/wU";
private static final String IV = "VDiJjncs4ak=";
private static byte[] encrypt(String data,
SecretKey key, String XFORM, byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance(XFORM);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(data.getBytes());
}
public static void main(String[] unused) throws Exception {
DESedeKeySpec spec = new DESedeKeySpec(new BASE64Decoder().decodeBuffer(KEY));
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(ALGORITHM);
SecretKey secretKey = secretKeyFactory.generateSecret(spec);
byte[] encBytes = encrypt(DATA, secretKey, XFORM, new BASE64Decoder().decodeBuffer(IV));
System.out.println("Data: " + DATA);
System.out.println("Encrypted Data: " + new BASE64Encoder().encode(encBytes));
}
}
输出:
Data: Whackabad
Encrypted Data: AEsDXVcgh2jsTjlDgh+REg==