【算法】常见的加密算法

10/1/2022 algorithm

# 概述

# 线性散列算法

  • MD5 加密

    • 加密之后产生一个固定长度的数据,16 位或 32 位字母序列
    • 可以被反向暴力破解,即用很多不同的数据进行加密后跟已有的加密数据进行对比,但 MD5 不存在解密方法
    • 注册账号时的密码一般都是用的 MD5 加密
    • 增加破解难度的方法(常用)
      • 使用一段无意义且随机的私匙进行 MD5 加密会生成一个加密串,记作串 A
      • 将要加密的的数据跟串 A 拼接,再进行一次 MD5 加密,这时会生成串 B
      • 将串 B 再次进行 MD5 加密,这时生成的串 C 就是加密后的数据
    • JS 使用 MD5 加密
      • 引入第三方库:<script src="https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.js"></script>
      • 编写 js 脚本:var hash = md5("1111");

# 对称加密算法

  • DES/AES 加密

    • Data Encryption Standard,数据加密标准。一种对称加密方式,加密、解密运算使用的是同样的密钥

    • DES 算法的入口参数有三个:Key、Data、Mode

      • Key:为 7 个字节共 56 位,是 DES 算法的工作密钥
      • Data:为 8 个字节 64 位,是要被加密或被解密的数据
      • Mode:DES 的工作方式,包括加密和解密
    • 暴力破解:DES 使用 56 位的密钥,则可能的密钥数量是 2 的 56 次方个

    • JS 使用 DES 加密

      • 引入第三方库:<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/crypto-js.js"></script>

      • 编写 js 脚本

        var aseKey = '12345678'; // 秘钥必须为 8/16/32 位
        var message = '我是一个密码';
        var encrypt = CryptoJS.AES.encrypt(
          message,
          CryptoJS.enc.Utf8.parse(aseKey),
          {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7,
          }
        ).toString(); // 加密 DES/AES 切换只需要修改 CryptoJS.AES <=> CryptoJS.DES
        
        console.log(encrypt);
        
        var decrypt = CryptoJS.AES.decrypt(
          encrypt,
          CryptoJS.enc.Utf8.parse(aseKey),
          {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7,
          }
        ).toString(CryptoJS.enc.Utf8);
        
        console.log(decrypt);
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23

# 非对称加密算法

  • RSA 加密

    • 非对称加密:通过公匙对数据进行加密,使用私匙进行解密

    • 算法强度复杂,安全性依赖于算法与密钥,加解密速度没有对称加密加解密的速度快

    • 用户输入的支付密码会通过 RSA 加密

    • JS 使用 RSA 加密

      • 引入第三方库:https://cdn.bootcss.com/jsencrypt/3.0.0-beta.1/jsencrypt.js

      • 编写 js 脚本

        var PUBLIC_KEY = 'xxx';
        var PRIVATE_KEY = 'yyyyyyy';
        var encrypt = new JSEncrypt();
        encrypt.setPublicKey(
          '-----BEGIN PUBLIC KEY-----' + PUBLIC_KEY + '-----END PUBLIC KEY-----'
        );
        var encrypted = encrypt.encrypt('ceshi01');
        console.log('加密后数据:', encrypted);
        var decrypt = new JSEncrypt();
        decrypt.setPrivateKey(
          '-----BEGIN RSA PRIVATE KEY-----' +
            PRIVATE_KEY +
            '-----END RSA PRIVATE KEY-----'
        );
        var uncrypted = decrypt.decrypt(encrypted);
        console.log('解密后数据:', uncrypted);
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16

# Base64 伪加密

  • Base64 是一种用 64 个字符来表示任意二进制数据的方法,它是一种编码方式而不是加密算法

  • 基本原理:

    • 使用 A-Z、a-z、0-9、+、/ 这 64 个字符
    • 将 3 个字节转换成 4 个字节,先读入 3 个字节,每读 1 个字节,左移 8 位,再右移 4 次,每次 6 位,这样就有 4 个字节了
  • 代码实现

    var Base64 = {
      _keyStr:
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
      encode: function (e) {
        var t = '';
        var n, r, i, s, o, u, a;
        var f = 0;
        // e = Base64._utf8_encode(e);
        while (f < e.length) {
          n = e.charCodeAt(f++);
          r = e.charCodeAt(f++);
          i = e.charCodeAt(f++);
          s = n >> 2;
          o = ((n & 3) << 4) | (r >> 4);
          u = ((r & 15) << 2) | (i >> 6);
          a = i & 63;
          if (isNaN(r)) {
            u = a = 64;
          } else if (isNaN(i)) {
            a = 64;
          }
          t =
            t +
            this._keyStr.charAt(s) +
            this._keyStr.charAt(o) +
            this._keyStr.charAt(u) +
            this._keyStr.charAt(a);
        }
        return t;
      },
      decode: function (e) {
        var t = '';
        var n, r, i;
        var s, o, u, a;
        var f = 0;
        e = e.replace(/[^A-Za-z0-9+/=]/g, '');
        while (f < e.length) {
          s = this._keyStr.indexOf(e.charAt(f++));
          o = this._keyStr.indexOf(e.charAt(f++));
          u = this._keyStr.indexOf(e.charAt(f++));
          a = this._keyStr.indexOf(e.charAt(f++));
          n = (s << 2) | (o >> 4);
          r = ((o & 15) << 4) | (u >> 2);
          i = ((u & 3) << 6) | a;
          t = t + String.fromCharCode(n);
          if (u != 64) {
            t = t + String.fromCharCode(r);
          }
          if (a != 64) {
            t = t + String.fromCharCode(i);
          }
        }
        // t = Base64._utf8_decode(t);
        return t;
      },
    };
    // 定义字符串
    var string = 'Hello World!';
    // 加密
    var encodedString = Base64.encode(string);
    console.log(encodedString); // 输出: "SGVsbG8gV29ybGQh"
    // 解密
    var decodedString = Base64.decode(encodedString);
    console.log(decodedString); // 输出: "Hello World!"
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64

# 参考

Last Updated: 10/8/2022, 2:37:24 PM