如何在服务器上使用C#加密jpeg,并在浏览器上使用Crypt JS解密

如何在服务器上使用C#加密jpeg,并在浏览器上使用Crypt JS解密,c#,cryptojs,C#,Cryptojs,我试图在服务器上加密jpeg并在浏览器上解密,如下所示,但在第3步失败 在服务器上用C#加密jpeg 在客户端浏览器上获取加密数据、向量和密码短语 在客户端浏览器上解密 我试着去做下面的事情,但没有任何帮助 在服务器上使用RijndaelManaged,而不是AesManaged 使用“CryptoJS.enc.Utf16.parse”而不是“CryptoJS.enc.Utf8.parse” 在客户机上 服务器上的加密 public byte[]加密(byte[]字节、字符串密码、字符串向量)

我试图在服务器上加密jpeg并在浏览器上解密,如下所示,但在第3步失败

  • 在服务器上用C#加密jpeg
  • 在客户端浏览器上获取加密数据、向量和密码短语
  • 在客户端浏览器上解密
  • 我试着去做下面的事情,但没有任何帮助

  • 在服务器上使用RijndaelManaged,而不是AesManaged
  • 使用“CryptoJS.enc.Utf16.parse”而不是“CryptoJS.enc.Utf8.parse” 在客户机上
  • 服务器上的加密

    public byte[]加密(byte[]字节、字符串密码、字符串向量)
    {
    aes管理aes=新aes管理();
    aes.KeySize=_KeySize;
    aes.BlockSize=_BlockSize;
    aes.Mode=CipherMode.CBC;
    aes.IV=Encoding.UTF8.GetBytes(向量);
    aes.Key=Encoding.UTF8.GetBytes(密码);
    aes.Padding=PaddingMode.PKCS7;
    byte[]encrypted=aes.CreateEncryptor().TransformFinalBlock(字节,0,字节.长度);
    返回加密;
    }
    
    客户端解密

    //这些值与上面的值相同
    var encrypted=…//字节[]
    变量向量=…//一串
    var密码=…//一串
    var cipherParams=CryptoJS.lib.cipherParams.create({
    iv:CryptoJS.enc.Utf8.parse(向量),
    模式:CryptoJS.mode.CBC,
    填充:CryptoJS.pad.Pkcs7
    });
    var cipherText=CryptoJS.lib.WordArray.create(加密);
    var passwordarray=CryptoJS.enc.Utf8.parse(密码);
    var decrypted=CryptoJS.AES.decrypt(密文、密码数组、密码参数);
    //已解密。此处的单词为空
    
    请告知

    我在Windows 10上使用.Net核心MVC 2.1、Crypto JS 3.1.9-1和Chrome74.0.3729.169

    此问题已解决

    正如Topaco提到的,javascript中存在一个缺陷。更正的代码如下所示

    var encrypted = ... //  byte[]
    var vector = ... // string
    var password = ... // string
    
    var cipherParams = CryptoJS.lib.CipherParams.create({
        iv: CryptoJS.enc.Utf8.parse(vector),
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    var cipherText = CryptoJS.lib.WordArray.create(encrypted);
    var cipherTextParam = CryptoJS.lib.CipherParams.create({
                ciphertext: cipherText
            });
    var passwordWordArray = CryptoJS.enc.Utf8.parse(password);
    var decrypted = CryptoJS.AES.decrypt(cipherTextParam, passwordWordArray, cipherParams);
    

    感谢您的帮助。

    JavaScript代码中有两个缺陷可以更正如下:

    • 在JavaScript代码行中:

      var cipherText = CryptoJS.lib.WordArray.create(encrypted);
      
      var decrypted = CryptoJS.AES.decrypt(cipherText, passwordWordArray, cipherParams);
      
      必须替换为:

      var cipherText = byteArrayToWordArray(encrypted); 
      
      在此,使用该函数:

      也可以使用。在此,使用该函数:

      必须替换为:

      var cipherParamsCipherText = CryptoJS.lib.CipherParams.create({
          ciphertext: cipherText
      });
      var decrypted = CryptoJS.AES.decrypt(cipherParamsCipherText, passwordWordArray, cipherParams);
      
      因为
      decrypted
      -函数需要一个
      CipherParams
      -对象作为第一个参数,而不是
      WordArray

      或者,还可以传递Base64编码的字符串:

      var cipherTextB64Enc = CryptoJS.enc.Base64.stringify(cipherText);   
      var decrypted = CryptoJS.AES.decrypt(cipherTextB64Enc, passwordWordArray, cipherParams);
      
    • 测试:C#-代码提供以下输入:

      byte[] bytes = Encoding.UTF8.GetBytes("The quick brown fox jumps over the lazy dog");
      string password = "0123456789012345"; // 16 byte -> AES-128
      string vector = "5432109876543210";   // 16 byte
      
      以下字节数组作为密文:

      170, 27, 161, 209, 42, 247, 234, 191, 38, 167, 22, 74, 34, 139, 115, 0, 75, 207, 119, 161, 97, 142, 179, 93, 41, 12, 177, 128, 52, 151, 75, 231, 76, 157, 14, 197, 59, 111, 63, 206, 136, 218, 189, 244, 116, 43, 25, 20
      
      如果使用这些数据测试修改后的JavaScript代码:

      var encrypted = [170,27,161,209,42,247,234,191,38,167,22,74,34,139,115,0,75,207,119,161,97,142,179,93,41,12,177,128,52,151,75,231,76,157,14,197,59,111,63,206,136,218,189,244,116,43,25,20]; // byte[]
      var vector = "5432109876543210"    // string
      var password = "0123456789012345"; // string
      
      它被正确地解密了

      在测试中使用了AES-128。只需使用32字节密钥而不是16字节密钥,即可切换到AES-256


    检查与AES填充相关的问题,如果OP因为填充数据而无法解密,他们会遇到问题。您听说过SSL吗?简单的方法是要求https。。。。任何其他方案都会使您将密钥“隐藏”在某个位置,没有很好的解决方案。感谢您的评论,我将检查填充并尝试其他填充选项。我应该提到连接。我将使用VPN,所以连接将是安全的。我的目标是在服务器上存储加密数据,并在客户端对其进行解密。这并不是为了保护AES的连接。非常感谢您的详细解释。你的第二点帮助了我!实际上,我以前尝试过“byteArrayToWordArray”,并观察到函数和“CryptoJS.lib.WordArray.create”返回相同的结果。
    byte[] bytes = Encoding.UTF8.GetBytes("The quick brown fox jumps over the lazy dog");
    string password = "0123456789012345"; // 16 byte -> AES-128
    string vector = "5432109876543210";   // 16 byte
    
    170, 27, 161, 209, 42, 247, 234, 191, 38, 167, 22, 74, 34, 139, 115, 0, 75, 207, 119, 161, 97, 142, 179, 93, 41, 12, 177, 128, 52, 151, 75, 231, 76, 157, 14, 197, 59, 111, 63, 206, 136, 218, 189, 244, 116, 43, 25, 20
    
    var encrypted = [170,27,161,209,42,247,234,191,38,167,22,74,34,139,115,0,75,207,119,161,97,142,179,93,41,12,177,128,52,151,75,231,76,157,14,197,59,111,63,206,136,218,189,244,116,43,25,20]; // byte[]
    var vector = "5432109876543210"    // string
    var password = "0123456789012345"; // string