gpt4 book ai didi

java - 将字符串加密从 Ruby 迁移到 Java

转载 作者:行者123 更新时间:2023-11-30 06:52:57 27 4
gpt4 key购买 nike

我需要在 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 解密,反之亦然,所以我认为这是可以实现的,但我看不出有什么问题。你有好主意吗?如果是的话,那会有很大帮助!

谢谢

最佳答案

首先要做的是derive the IV and key从给定的密码。

从上面的链接中,您将获得分别与 "VDiJjncs4ak=""s9e42J3PpmQv8n5T8L3zzuFaGdrzK/wU" 对应的编码 IV 和 KEY。这意味着Java代码中使用的key和IV vector 是错误的,正如注释中所说。

下面是生成的 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 迁移到 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42404347/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com