摘要&加密算法

摘要&加密算法

摘要算法:一切从MD5开始

MD5是一个非常常见的摘要(hash)逻辑. 其特点就是小巧. 速度快. 极难被破解. 所以, md5依然是国内非常多的互联网公司选择的密码摘要算法.

  1. 这玩意不可逆. 所以. 摘要算法就不是一个加密逻辑.

  2. 相同的内容计算出来的摘要是一样的

  3. 不同的内容(哪怕是一丢丢丢丢丢不一样) 计算出来的结果差别非常大

在数学上. 摘要其实计算逻辑就是hash.

hash(数据) => 数字

1. 密码
2. 一致性检测  

md5的python实现:

from hashlib import md5

obj = md5()
obj.update("you".encode("utf-8"))
# obj.update("are".encode('utf-8'))  # 可以添加多个被加密的内容

bs = obj.hexdigest()
print(bs)

在这里插入图片描述

我们把密文丢到网页里. 发现有些网站可以直接解密. 但其实不然. 这里并不是直接解密MD5. 而是"撞库".

就是它网站里存储了大量的MD5的值. 就像这样:

而需要进行查询的时候. 只需要一条select语句就可以查询到了. 这就是传说中的撞库.

如何避免撞库: md5在进行计算的时候可以加盐. 加盐之后. 就很难撞库了.


from hashlib import md5

salt = "盐"
obj = md5(salt.encode("utf-8"))
obj.update("you".encode("utf-8"))
# obj.update("are".encode('utf-8'))  # 可以添加多个被加密的内容

bs = obj.hexdigest()
print(bs)

在这里插入图片描述

扩展

不论是sha1, sha256, md5都属于摘要算法. 都是在计算hash值. 只是散列的程度不同而已. 这种算法有一个特性. 他们是散列. 不是加密. 而且, 由于hash算法是不可逆的, 所以不存在解密的逻辑.

from hashlib import sha1, sha256
sha = sha256(b'salt')
sha.update(b'alex')
print(sha.hexdigest())

对称加密(AES与DES)

加密相关理论可以参考 加密与CA证书

AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个。

常见的对称加密: AES, DES, 3DES. 我们这里讨论AES。

安装:

pip install pycryptodome

AES 加密最常用的模式就是 CBC 模式和 ECB模式 ,当然还有很多其它模式,他们都属于AES加密。ECB模式和CBC 模式俩者区别就是 ECB 不需要 iv偏移量,而CBC需要。

"""
长度
    16: *AES-128*   
    24: *AES-192*
    32: *AES-256*
    
MODE 加密模式. 
    常见的ECB, CBC
    ECB:是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。
    CBC:是一种循环模式,前一个分组的密文和当前分组的明文异或或操作后再加密,这样做的目的是增强破解难度。
"""

CBC加密案例(选择aes-128):

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64

key = '0123456789abcdef'.encode()  # 秘钥: 因为aes-128模式,所以必须16字节
iv = b'abcdabcdabcdabcd'  # 偏移量:因为aes-128模式,所以必须16字节
text = 'alex is a monkey!'  # 加密内容,因为aes-128模式,所以字节长度必须是16的倍数
# while len(text.encode('utf-8')) % 16 != 0:  # 如果text不足16位的倍数就用空格补足为16位
#     text += '\0'
text = pad(text.encode(), 16)  # pad 用来补全长度
print("完整text:", text)

aes = AES.new(key, AES.MODE_CBC, iv)  # 创建一个aes对象

en_text = aes.encrypt(text)  # 加密明文
print("aes加密数据:::", en_text)  # b"_\xf04\x7f/R\xef\xe9\x14#q\xd8A\x12\x8e\xe3\xa5\x93\x96'zOP\xc1\x85{\xad\xc2c\xddn\x86"

en_text = base64.b64encode(en_text).decode()  # 将返回的字节型数据转进行base64编码
print(en_text)  # X/A0fy9S7+kUI3HYQRKO46WTlid6T1DBhXutwmPdboY=

CBC解密案例:

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)  # base64解码成字节流
source = aes.decrypt(ecrypted_base64)  # 解密
print("aes解密数据:::", source.decode())
print("aes解密数据:::", unpad(source, 16).decode())
  1. 在Python中进行AES加密解密时,所传入的密文、明文、秘钥、iv偏移量、都需要是bytes(字节型)数据。python 在构建aes对象时也只能接受bytes类型数据。

  2. 当秘钥,iv偏移量,待加密的明文,字节长度不够16字节或者16字节倍数的时候需要进行补全。

  3. CBC模式需要重新生成AES对象,为了防止这类错误,无论是什么模式都重新生成AES对象就可以了。

非对称加密

非对称加密. 加密和解密的秘钥不是同一个秘钥. 这里需要两把钥匙. 一个公钥, 一个私钥. 公钥发送给客户端. 发送端用公钥对数据进行加密. 再发送给接收端, 接收端使用私钥来对数据解密. 由于私钥只存放在接受端这边. 所以即使数据被截获了. 也是无法进行解密的.

常见的非对称加密算法: RSA, DSA等等, 我们就介绍一个. RSA加密, 也是最常见的一种加密方案

  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())
  1. 加密

    data = "加密数据!"
    
    with open("rsa.public.pem", mode="r") as f:
        pk = f.read()
    # 构建钥匙对象
    rsa_pk = RSA.importKey(pk)
    # 构建rsa算法对象
    rsa = PKCS1_v1_5.new(rsa_pk)
    # 数据加密
    result = rsa.encrypt(data.encode("utf-8"))
    # base64处理
    base_result = base64.b64encode(result).decode("utf-8")
    print(base_result)
    
  2. 解密

    data = "EVt+YXoDafYx+gvx+rbCrkZs0L0n1TG4Ime3CXitMWItxA0fM0IxY08vxvO7Lgfeb4YBidPkwntGC0KoBelx4M7SmbW+DiCvvIp/7rsfGC6lYfxXjdJ4t89I+VBwIPvex/+l+iR7AyL6FRyuv+kiSzRPUvR7kxeUE+4b6UEP3Gs="
    
    # base64 解码
    encrypt_data = base64.b64decode(data)
    
    # 构建钥匙对象
    with open("rsa.private.pem", "r") as f:
        pk = f.read()
    
    rsa_pk = RSA.importKey(pk)
    
    # 构建rsa算法对象
    rsa = PKCS1_v1_5.new(rsa_pk)
    
    # 数据解密
    data = rsa.decrypt(encrypt_data, None)
    
    print(data.decode("utf-8"))
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

go&Python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值