gpt4 book ai didi

javascript - 用Java重现加密方法

转载 作者:行者123 更新时间:2023-11-30 06:53:32 26 4
gpt4 key购买 nike

我已经用 C# 和 Javascript 编写了两个函数来解密和加密消息,但我也需要用 Java 来解密和加密消息,但我无法让它像以前的函数一样工作。

JS加密方式:

this.aesEncrypt = function (encryptedMessage) {
var key = CryptoJS.enc.Utf8.parse("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
var initialVector = CryptoJS.enc.Utf8.parse("xxxxxxxxxxxxxxxx");
var encryptedText = CryptoJS.AES.encrypt(encryptedMessage, key,
{
iv: initialVector,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encryptedText.toString().hexEncode();
}
String.prototype.hexEncode = function () {
var hex, i;

var result = "";
for (i = 0; i < this.length; i++) {
hex = this.charCodeAt(i).toString(16);
result += ("0" + hex).slice(-2);
}

return result;
}

C#解密方法:

private static string AesDecrypt(string encryptedMessage)
{
try
{
var temp = FromHex(encryptedMessage);
var encryptedBytes = Convert.FromBase64String(Encoding.ASCII.GetString(temp));
var aes = new AesCryptoServiceProvider
{
BlockSize = 128,
KeySize = 256,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
Key = Encoding.UTF8.GetBytes("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"),
IV = Encoding.UTF8.GetBytes("xxxxxxxxxxxxxxxx")
};
var crypto = aes.CreateDecryptor(aes.Key, aes.IV);
var secret = crypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
crypto.Dispose();
return Encoding.ASCII.GetString(secret);
}
catch (Exception)
{
return null;
}
}

public static byte[] FromHex(string hex)
{
hex = hex.Replace("-", "");
var raw = new byte[hex.Length / 2];
for (var i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
return raw;
}

Java加密方法:

public static String toHex(String arg) {
return String.format("%x", new BigInteger(1, arg.getBytes()));
}
public static String AesEncrypt(String encryptedMessage){
try {
IvParameterSpec initialVector = new IvParameterSpec("xxxxxxxxxxxxxxxx".getBytes("UTF-8"));
SecretKeySpec secretKeySpec = new SecretKeySpec("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".getBytes("UTF-8"), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, initialVector);

byte[] encrypted = cipher.doFinal(encryptedMessage.getBytes());
StringBuilder encryptedSb = new StringBuilder(encrypted.length);
for (byte i : encrypted){
encryptedSb.append(i);
}
return toHex(encryptedSb.toString());
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}

Java加密后返回80个十六进制数字,JS返回48个十六进制数字。AFAIK Java PKCS5 填充与 C# PKCS7 填充相同。

我还尝试使用结果的 base64 编码
http://commons.apache.org/proper/commons-codec/download_codec.cgi
,但仍然不是这个。

public static String AesEncrypt(String encryptedMessage){
try {
IvParameterSpec initialVector = new IvParameterSpec("xxxxxxxxxxxxxxxx".getBytes("UTF-8"));
SecretKeySpec secretKeySpec = new SecretKeySpec("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".getBytes("UTF-8"), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, initialVector);

byte[] encrypted = cipher.doFinal(encryptedMessage.getBytes());

byte[] base64 = Base64.encodeBase64(encrypted);

StringBuilder encryptedSb = new StringBuilder(base64.length);
for (byte i : base64){
encryptedSb.append(i);
}
return toHex(encryptedSb.toString());
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}

最佳答案

无论任何其他参数如何,AES 都在 16 字节 block 上运行。 Java AES 中的 PCKS#5 填充将解析为 PCKS#7 。使用 PCKS#7,您将填充到 block 边界;即填充到最接近的 16 个字节。

您的 UTF-8 输入“ABC”是 3 个字节。 16 字节将需要 (16–3)=13 字节的填充。因此,密文将为 16 个字节,即 32 个十六进制字符。

总而言之,我相信您的 StringBuildertoHex() 逻辑之间的编码转换有问题。尝试使用DatatypeConverter.printHexBinary(byte[] val)byte[]加密转换回十六进制。

关于javascript - 用Java重现加密方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42252463/

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