AES.js加密解密與C#的相互轉換

AES簡介

AES, Advanced Encryption Standard,實際上是一套標準:FIPS 197,而咱們所說的AES算法實際上是Rijndael算法。javascript

NIST (National INstitute of Standards and Technology) 在1997年9月12日公開徵集更高效更安全的替代DES加密算法,第一輪共有15種算法入選,其中5種算法入圍了決賽,分別是MARS,RC6,Rijndael,Serpent和Twofish。又通過3年的驗證、評測及公衆討論以後Rijndael算法最終入選。java

image.png

Rijndael算法

Rijndael算法是由比利時學者Joan Daemen和Vincent Rijmen所提出的,算法的名字就由兩位做者的名字組合而成。Rijndael的優點在於集安全性、性能、效率、可實現性及靈活性與一體。git

背景

因爲在HTTP中參數都是經過URL或者Body進行傳輸的,那麼就存在信息的暴露問題,這時候不少敏感的信息就須要進行加密,防止敏感信息泄露。github

具體實現

一、服務端加密/解密

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();
                      }
                  }
              }
          }
      }        
  }

二、 客戶端(JS)

  • 使用包算法

    npm install crypto-js
  • 定義Key/IVshell

    const key = CryptoJS.enc.Utf8.parse("1234567890000000");
    const iv = CryptoJS.enc.Utf8.parse("1234567890000000");
    注意:客戶端和服務端的KEY/IV必須保持一致
  • 加密方法npm

    //**************************************************************
    //*字符串/對象加密
    //*   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;
    }

三、展現效果

  • 採用簡單的註冊信息進行測試
    image.png
  • Js進行加密後的值
    image.png
  • 服務端解密的值與註冊的驗證碼一致
    image.png

參考資料安全

demo下載地址: https://download.csdn.net/dow...

————————————————
原文連接:https://blog.csdn.net/xhl_jam...性能

相關文章
相關標籤/搜索