JS中的C#解密加密(CryptoJS)

时间:2016-09-15 07:47:31

标签: javascript c# encryption cryptojs tripledes

我在CryptoJS上得不到相同的结果。请你检查一下是什么问题?

这是我预期的输入/输出:

Encrypted String: 723024D59CF7801A295F81B9D5BB616E
Decrypted String: stackoverflow

以下是我在C#中的解密/加密方法。加密是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());

2 个答案:

答案 0 :(得分:1)

CryptoJS期望密文是CipherParams对象或OpenSSL编码的字符串。你已经将密文作为Hex传递。这样做:

var decrypted = CryptoJS.TripleDES.decrypt({
    ciphertext: CryptoJS.enc.Hex.parse('723024D59CF7801A295F81B9D5BB616E')
}, key, { 
    iv : iv, 
    mode:CryptoJS.mode.CBC
});

decrypted现在是WordArray个对象。对其进行字符串化会产生一个字符串,其默认编码为Hex。如果您知道应该输出文本,则可以使用适当的编码,如:

console.log(decrypted.toString(CryptoJS.enc.Utf8));

答案 1 :(得分:0)

Artjom B的答案有效,但如果与静态IV结合使用则存在问题。 IV(和SALT)应随消息而变化。并且尝试在不同的语言/库之间创建和发送非静态IV / SALT可能很困难。

因此,由于我还努力在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(在加密/解密方法中生成)在C#和JS之间交换密文。