AES.js加密解密与C#的相互转换

AES简介

AES, Advanced Encryption Standard,其实是一套标准:FIPS 197,而我们所说的AES算法其实是Rijndael算法。

NIST (National INstitute of Standards and Technology) 在1997年9月12日公开征集更高效更安全的替代DES加密算法,第一轮共有15种算法入选,其中5种算法入围了决赛,分别是MARS,RC6,Rijndael,Serpent和Twofish。又经过3年的验证、评测及公众讨论之后Rijndael算法最终入选。

思维导图

Rijndael算法

Rijndael算法是由比利时学者Joan Daemen和Vincent Rijmen所提出的,算法的名字就由两位作者的名字组合而成。Rijndael的优势在于集安全性、性能、效率、可实现性及灵活性与一体。

背景

由于在HTTP中参数都是通过URL或者Body进行传输的,那么就存在信息的暴露问题,这时候很多敏感的信息就需要进行加密,防止敏感信息泄露。

具体实现

1、服务端加密/解密
public class DecryptStringAES
{
      /// <summary>  
      /// AES加密算法  
      /// </summary>  
      /// <param name="input">明文字符串</param>  
      /// <returns>字符串</returns>  
      public static string EncryptByAES(string input)
      {
     	  if (string.IsNullOrWhiteSpace(input))
          {
              return input;
          }
          using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
          {
              rijndaelManaged.Mode = CipherMode.CBC;
              rijndaelManaged.Padding = PaddingMode.PKCS7;
              rijndaelManaged.FeedbackSize = 128;

              rijndaelManaged.Key = Encoding.UTF8.GetBytes(Decrypt.Key);
              rijndaelManaged.IV = Encoding.UTF8.GetBytes(Decrypt.AES_IV);

              ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(rijndaelManaged.Key, rijndaelManaged.IV);
              using (MemoryStream msEncrypt = new MemoryStream())
              {
                  using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                  {
                      using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                      {
                          swEncrypt.Write(input);
                      }
                      byte[] bytes = msEncrypt.ToArray();
                      return Convert.ToBase64String(bytes);
                  }
              }
          }
      }

      /// <summary>  
      /// AES解密  
      /// </summary>  
      /// <param name="input">密文字节数组</param>  
      /// <returns>返回解密后的字符串</returns>  
      public static string DecryptByAES(string input)
      {
   		  if (string.IsNullOrWhiteSpace(input))
          {
              return input;
          }
          var buffer = Convert.FromBase64String(input);
          using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
          {
              rijndaelManaged.Mode = CipherMode.CBC;
              rijndaelManaged.Padding = PaddingMode.PKCS7;
              rijndaelManaged.FeedbackSize = 128;

              rijndaelManaged.Key = Encoding.UTF8.GetBytes(Decrypt.Key);
              rijndaelManaged.IV = Encoding.UTF8.GetBytes(Decrypt.AES_IV);

              ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(rijndaelManaged.Key, rijndaelManaged.IV);
              using (MemoryStream msEncrypt = new MemoryStream(buffer))
              {
                  using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read))
                  {
                      using (StreamReader srEncrypt = new StreamReader(csEncrypt))
                      {
                          return srEncrypt.ReadToEnd();
                      }
                  }
              }
          }
      }        
  }
2、 客户端(JS)
  • 定义Key/IV
const key = CryptoJS.enc.Utf8.parse("1234567890000000");
const iv = CryptoJS.enc.Utf8.parse("1234567890000000");
  • 加密方法
//**************************************************************
//*字符串/对象加密
//*   0:需要解密的字符串或对象
//****************************************************************/
function Encrypt(o) {
   if (typeof (o) === "string") {
        if (o) {
            var srcs = CryptoJS.enc.Utf8.parse(o);
            return CryptoJS.AES.encrypt(srcs, key, {
                keySize: 128 / 8,
                iv: iv,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            }).toString();
        }
    }
    else if (typeof (o) === "object") {
        for (var _o in o) {
            if (o[_o]) {
                var srcs = CryptoJS.enc.Utf8.parse(o[_o]);
                o[_o] = CryptoJS.AES.encrypt(srcs, key, {
                    keySize: 128 / 8,
                    iv: iv,
                    mode: CryptoJS.mode.CBC,
                    padding: CryptoJS.pad.Pkcs7
                }).toString();
            }
        };

    }
    return o;
}
  • 解密方法
//**************************************************************
//*字符串解密
//*   str:需要解密的字符串
//****************************************************************/
function Decrypt(str) {
   var decrypt = CryptoJS.AES.decrypt(str, key, {
        keySize: 128 / 8,
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
    return decryptedStr;
}

客户端和服务端的KEY/IV必须保持一致

3、展示效果
  • 采用简单的注册信息进行测试
    在这里插入图片描述
  • Js进行加密后的值
    在这里插入图片描述
  • 服务端解密的值与注册的验证码一致
    在这里插入图片描述

总结

由于不是很善于写文章,希望将自己平时的点滴进行记录,这样能够锻炼写作能力,还能分享出自己的成果,当看到很多园友看了我的文章并点赞的时候心里还是有那么一丝丝欣慰的。

参考资料

  • https://www.c-sharpcorner.com/UploadFile/4d9083/encrypt-in-javascript-and-decrypt-in-C-Sharp-with-aes-algorithm/
  • https://stackoverflow.com/questions/19094547/aes-encryption-in-c-sharp-and-decryption-in-cryptojs
  • crypto npm https://www.npmjs.com/package/crypto-js
  • Aes文档 https://github.com/matt-wu/AES

demo下载地址:https://download.csdn.net/download/xhl_james/11143064

原文地址:https://www.cnblogs.com/cqxhl/p/12993302.html