登录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