gpt4 book ai didi

java - 以与 Java 相同的方式使用 OpenSSL 进行加密

转载 作者:搜寻专家 更新时间:2023-11-01 03:02:33 24 4
gpt4 key购买 nike

我必须使用 bash 脚本加密字符串,就像使用 javax.crypto.Cipher 加密一样。在 java 中,我使用 key 为“0123456789”的 AES-256。但是当我使用 openssl 时,我不得不将“0123456789”转换为十六进制,但结果与 java 不同

echo "lun01" | openssl aes-256-cbc -e -a -K 7573746f726530313233343536373839 -iv 7573746f726530313233343536373839

dpMyN7L5HI8VZEs1biQJ7g==

Java:

public class CryptUtil {
public static final String DEFAULT_KEY = "0123456789";

private static CryptUtil instance;

private String chiperKey;

private CryptUtil(String chiperKey) {
this.chiperKey = chiperKey;
}

public static CryptUtil getInstance() {
if (null == instance) {
instance = new CryptUtil(DEFAULT_KEY);
}

return instance;
}

public static CryptUtil getInstance(String cipherkey) {
instance = new CryptUtil(cipherkey);
return instance;
}

public String aesEncrypt(String plainText) {
byte[] keyBytes = Arrays.copyOf(this.chiperKey.getBytes("ASCII"), 16);

SecretKey key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);

byte[] cleartext = plainText.getBytes("UTF-8");
byte[] ciphertextBytes = cipher.doFinal(cleartext);
final char[] encodeHex = Hex.encodeHex(ciphertextBytes);

return new String(encodeHex);

return null;
}

public static void main(String[] args) {

CryptUtil cryptUtil = CryptUtil.getInstance();
System.out.println(cryptUtil.aesEncrypt("lun01"));
}
}

d230b216e9d65964abd4092f5c455a21

最佳答案

如果无数的在线十六进制转换器都不起作用,那么您可以简单地将您在 Java 中使用的 key 打印为十六进制。 Here是关于此壮举 的热门 SO 问题。

完成之后,您会发现它仍然不起作用,因为您使用的是不同的算法。

当您使用 Cipher.getInstance("AES"); 时,它很可能会默认为“AES/ECB/PKCS5Padding”,这与“aes-256-cbc”不同,因为ECB和CBC是两个完全不同的modes of operation .为了防止这种歧义,请始终完全限定您的密码,例如:Cipher.getInstance("AES/CBC/PKCS5Padding");

然后您在 Java 中生成的 key 只有 16 个字节长,因此在 OpenSSL 中匹配的密码将是“aes-128-ecb”。

正如 dave_thompson_085 在 comment 中所说:

  • echo 添加一个您的 Java 代码没有添加的换行符。您需要以这种方式创建明文:echo -n "lun01"。或查看 this如果您使用的是 Windows。

  • 您的 Java 代码将结果输出为十六进制,因此您需要在 OpenSSL 中执行相同的操作。您需要删除 OpenSSL 命令中的 -a 选项以防止 Base64 编码,然后您可以使用其他命令行工具,例如 linux 上的 od 将二进制输出数据转换为十六进制与 od -tx1

  • 完整命令:

    echo -n lun01 |openssl aes-128-ecb -K 30313233343536373839000000000000 |od -tx1

不要使用 ECB 模式!它在语义上不安全。您至少需要使用带有随机 IV 的 CBC 模式(检查它是随机的,而不仅仅是零字节)。

更好的方法是添加身份验证,例如通过先加密然后 MAC 方法添加 HMAC 标记,或者简单地使用像 GCM 这样的身份验证模式。


如果您使用的不是 ECB,那么您不能在两个版本中加密相同的内容并期望出现相同的密文。由于它是随机的,您需要在一个版本中加密并在另一个版本中解密以确保兼容性。

关于java - 以与 Java 相同的方式使用 OpenSSL 进行加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32018672/

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