美文网首页转载随笔-生活工作点滴
50-常见加密方式和Python实现

50-常见加密方式和Python实现

作者: ju7ran | 来源:发表于2019-07-08 13:55 被阅读11次

前言

我们所说的加密方式,都是对二进制编码的格式进行加密的,对应到Python中,则是我们的Bytes。

将字符串和Bytes互相转换可以使用encode()和decode()方法。

# 方法中不传参数则是以默认的utf-8编码进行转换
'居然'.encode()
b'\xe5\xb1\x85\xe7\x84\xb6'

b'\xe5\x8d\x97\xe5\x8c\x97'.decode()
'居然'

URL编码

正常的URL中是只能包含ASCII字符的,也就是字符、数字和一些符号。而URL编码就是一种浏览器用来避免url中出现特殊字符(如汉字)的编码方式。

from urllib import parse

# quote()方法会自动将str转换成bytes,所以这里传入str和bytes都可以
parse.quote('居然')
%E5%B1%85%E7%84%B6

parse.unquote('%E5%B1%85%E7%84%B6')
'居然'

Base64编码

Base64是一种用64个字符来表示任意二进制数据的方法。

Base64编码可以称为密码学的基石。可以将任意的二进制数据进行Base64编码。所有的数据都能被编码为并只用65个字符就能表示的文本文件。

Python内置的base64模块可以直接进行base64的编解码

注意:用于base64编码的,要么是ASCII包含的字符,要么是二进制数据

import base64

base64.b64encode(b'hello world')
b'aGVsbG8gd29ybGQ='

base64.b64decode(b'aGVsbG8gd29ybGQ=')
b'hello world'

MD5(信息-摘要算法)

message-digest algorithm 5(信息-摘要算法)。经常说的“MD5加密”,就是信息摘要算法。

md5,其实就是一种算法。可以将一个字符串,或文件,或压缩包,执行md5后,就可以生成一个固定长度为128bit的串。这个串,基本上是唯一的。

特点

  • 压缩性:任意长度的数据,算出的MD5值长度都是固定的。
  • 容易计算:从原数据计算出MD5值很容易。
  • 抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
  • 强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
  • 不可逆性

由于MD5模块在python3中被移除,在python3中使用hashlib模块进行md5操作

import hashlib

# 待加密信息
str = '这是待加密字符串'

# 创建md5对象
hl = hashlib.md5()

# 此处必须声明encode
# 若写法为hl.update(str)  报错为: Unicode-objects must be encoded before hashing
hl.update(str.encode(encoding='utf-8'))

print('MD5加密前为 :' + str)
print('MD5加密后为 :' + hl.hexdigest())

MD5加密前为 :这是待加密字符串
MD5加密后为 :daacaad2cedc3b68c6b7719c4e50b5a0

DES

DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准。

DES是一个分组加密算法,典型的DES以64位为分组对数据加密,加密和解密用的是同一个算法。

DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。

密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1),分组后的明文组和56位的密钥按位替代或交换的方法形成密文组。

安装
pip install pycryptodomex

# 导入DES模块
from Cryptodome.Cipher import DES
import binascii

# 这是密钥
key = b'abcdefgh'
# 需要去生成一个DES对象
des = DES.new(key, DES.MODE_ECB)
# 需要加密的数据
text = 'python spider!'
text = text + (8 - (len(text) % 8)) * '='

# 加密的过程
encrypto_text = des.encrypt(text.encode())
encrypto_text = binascii.b2a_hex(encrypto_text)
print(encrypto_text)

AES

高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

image.png

AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同。

from Cryptodome.Cipher import AES
from Cryptodome import Random
from binascii import b2a_hex  

# 要加密的明文
data = '居然'
# 密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.
# 目前AES-128足够用
key = b'this is a 16 key'
# 生成长度等于AES块大小的不可重复的密钥向量
iv = Random.new().read(AES.block_size)

# 使用key和iv初始化AES对象, 使用MODE_CFB模式
mycipher = AES.new(key, AES.MODE_CFB, iv)
# 加密的明文长度必须为16的倍数,如果长度不为16的倍数,则需要补足为16的倍数
# 将iv(密钥向量)加到加密的密文开头,一起传输
ciphertext = iv + mycipher.encrypt(data.encode())

# 解密的话要用key和iv生成新的AES对象
mydecrypt = AES.new(key, AES.MODE_CFB, ciphertext[:16])
# 使用新生成的AES对象,将加密的密文解密
decrypttext = mydecrypt.decrypt(ciphertext[16:])


print('密钥k为:', key)
print('iv为:', b2a_hex(ciphertext)[:16])
print('加密后数据为:', b2a_hex(ciphertext)[16:])
print('解密后数据为:', decrypttext.decode())

RSA

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。

因为RSA加密算法的特性,RSA的公钥私钥都是10进制的,但公钥的值常常保存为16进制的格式,所以需要将其用int()方法转换为10进制格式。

pip install rsa


import rsa
import binascii

# 使用网页中获得的n和e值,将明文加密
def rsa_encrypt(rsa_n, rsa_e, message):
    # 用n值和e值生成公钥
    key = rsa.PublicKey(rsa_n, rsa_e)
    # 用公钥把明文加密
    message = rsa.encrypt(message.encode(), key)
    # 转化成常用的可读性高的十六进制
    message = binascii.b2a_hex(message)
    # 将加密结果转化回字符串并返回
    return message.decode()

# RSA的公钥有两个值n和e,我们在网站中获得的公钥一般就是这样的两个值。
# n常常为长度为256的十六进制字符串
# e常常为十六进制‘10001’
pubkey_n = '8d7e6949d411ce14d7d233d7160f5b2cc753930caba4d5ad24f923a505253b9c39b09a059732250e56c594d735077cfcb0c3508e9f544f101bdf7e97fe1b0d97f273468264b8b24caaa2a90cd9708a417c51cf8ba35444d37c514a0490441a773ccb121034f29748763c6c4f76eb0303559c57071fd89234d140c8bb965f9725'
pubkey_e = '10001'
# 需要将十六进制转换成十进制
rsa_n = int(pubkey_n, 16)
rsa_e = int(pubkey_e, 16)

# 要加密的明文
message = '居然'

print("公钥n值长度:", len(pubkey_n))
print(rsa_encrypt(rsa_n, rsa_e, message))

网站:http://tool.chacuo.net/cryptdes

相关文章

网友评论

    本文标题:50-常见加密方式和Python实现

    本文链接:https://www.haomeiwen.com/subject/mwyohctx.html