JS中的加密和C#解密(CryptoJS)
Encryption in C# Decryption in JS (CryptoJS)
我在 CryptoJS 上没有得到相同的结果。可以请你检查一下有什么问题吗?
这是我的预期 input/outputs:
Encrypted String: 723024D59CF7801A295F81B9D5BB616E
Decrypted String: Whosebug
这是我在 C# 中的 Decryption/Encryption 方法。加密是 TripleDES 模式 CBC,我在 CryptoJS 代码上使用相同的密钥和 iv。
public static string Encrypt(string data, string key, string iv)
{
byte[] bdata = Encoding.ASCII.GetBytes(data);
byte[] bkey = HexToBytes(key);
byte[] biv = HexToBytes(iv);
var stream = new MemoryStream();
var encStream = new CryptoStream(stream,
des3.CreateEncryptor(bkey, biv), CryptoStreamMode.Write);
encStream.Write(bdata, 0, bdata.Length);
encStream.FlushFinalBlock();
encStream.Close();
return BytesToHex(stream.ToArray());
}
public static string Decrypt(string data, string key, string iv)
{
byte[] bdata = HexToBytes(data);
byte[] bkey = HexToBytes(key);
byte[] biv = HexToBytes(iv);
var stream = new MemoryStream();
var encStream = new CryptoStream(stream,
des3.CreateDecryptor(bkey, biv), CryptoStreamMode.Write);
encStream.Write(bdata, 0, bdata.Length);
encStream.FlushFinalBlock();
encStream.Close();
return Encoding.ASCII.GetString(stream.ToArray());
}
这是我使用 CryptoJS 进行解密的方法
var key = "90033E3984CEF5A659C44BBB47299B4208374FB5DC495C96";
var iv = "E6B9AFA7A282A0CA";
key = CryptoJS.enc.Hex.parse(key);
iv = CryptoJS.enc.Hex.parse(iv);
// Input is a Hex String
var decrypted = CryptoJS.TripleDES.decrypt('723024D59CF7801A295F81B9D5BB616E', key, { iv : iv, mode:CryptoJS.mode.CBC});
console.log(decrypted.toString());
CryptoJS 期望密文是 CipherParams
对象或 OpenSSL 编码的字符串。您已将密文作为十六进制传递。改为这样做:
var decrypted = CryptoJS.TripleDES.decrypt({
ciphertext: CryptoJS.enc.Hex.parse('723024D59CF7801A295F81B9D5BB616E')
}, key, {
iv : iv,
mode:CryptoJS.mode.CBC
});
decrypted
现在是一个 WordArray
对象。将其字符串化会生成一个默认编码为十六进制的字符串。如果您知道应该输出文本,则可以使用适当的编码,例如:
console.log(decrypted.toString(CryptoJS.enc.Utf8));
Artjom B 的答案有效,但如果与静态 IV 一起使用则会出现问题。 IV(和 SALT)应该随着消息的不同而变化。并且尝试在不同 languages/libraries 之间创建和发送非静态 IV / SALTS 可能很困难。
因此,当我还在为在 C# 和 JS 之间交换加密文本而苦苦挣扎时,我花时间一劳永逸地解决了这个问题,并编写了一个小型库并在 MIT 许可下发布了它供大家使用。
密文为base64,由":"与base64-SALT和base64-IV组合
这些是使用它的步骤:
使用来自https://github.com/smartinmedia/Net-Core-JS-Encryption-Decryption
的库
对于 C#:
//Encrypt plain text in C# with a random password
string plainText = "This is my secret text!";
//You can also use the built in password generator!!
//string passPhrase = PasswordGenerator.GenerateRandomPassword(20);
//Or use your own password:
string passPhrase = "This_is_my_password!";
var enc = EncryptionHandler.Encrypt(plainText, passPhrase);
Console.WriteLine("Plaintext: 'This is my secret text' with password 'This_is_my_password!' results in ciphertext: " + enc);
var dec3 = EncryptionHandler.Decrypt(enc, passPhrase);
Console.WriteLine("And decrypting again: " + dec3);
Console.WriteLine("Please start the index.html to see the same in Javascript. Encryption / Decryption run in both ways and can be interchanged between C# and JS!");
对于 JS:
// This is the ciphertext, which was encrypted by C# to check the interchangeability:
var encryptedBase64FromCSharp = "uTkXNB+PSTjzwUCJbfAHVHd95YOlcJr38wbF08ZxqNw=:PNGRjWb5tOINneaVVf8+cw==:Aic+gosvLjTrCebzY8l/usTh+kWuE0v1xSWw7apYunI=";
var passPhrase = "This_is_my_password!";
var eH = new encryptionHandler();
var decryptedFromCSharp = eH.decrypt(encryptedBase64FromCSharp, passPhrase);
//Now encrypt again with JS
var encryptTextWithJs = eH.encrypt(decryptedFromCSharp, "This_is_my_password!");
//And decrypt again with JS
var decryptedTextWithJs = eH.decrypt(encryptTextWithJs, "This_is_my_password!");
因此,正如您在此处看到的那样,可以使用随机生成的 SALT 和 IV(在方法 encrypt/decrypt 中生成)在 C# 和 JS 之间交换密文。
我在 CryptoJS 上没有得到相同的结果。可以请你检查一下有什么问题吗?
这是我的预期 input/outputs:
Encrypted String: 723024D59CF7801A295F81B9D5BB616E
Decrypted String: Whosebug
这是我在 C# 中的 Decryption/Encryption 方法。加密是 TripleDES 模式 CBC,我在 CryptoJS 代码上使用相同的密钥和 iv。
public static string Encrypt(string data, string key, string iv)
{
byte[] bdata = Encoding.ASCII.GetBytes(data);
byte[] bkey = HexToBytes(key);
byte[] biv = HexToBytes(iv);
var stream = new MemoryStream();
var encStream = new CryptoStream(stream,
des3.CreateEncryptor(bkey, biv), CryptoStreamMode.Write);
encStream.Write(bdata, 0, bdata.Length);
encStream.FlushFinalBlock();
encStream.Close();
return BytesToHex(stream.ToArray());
}
public static string Decrypt(string data, string key, string iv)
{
byte[] bdata = HexToBytes(data);
byte[] bkey = HexToBytes(key);
byte[] biv = HexToBytes(iv);
var stream = new MemoryStream();
var encStream = new CryptoStream(stream,
des3.CreateDecryptor(bkey, biv), CryptoStreamMode.Write);
encStream.Write(bdata, 0, bdata.Length);
encStream.FlushFinalBlock();
encStream.Close();
return Encoding.ASCII.GetString(stream.ToArray());
}
这是我使用 CryptoJS 进行解密的方法
var key = "90033E3984CEF5A659C44BBB47299B4208374FB5DC495C96";
var iv = "E6B9AFA7A282A0CA";
key = CryptoJS.enc.Hex.parse(key);
iv = CryptoJS.enc.Hex.parse(iv);
// Input is a Hex String
var decrypted = CryptoJS.TripleDES.decrypt('723024D59CF7801A295F81B9D5BB616E', key, { iv : iv, mode:CryptoJS.mode.CBC});
console.log(decrypted.toString());
CryptoJS 期望密文是 CipherParams
对象或 OpenSSL 编码的字符串。您已将密文作为十六进制传递。改为这样做:
var decrypted = CryptoJS.TripleDES.decrypt({
ciphertext: CryptoJS.enc.Hex.parse('723024D59CF7801A295F81B9D5BB616E')
}, key, {
iv : iv,
mode:CryptoJS.mode.CBC
});
decrypted
现在是一个 WordArray
对象。将其字符串化会生成一个默认编码为十六进制的字符串。如果您知道应该输出文本,则可以使用适当的编码,例如:
console.log(decrypted.toString(CryptoJS.enc.Utf8));
Artjom B 的答案有效,但如果与静态 IV 一起使用则会出现问题。 IV(和 SALT)应该随着消息的不同而变化。并且尝试在不同 languages/libraries 之间创建和发送非静态 IV / SALTS 可能很困难。
因此,当我还在为在 C# 和 JS 之间交换加密文本而苦苦挣扎时,我花时间一劳永逸地解决了这个问题,并编写了一个小型库并在 MIT 许可下发布了它供大家使用。
密文为base64,由":"与base64-SALT和base64-IV组合
这些是使用它的步骤:
使用来自https://github.com/smartinmedia/Net-Core-JS-Encryption-Decryption
的库对于 C#:
//Encrypt plain text in C# with a random password
string plainText = "This is my secret text!";
//You can also use the built in password generator!!
//string passPhrase = PasswordGenerator.GenerateRandomPassword(20);
//Or use your own password:
string passPhrase = "This_is_my_password!";
var enc = EncryptionHandler.Encrypt(plainText, passPhrase);
Console.WriteLine("Plaintext: 'This is my secret text' with password 'This_is_my_password!' results in ciphertext: " + enc);
var dec3 = EncryptionHandler.Decrypt(enc, passPhrase);
Console.WriteLine("And decrypting again: " + dec3);
Console.WriteLine("Please start the index.html to see the same in Javascript. Encryption / Decryption run in both ways and can be interchanged between C# and JS!");
对于 JS:
// This is the ciphertext, which was encrypted by C# to check the interchangeability:
var encryptedBase64FromCSharp = "uTkXNB+PSTjzwUCJbfAHVHd95YOlcJr38wbF08ZxqNw=:PNGRjWb5tOINneaVVf8+cw==:Aic+gosvLjTrCebzY8l/usTh+kWuE0v1xSWw7apYunI=";
var passPhrase = "This_is_my_password!";
var eH = new encryptionHandler();
var decryptedFromCSharp = eH.decrypt(encryptedBase64FromCSharp, passPhrase);
//Now encrypt again with JS
var encryptTextWithJs = eH.encrypt(decryptedFromCSharp, "This_is_my_password!");
//And decrypt again with JS
var decryptedTextWithJs = eH.decrypt(encryptTextWithJs, "This_is_my_password!");
因此,正如您在此处看到的那样,可以使用随机生成的 SALT 和 IV(在方法 encrypt/decrypt 中生成)在 C# 和 JS 之间交换密文。