javascript和python中的摘要算法以及AES、DES、RSA算法的实现

一、摘要算法

1.1 简介

摘要算法(Hashing Algorithm),也称为哈希算法,是一种将任意长度的数据映射为固定长度的值的算法。这个固定长度的值被称为“哈希值”或“摘要”。摘要算法的主要特点是: 不可逆、高效、 唯一性 (不同的输入应生成不同的输出)和敏感性(即使输入的改变非常微小,输出也会完全不同)。
摘要算法广泛用于数据完整性验证、数字签名、密码存储等领域。下面是关于摘要算法的详细介绍,包括常见的算法及其应用。

1.2 摘要算法的特点

固定长度输出:不管输入数据的大小是多少,摘要算法总是生成固定长度的输出。对于MD5来说,输出是128位(16字节);对于SHA-256来说,输出是256位(32字节)。

  • 不可逆性:摘要算法是单向的,从哈希值无法反推出原始输入。这一点使它们适合用于密码学中的密码存储和数字签名。

  • 雪崩效应:输入的微小变化(如一个比特的变动)会导致输出的哈希值发生巨大变化。这一特性有助于确保输出的随机性和不可预测性。

  • 高效性:摘要算法通常是设计为高效的,它们能够快速地处理大数据并生成对应的哈希值。

  • 抗碰撞性:两份不同的数据产生相同的哈希值的情况应非常罕见。抗碰撞性使摘要算法在许多安全场景中变得重要。

1.3 MD5 算法

  • python版本:
from hashlib import md5
obj = md5()
obj.update("yuan".encode("utf-8"))
#obj.update("alex".encode('utf-8'))  # 可以添加多个被加密的内容
bs = obj.hexdigest()
print(bs)
  • 拓展(sha1,sha256):
from hashlib import sha1, sha256
sha = sha256(b'salt')
sha.update(b'alex')
print(sha.hexdigest())
  • javascript版本:
const CryptoJS = require('crypto-js');
// 原始数据
const data = '123456';
// 生成MD5摘要
const md5Digest = CryptoJS.MD5(data).toString();

console.log(md5Digest);

二、 DES/AES加密(可逆)

  • DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的算法。该加密算法是一种对称加密方式,其加密运算、解密运算需要使用的是同样的密钥(一组字符串)即可。

  • 注意:

    • 现在用AES这个标准来替代原先的DES。
    • AES和DES的区别:
      • 加密后密文长度的不同:
        • DES加密后密文长度是8的整数倍
        • AES加密后密文长度是16的整数倍
      • 应用场景的不同:
        • 企业级开发使用DES足够安全
        • 如果要求高使用AES
  • DES算法的入口参数有三个:

    • Key、Data、Mode,padding、iv。
      • Key为DES算法的工作密钥;
      • Data为要被加密或被解密的数据;
      • Mode为DES的工作模式。最常用的模式就是 CBC 模式和 ECB模式
        • ECB:是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。
        • CBC:是一种循环模式,前一个分组的密文和当前分组的明文异或后再加密,这样做的目的是增强破解难度。
      • padding为填充模式,如果加密后密文长度如果达不到指定整数倍(8个字节、16个字节),填充对应字符
      • iv:参数中的iv主要用于CBC模式,确保即使加密相同的明文,每次产生的密文也不相同,增强加密的安全性。iv通常是一个16字节的随机字符串。这个字符串在解密时也需要用到,因此需要妥善保存。
  • Python版本:

    • 环境安装:

      pip install pycryptodome
      
    • 加密代码:

      from Crypto.Cipher import AES
      from Crypto.Util.Padding import pad
      import base64
      
      key = '0123456789abcdef'.encode()  # 秘钥: 必须16字节
      iv = b'abcdabcdabcdabcd'  # 偏移量:16位/字节(字节类型)
      text = 'alex is a monkey!'  # 加密内容
      #设置加密内容的长度填充(位数为16的整数倍)
      text = pad(text.encode(), 16)
      #创建加密对象
      aes = AES.new(key, AES.MODE_CBC, iv)  # 创建一个aes对象
      
      en_text = aes.encrypt(text)  # 加密明文
      print("aes加密数据:::", en_text) #返回二进制类型数据
      
      #二进制密文转换成字符串格式
      en_text = base64.b64encode(en_text).decode()  # 将返回的字节型数据转进行base64编码
      print(en_text) 
      
    • 解密代码:

      from Crypto.Cipher import AES
      import base64
      from Crypto.Util.Padding import unpad
      
      key = '0123456789abcdef'.encode()
      iv = b'abcdabcdabcdabcd'
      aes = AES.new(key, AES.MODE_CBC, iv)
      #需要解密的文本
      text = 'X/A0fy9S7+kUI3HYQRKO46WTlid6T1DBhXutwmPdboY='.encode()  
      #将密文数据转换为二进制类型
      ecrypted_base64 = base64.b64decode(text)  
      
      source = aes.decrypt(ecrypted_base64)  # 解密
      #未填充数据
      print("aes解密数据:::", source.decode())
      #取消填充数据
      print("aes解密数据:::", unpad(source, 16).decode())
      
  • JS版本:

    • 加密:

      const CryptoJS = require("crypto-js")
      
      // 密钥(128位,16字节)
      var key = CryptoJS.enc.Utf8.parse('0123456789abcdef');
      
      // 初始化向量(IV)(128位,16字节)
      var iv = CryptoJS.enc.Utf8.parse('1234567890abcdef');
      
      // 待加密的数据
      var plaintext = 'Hello, bobo!';
      
      // 进行AES-128加密,使用CBC模式和PKCS7填充
      var encrypted = CryptoJS.AES.encrypt(plaintext, key, {
          iv: iv,
          mode: CryptoJS.mode.CBC,
          padding: CryptoJS.pad.Pkcs7
      });
      
      // 获取加密后的密文
      var ciphertext = encrypted.toString();
      
      console.log(ciphertext);
      
    • 解密:

      const CryptoJS = require("crypto-js")
      
      // 密钥(128位,16字节)
      var key = CryptoJS.enc.Utf8.parse('0123456789abcdef');
      
      // 初始化向量(IV)(128位,16字节)
      var iv = CryptoJS.enc.Utf8.parse('1234567890abcdef');
      
      // 密文数据
      var encrypText = 'GYc9oxlZB/PeyfFG3ppK6Q==';
      
      // 进行加密,使用CBC模式和PKCS7填充
      var decrypted = CryptoJS.AES.decrypt(encrypText, key, {
          iv: iv,
          mode: CryptoJS.mode.CBC,
          padding: CryptoJS.pad.Pkcs7
      });
      
      // 解密
      var plaintext = decrypted.toString(CryptoJS.enc.Utf8);
      
      console.log(plaintext);
      
  • 上述代码的关键字:

    • AES,DES
    • encrypt(用于加密的函数名),decrypt(用于解密的函数名)
    • xxxkey:秘钥一般是单独生成的,一定不会傻到明文的写在代码中!

三、RSA加密(可逆)

  • RSA加密:
    • RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。
  • 非对称加密算法:
    • 非对称加密算法需要两个密钥:
      • 公开密钥(publickey:简称公钥)
      • 私有密钥(privatekey:简称私钥)
      • 公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
  • 注意:
    • 使用时都是使用公匙加密使用私匙解密。公匙可以公开,私匙自己保留。
    • 算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。
  • 使用流程和场景介绍
    • 通过公匙加密,使用私匙解密。私匙是通过公匙计算生成的。假设ABC三方之间相互要进行加密通信。大家相互之间使用公匙进行信息加密,信息读取时使用各自对应的私匙进行信息解密
    • 用户输入的支付密码会通过RSA加密
  • 公钥私钥生成方式:
    • 公私匙可以在线生成
      • http://web.chacuo.net/netrsakeypair
  • 环境安装:npm install jsencrypt

JS代码示例:

window = global;

const JSEncrypt = require('jsencrypt');


var PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALyBJ6kZ/VFJYTV3vOC07jqWIqgyvHulv6us/8wzlSBqQ2+eOTX7s5zKfXY40yZWDoCaIGk+tP/sc0D6dQzjaxECAwEAAQ==-----END PUBLIC KEY-----';
        //私钥
var PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvIEnqRn9UUlhNXe84LTuOpYiqDK8e6W/q6z/zDOVIGpDb545NfuznMp9djjTJlYOgJogaT60/+xzQPp1DONrEQIDAQABAkEAu7DFsqQEDDnKJpiwYfUE9ySiIWNTNLJWZDN/Bu2dYIV4DO2A5aHZfMe48rga5BkoWq2LALlY3tqsOFTe3M6yoQIhAOSfSAU3H6jIOnlEiZabUrVGqiFLCb5Ut3Jz9NN+5p59AiEA0xQDMrxWBBJ9BYq6RRY4pXwa/MthX/8Hy+3GnvNw/yUCIG/3Ee578KVYakq5pih8KSVeVjO37C2qj60d3Ok3XPqBAiEAqGPvxTsAuBDz0kcBIPqASGzArumljkrLsoHHkakOfU0CIDuhxKQwHlXFDO79ppYAPcVO3bph672qGD84YUaHF+pQ-----END PRIVATE KEY-----';
//使用公钥加密
var encrypt = new JSEncrypt();//实例化加密对象
encrypt.setPublicKey(PUBLIC_KEY);//设置公钥
var encrypted = encrypt.encrypt('hello bobo!');//对指定数据进行加密
console.log(encrypted);//使用私钥解密

//使用私钥解密
var decrypt = new JSEncrypt();
decrypt.setPrivateKey(PRIVATE_KEY);//设置私钥
var uncrypted = decrypt.decrypt(encrypted);//解密
console.log(uncrypted);

Python代码示例:

1.创建公钥和私钥

from Crypto.PublicKey import RSA

# 通过相关算法生成唯一秘钥
rsakey = RSA.generate(1024)
#将秘钥保存到文件中
with open("rsa.public.pem", mode="wb") as f:
    f.write(rsakey.publickey().exportKey())

with open("rsa.private.pem", mode="wb") as f:
    f.write(rsakey.exportKey())

2.加密算法实现

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64

# 加密
data = "我喜欢你"
with open("rsa.public.pem", mode="r") as f:
    pk = f.read()
    rsa_pk = RSA.importKey(pk)
    #基于公钥创建加密对象
    rsa = PKCS1_v1_5.new(rsa_pk)

    result = rsa.encrypt(data.encode("utf-8"))
    # 处理成b64方便传输
    b64_result = base64.b64encode(result).decode("utf-8")
    print(b64_result)

3.解密算法实现

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64

data = '17wJJtBBujJurHRu3teDC44jSllmqcB9a22U1DQ5/IsI0m3NuShPTxBq8pLTWRdszPapiXfjvOh47P9u5+7U4hvNZL+kKqs3H5m4BKKphORUUfqb9zTowoHb1mM9ji2LuMAYmc1l70ZR+s9XsV3HrHCV/S2FzGWngcWpNVtsTJg='
# 解密
with open("rsa.private.pem", mode="r") as f:
    prikey = f.read()
    rsa_pk = RSA.importKey(prikey)
    #创建解密对象
    rsa = PKCS1_v1_5.new(rsa_pk)
    result = rsa.decrypt(base64.b64decode(data), None)
    print("rsa解密数据:::", result.decode("utf-8"))

以上是在JavaScript和python中对常用摘要算法和常用请求加密算法的详细的介绍和代码的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值