【问题标题】:Encrypt text using AES in Javascript then Decrypt in C# WCF Service在 Javascript 中使用 AES 加密文本,然后在 C# WCF 服务中解密
【发布时间】:2014-11-19 14:19:39
【问题描述】:

我正在尝试使用 AES 128 位加密来加密字符串。我有 Javascript 和 C# 的代码。主要目标是使用 Javascript CryptoJS 加密字符串,然后获取生成的密文并使用 C# AES AesCryptoServiceProvider 对其进行解密。

Javascript 代码:

function EncryptText()
{
var text = document.getElementById('textbox').value;
var Key = CryptoJS.enc.Hex.parse("PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0=");
var IV = CryptoJS.enc.Hex.parse("YWlFLVEZZUFNaWl=");
var encryptedText = CryptoJS.AES.encrypt(text, Key, {iv: IV, mode: CryptoJS.mode.CBC, padding:     CryptoJS.pad.Pkcs7});
//var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase");
var encrypted = document.getElementById('encrypted');
encrypted.value = encryptedText;
}

C#代码:

private String AES_decrypt(string encrypted)
    {
        byte[] encryptedBytes = Convert.FromBase64String(encrypted);
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 256;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.Pkcs7;
        aes.Key = Key;
        aes.IV = IV;
        ICryptoTransform crypto = aes.CreateDecryptor(aes.Key, aes.IV);
        byte[] secret = crypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
        crypto.Dispose();
        return System.Text.ASCIIEncoding.ASCII.GetString(secret);
    }

当使用“hello”作为 javascript 的纯文本时,我得到了这个密文:

uqhe5ya+mISuK4uc1WxxeQ==

将其传递到 C# 应用程序时,在运行 Decrypt 方法时我收到:

Padding is invalid and cannot be removed.

我被难住了,并尝试了许多解决方案,导致同样的错误。

当通过我收到的 C# 加密 AES 方法加密你好时:

Y9nb8DrV73+rmmYRUcJiOg==

提前感谢您的帮助!

【问题讨论】:

  • 如果你使用会发生什么: var Key = CryptoJS.enc.Utf8.parse("PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0=");而不是十六进制?你在 C# 中的 Key 和 IV 是什么?因为实际上您放入密钥和解析的字符串不是十六进制字符串。十六进制为 0 到 F
  • 实际上你在 Javascript 中的 IV 字符串也不是十六进制的。
  • 嗨 Uwe,如果您将此评论作为答案发布,我很乐意将其标记为答案。将其更改为 utf8 有效!谢谢一百万!

标签: javascript c# wcf encryption cryptography


【解决方案1】:

javascript代码:

function EncryptText()
{
   var text = CryptoJS.enc.Utf8.parse(document.getElementById('textbox').value);
   var Key = CryptoJS.enc.Utf8.parse("PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0="); //secret key
   var IV = CryptoJS.enc.Utf8.parse("2314345645678765"); //16 digit
   var encryptedText = CryptoJS.AES.encrypt(text, Key, {keySize: 128 / 8,iv: IV, mode: CryptoJS.mode.CBC, padding:CryptoJS.pad.Pkcs7});
   var encrypted = document.getElementById('encrypted');
   encrypted.value = encryptedText;
   //Pass encryptedText through service 

}

C#代码:

private String AES_decrypt(string encrypted,String secretKey,String initVec)
{
    byte[] encryptedBytes = Convert.FromBase64String(encrypted);
    AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
    //aes.BlockSize = 128; Not Required
    //aes.KeySize = 256; Not Required
    aes.Mode = CipherMode.CBC;
    aes.Padding = PaddingMode.Pkcs7;
    aes.Key = Encoding.UTF8.GetBytes(secretKey);PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0=
    aes.IV = Encoding.UTF8.GetBytes(initVec); //2314345645678765
    ICryptoTransform crypto = aes.CreateDecryptor(aes.Key, aes.IV);
    byte[] secret = crypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
    crypto.Dispose();
    return System.Text.ASCIIEncoding.ASCII.GetString(secret);
}

使用上面的代码工作正常!!!

【讨论】:

  • 不错的一个Praj!很有魅力。 (角度 7 和 .net 4.7.2)
  • 适用于 Angular 8 和 Net Core 2.2!
【解决方案2】:

尝试使用 var Key = CryptoJS.enc.Utf8.parse("PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0=");而不是十六进制。
因为实际上您放入密钥(和 IV)并解析的字符串不是十六进制字符串。十六进制是 0 到 F。

【讨论】:

    【解决方案3】:

    首先,您在 JS 中的 Key 变量包含一个包含 32 个字符的字符串(在看起来很奇怪的 parse 调用之后)。尽管这可能被解释为 128 位密钥,但 CryptoJS 有一定的机会将其作为密码短语(并使用某种算法从中生成密钥)。因此,您的实际密钥看起来完全不同。该字符串看起来也很像十六进制编码,因此对于它的 C# 值可能会有一些额外的混淆。您必须确保在 JS 和 C# 中使用相同的密钥。

    其次,IV 变量在解析后也看起来像一个十六进制编码值。所以你必须小心你在 C# 端使用的值。

    仅供参考,以下是解析后 KeyIV 的值: Key = 00000000000e00000d000c0000010000, IV = 0000000e000f0a00

    【讨论】:

    • 感谢您的建议。
    【解决方案4】:

    感谢“Uwe”用 UTF8 解析解决了所有问题。

    如果你使用会发生什么: var Key = CryptoJS.enc.Utf8.parse("PSVJQRk9QTEpNVU1DWUZCRVFGV1VVT0=");而不是 > 十六进制?你在 C# 中的 Key 和 IV 是什么?因为实际上您放入密钥和 >parsing 的字符串不是十六进制字符串。十六进制为 0 到 F

    非常感谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      相关资源
      最近更新 更多