gpt4 book ai didi

java - OpenSSL AES/CBC 256 命令输出与 java 代码输出不匹配

转载 作者:太空宇宙 更新时间:2023-11-04 10:53:48 25 4
gpt4 key购买 nike

您好,我正在使用 openSSL 命令来加密和解密我的消息。现在我想在java代码中转换这个命令,我已经尝试了网络上提供的不同解决方案,但没有一个代码与结果匹配。

这是我的 OpenSSL 命令,我在评论中做了简单的说明:

key="FB4FF1BA6F1FCC1A11B8B3910342CBD3A2BEAEB8F52E8910D9B25C0C96280EEA"

# Getting 16 digits from the iv.txt file and putting it into the bin
head -c 16 iv.txt > iv.bin

# Converting iv.bin text into the HEXA value
iv=`xxd -l 16 -p iv.bin`

# encrypt without "-a"
openssl enc -aes-256-cbc -K $key -iv $iv -in plainKey.txt -out encryptedKey.bin

# printing encrypted results in base64 format this need to be matched with my java code.
echo "<enc>"`cat encryptedKey.bin | base64`"</enc>"

这就是我在 Java 中所做的:

注意:来自堆栈溢出的代码接受了稍作更改的答案,我也尝试了一些其他代码,但不能在这里提及全部。

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

public class Test {

public static void main(String[] args) {
try {
runEncryption();
} catch (Exception e) {
e.printStackTrace();
}
}

private static void runEncryption() throws Exception
{
//String to be encrypted
String plainText = "abcd@1234\n";

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

// IV text
String iv = "C837E1B6C3D3A7E28F47719DE0C182C9";

// getting 16 characters of iv text
iv = iv.substring(0,16);

// Value of key
String key = "FB4FF1BA6F1FCC1A11B8B3910342CBD3A2BEAEB8F52E8910D9B25C0C96280EEA";

// Logic for converting 16 Digits of IV into HEX
StringBuffer hexString = new StringBuffer();
for (int i=0;i<iv.getBytes().length;i++) {
String hex=Integer.toHexString(0xff & iv.getBytes()[i]);
if(hex.length()==1) hexString.append('0');
hexString.append(hex);
}

// Seems something wrong here because if i am passing all the bytes to keySpe like key.getBytes() it is producing exception so i am passing 16 bytes as previous code was doing in SO
SecretKeySpec keySpec = new SecretKeySpec(hexToBytes(key), 0, 16, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(hexToBytes(hexString.toString()));

cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));

String encryptedBase64 = new String(DatatypeConverter.printBase64Binary(encrypted));

System.out.println("");
System.out.println("Encrypted base64 = " + encryptedBase64);
}

private static byte[] hexToBytes(String s)
{
int len = s.length();
byte[] data = new byte[len / 2];

for (int i = 0; i < len; i += 2)
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));

return data;
}
}

我正在使用 openSSL 命令生成 key 和 iv

openssl enc -aes-256-cbc -k secret -P -md sha1

这里似乎出了问题,因为如果我将所有字节传递给 keySpec (如 key.getBytes() ),它会产生异常,所以我传递 16 个字节,就像之前的代码在 SO 中所做的那样,我也在代码注释中提到了这一点,请就此提出建议,谢谢。

最佳答案

您的代码中有几个错误

假设您想要做的是

 openssl enc -aes-256-cbc -K FB4FF1BA6F1FCC1A11B8B3910342CBD3A2BEAEB8F52E8910D9B25C0C96280EEA -iv 03B13BBE886F00E00000000000000000 -base64 -in input.txt

在你的代码中你有一些错误(wtf时刻)。我不会为你修复它们,但基本上:

  1. 我建议使用一些普通的库(例如 commons-codec,..)来从十六进制编码/解码,尽管到目前为止它似乎正在工作

  2. 您正在使用 16 字节(128 位)iv 和 key 有效地执行 AES-128。您需要使用具有 key 和 iv 256 位长(32 字节)的 AES-256。您已将两者都削减为 16 个字节,因此它们与 openssl 使用的值不同

  3. 主要断点:IvParameterSpec ivSpec = new IvParameterSpec(hexToBytes(hexString.toString()));请稍微考虑一下。 hexToBytes(iv)

关于java - OpenSSL AES/CBC 256 命令输出与 java 代码输出不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47513894/

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