登錄AES和RSA混合加密解密流程


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>CryptoJS</title>
    <!-- CryptoJS針對密碼加密 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.0.0/crypto-js.js"></script>
    <!-- jsencrypt針對明文key加密 -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jsencrypt/3.0.0-rc.1/jsencrypt.js"></script>
  </head>
  <body>
    <!-- 
前后端各生成一對公鑰和私鑰

比如:
后端生成的一對公鑰和私鑰為pubKey1、priKey1
前端生成的一對公鑰和私鑰為pubKey2、priKey2

然后前后端相互交換公鑰
交換公鑰后的結果為
后端pubKey2、priKey1 前端pubKey1、priKey2
此時:
后端拿到了前端的pubKey2
前端拿到了后端的pubKey1

之后前端隨機生成16位的明文key。也就是AES(screet密鑰)
前端用16的明文key去加密密碼
前端再用pubKey1去加密16位的key得到密文的key
之后點登錄一起傳給后端
后端此時拿到了用戶名、經過key加密的秘密 和 密文key
此時后端需要用自己的priKey1去解密密文key得到明文key
再用明文key去解密 經過key加密的秘密 得到明文密碼
再然后用md5加密明文密碼存儲到數據庫
   -->
    <script>
      // ============================CryptoJS針對密碼加密解密============================
      // 步驟1
      //================加密(前端)================
      var screet = randomString(16); // 明文的16位key
      let key = CryptoJS.enc.Utf8.parse(screet); //密鑰必須是16位,且避免使用保留字符

      // 用明文key對密碼加密
      let encryptedData = CryptoJS.AES.encrypt("123456", key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7,
      });
      let hexData = encryptedData.ciphertext.toString();
      console.log(key, hexData); // 得到用明文key加密的密碼
      //================加密(前端)================

      // 步驟4
      //================解密(后端)================
      let encryptedHexStr = CryptoJS.enc.Hex.parse(hexData);
      let encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr);
      // 用明文key對加密過的密碼解密
      let decryptedData = CryptoJS.AES.decrypt(encryptedBase64Str, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7,
      });
      let text = decryptedData.toString(CryptoJS.enc.Utf8);
      console.log(text); // => 123456 得到明文密碼后再用md5加密存儲到數據庫
      //================解密(后端)================

      // ============================CryptoJS針對密碼加密解密============================

      // ============================jsencrypt針對明文16位key加密解密============================
      console.log(screet);
      var public_key = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDg7HJaKXdShCiJ64s4cSuYpmLf
SWiGWJIFMsBjlYRX3NL+0cnUE9pnwHqZ7+vhmAOpV0jBFncUVwQG64me/zJLL0yQ
yUH/KnW+NLLiwVutflZre45FVXzpWbvI9cIKK4Nul6REwW8wJcNwxNoXmdTDxmtP
/yZyR+dOlEsS35KD9QIDAQAB
-----END PUBLIC KEY-----
`;
      var private_key = `-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAODsclopd1KEKInr
izhxK5imYt9JaIZYkgUywGOVhFfc0v7RydQT2mfAepnv6+GYA6lXSMEWdxRXBAbr
iZ7/MksvTJDJQf8qdb40suLBW61+Vmt7jkVVfOlZu8j1wgorg26XpETBbzAlw3DE
2heZ1MPGa0//JnJH506USxLfkoP1AgMBAAECgYB7GIxg0c7O5ys0iCdyZWVhrrXv
08ITvId1ttfZ6Gs8lssW0IOvwInIPGwcsVSb61EdrXpQylWzWQgILYHs9Wd0/Z+Z
pFVbp+qJDRXb6CxRbwcSwcp7oZ53sZAWvRiTTiB0mL1UHP73JJ7VZ2Ck8n3cZaOf
RqCisKJ02IqCiAo2JQJBAPVC88my8GlUX1+uV0G+oCMxaJCCTHLeFfeflWUxJ1Os
LW5Ej/poSA1NiVoKuIACDTAJyq91JWVGDHgBD9LbAK8CQQDqxYi6clRQeJOPMxam
i/1AXHMidAxFGHQKYovYzVoa/B1NMLT3xK1MyRzPq1/2qk02lrPlVm5JaJj1mfcn
mwabAkBWVuZ5h9uoSMJ2bWpcQ54eJYOY87Wz7kivbmdqQx6EDyXDHrHMxi8vN691
mjaPIanA0oGeuM+cUkeLa1xFr0ETAkEAthrhEtZqBj1xIAudzzQZDhpoCFqBxfrQ
z9le5p1q/jF/PQfB58p8Lmp1WbRx7HBvEh/VjNf9Fh33P9LcvrDmbwJAHtcUYMLd
RyYk8h3ylIa/b+X/yaZ+pBBFOYrgYHg5yxsitP/u3pSBhx4h3+miP9KLkpg2K+Fr
jx4UdOTBzj9Tfw==
-----END PRIVATE KEY-----
`;
      // 步驟2
      //================加密(前端)================
      // 采用后端給的公鑰對16位明文key進行加密
      var encrypt = new JSEncrypt();
      encrypt.setPublicKey(public_key);
      var encrypted = encrypt.encrypt(screet); // 加密
      console.log(encrypted); // 得到密文的key
      //================加密(前端)================

      // 步驟3
      //================解密(后端)================
      // 采用后端自己的私鑰進行解密
      var decrypt = new JSEncrypt();
      decrypt.setPrivateKey(private_key);
      var uncrypted = decrypt.decrypt(encrypted); // 解密
      console.log(uncrypted); // => 得到明文的16位key 之后用明文的16位key解密前端用明文key加密過的密碼得到明文密碼
      //================解密(后端)================
      // ============================jsencrypt針對明文16位key加密解密============================

      // 生成隨機的16位的key(AES的密鑰screet)
      function randomString(len) {
        len = len || 32;
        var $chars =
          "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789";
        var maxPos = $chars.length;
        var pwd = "";
        for (i = 0; i < len; i++) {
          pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
        }
        return pwd;
      }
    </script>
  </body>
</html>

效果圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM