DES加密
Python加密库PyCryptodome
PyCrytodome 取代了 PyCrypto 。
安装与导入
Windows安装之前需要先安装Microsoft Visual c++ 2015。
下载地址:https://www.microsoft.com/en-us/download/details.aspx?id=48145
在Linux上安装,可以使用以下 pip 命令:
pip install pycryptodome
import Crypto
在Windows 系统上安装则稍有不同:
pip install pycryptodomex
import Cryptodome
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位的密钥按位替代或交换的方法形成密文组。
加密原理
DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。
算法步骤
1)初始置换
其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长3 2位,其置换规则为将输入的第58位换到第一位,第50位换到第2位……依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0是右32位,例:设置换前的输入值为D1D2D3……D64,则经过初始置换后的结果为:L0=D58D50……D8;R0=D57D49……D7。
其置换规则见下表:
58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,
2)逆置换
经过16次迭代运算后,得到L16、R16,将此作为输入,进行逆置换,逆置换正好是初始置换的逆运算,由此即得到密文输出。
此算法是对称加密算法体系中的代表,在计算机网络系统中广泛使用.
DES加密和解密的过程
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
===========================
# @Time : 2020/9/3 18:02
# @File : des_.py
# @Author: adeng
# @Date : 2020/9/3
============================
"""
# DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准。
# ------------------加密过程--------------------
# 由于linux和windows导入有所区别。
import sys
if sys.platform == "win32":
from Cryptodome.Cipher import DES
from Cryptodome.Random import get_random_bytes
elif sys.platform == "linux":
from Crypto.Cipher import DES
from Crypto.Random import get_random_bytes
# 必须是8个字节,也就是64位
key = get_random_bytes(8) # 随机8个字节的bytes。一般key是固定的找开发大佬要
print(key)
# 创建一个DES实例
des = DES.new(key, DES.MODE_OFB)
iv = des.iv
# 定义一个函数,用来解决加密的文本长度对8取余,不等0的情况
# 方法1
def change_str_8(text):
text = text + (8-len(text)%8)*" "
return text
"""
方法2
def change_str_8(text):
'''
text不是8的倍数【加密文本text必须为8的倍数!】,那就补足为8的倍数
'''
while len(text)%8 != 0:
text += " "
return text
"""
name = "阿登哥哥啊" # 要加密的文本
text_name = change_str_8(name)
# 加密:encrypt()
encrypt_text = des.encrypt(text_name.encode('utf-8'))
print("DES加密后:\n",encrypt_text,sep="")
#-------DES解密过程----
# decrypt(加密文本) 返回是一个byte,需要decode()解码,然后去除右边的空格
des = DES.new(key,DES.MODE_OFB,iv=iv)
decrypt_text = des.decrypt(encrypt_text).decode().rstrip(" ")
print(decrypt_text)
#-----------------------------------------------------------------
import binascii
# 这是密钥
key = b'abcdefgh'
# 需要去生成一个DES对象
des = DES.new(key, DES.MODE_OFB)
iv = des.iv
# 需要加密的数据
# text = 'python spider!'
text = '阿登哥哥啊'
text = text + (8 - (len(text) % 8)) * ' '
# 加密的过程
encrypt_text = des.encrypt(text.encode())
# 加密过后二进制转化为16进制ascii--->decode()转化为字符串
encrypt_text = binascii.b2a_hex(encrypt_text).decode()
print(encrypt_text)
# 解密需要ASCII 先转化为二进制 然后再进行解密
des = DES.new(key, DES.MODE_OFB, iv=iv)
plaint = des.decrypt(binascii.a2b_hex(encrypt_text.encode("utf-8"))).decode().rstrip(" ")
print(plaint, type(plaint))
# -------------------DES 函数封装------------------------------
# -----------------------------------------
def des_encrypt(text, key=b"dyunrena"):
"""
DES 对称法加密text
text:需要加密的文本
key:8位,必须是byte,默认值可以做成 配置文件,以后修改直接修改配置文件
"""
import sys,binascii
if sys.platform == "win32":
from Cryptodome.Cipher import DES
from Cryptodome.Random import get_random_bytes
elif sys.platform == "linux":
from Crypto.Cipher import DES
from Crypto.Random import get_random_bytes
des = DES.new(key, DES.MODE_OFB,iv=iv)
name_text = text + (8 - len(text) % 8) * " "
encrypt_text = des.encrypt(name_text.encode("utf-8"))
return binascii.b2a_hex(encrypt_text).decode()
def des_decrypt(text, key=b"dyunrena"):
"""
DES 对称法加密text,类型str
text:需要加密的文本
key:8位,必须是byte.默认值可以做成 配置文件,以后修改直接修改配置文件
"""
import sys, binascii
if sys.platform == "win32":
from Cryptodome.Cipher import DES
from Cryptodome.Random import get_random_bytes
elif sys.platform == "linux":
from Crypto.Cipher import DES
from Crypto.Random import get_random_bytes
des = DES.new(key, DES.MODE_OFB,iv=iv)
# 解密
decrypt_text = des.decrypt(binascii.a2b_hex(text.encode("utf-8"))) # 返回是一个 b
return decrypt_text.decode()
print("加密:",des_encrypt('python spider!'))
print("解密:",des_decrypt(des_encrypt("他问她头发头发11112hell ")))
AES加密
AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同。
一般常用的是128位
DES加密和解密的过程
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
===========================
# @Time : 2020/9/4 0:16
# @File : aes_.py
# @Author: adeng
# @Date : 2020/9/4
============================
"""
import sys,binascii
if sys.platform == "win32":
from Cryptodome.Cipher import AES
from Cryptodome.Random import get_random_bytes
from Cryptodome import Random
elif sys.platform == "linux":
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
# 密钥key必须为 16(AES-128), 24(AES-192), 32(AES-256)
key = b'this is a 16 key'
# 创建一个AES实例
cipher = AES.new(key, AES.MODE_EAX,nonce=key)
data = "我是阿登啊"
# data = "hello"
# 加密的明文长度必须为16的倍数, 如果长度不为16的倍数, 则需要补足为16的倍数
# 加密
cipher_text, tag = cipher.encrypt_and_digest(data.encode("utf-8"))
cipher_text = binascii.b2a_hex(cipher_text).decode() # 转化成字符串
print(cipher_text)
# 重新创建一个AES实例
aes = AES.new(key, AES.MODE_EAX,nonce=key)
decrypt_text = aes.decrypt(binascii.a2b_hex(cipher_text.encode("utf-8")))
print(decrypt_text,type(decrypt_text))
decrypt_text = decrypt_text.decode()
print(decrypt_text)
#---------------------------------------------------------
# # 封装成函数
def aes_encrypt(data,key=b'this is a 16 key'):
cipher = AES.new(key, AES.MODE_EAX,nonce=key)
cipher_text, tag = cipher.encrypt_and_digest(data.encode("utf-8"))
return binascii.b2a_hex(cipher_text).decode("utf-8")
def aes_decrypt(data,key=b'this is a 16 key'):
data = binascii.a2b_hex(data.encode("utf-8"))
cipher = AES.new(key,AES.MODE_EAX,nonce=key)
decrypt_text = cipher.decrypt(data)
return decrypt_text.decode()
print(aes_encrypt("python1111111111"))
print(aes_decrypt(aes_encrypt("python122222")))
RSA加密
非对称加密
典型的非对称加密
典型的如RSA等,常见方法,使用openssl ,keytools等工具生成一对公私钥对,使用被公钥加密的数据可以使用私钥来解密,反之亦然(被私钥加密的数据也可以被公钥解密) 。
在实际使用中私钥一般保存在发布者手中,是私有的不对外公开的,只将公钥对外公布,就能实现只有私钥的持有者才能将数据解密的方法。 这种加密方式安全系数很高,因为它不用将解密的密钥进行传递,从而没有密钥在传递过程中被截获的风险,而破解密文几乎又是不可能的。
但是算法的效率低,所以常用于很重要数据的加密,常和对称配合使用,使用非对称加密的密钥去加密对称加密的密钥。
简介
RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。
该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用
而且,因为RSA加密算法的特性,RSA的公钥私钥都是10进制的,但公钥的值常常保存为16进制的格式,所以需要将其用int()方法转换为10进制格式。
RSA加密和解密的过程
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
===========================
# @Time : 2020/9/4 1:53
# @File : rsa_.py
# @Author: adeng
# @Date : 2020/9/4
============================
"""
import sys,binascii
if sys.platform == "win32":
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP,PKCS1_v1_5
elif sys.platform == "linux":
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP, PKCS1_v1_5
class MyRSA():
def create_rsa_key(self, password):
"""
创建RSA密钥
步骤说明:
1、从 Crypto.PublicKey 包中导入 RSA,创建一个密码
2、生成 1024/2048 位的 RSA 密钥
3、调用 RSA 密钥实例的 exportKey 方法,传入密码、使用的 PKCS 标准以及加密方案这三个参数。
4、将私钥写入磁盘的文件。
5、使用方法链调用 publickey 和 exportKey 方法生成公钥,写入磁盘上的文件。
"""
key = RSA.generate(1024)
encrypted_key = key.exportKey(passphrase=password.encode("utf-8"), pkcs=8,
protection="scryptAndAES128-CBC")
with open("my_private_rsa_key.bin", "wb") as f:
f.write(encrypted_key) # 私钥写入文件
with open("my_rsa_public.pem", "wb") as f:
f.write(key.publickey().exportKey()) # 公钥写入文件
def encrypt(self, plaintext):
"""
plaintext:需要加密的文本,公钥加密,私钥解密
"""
# 加载公钥
recipient_key = RSA.import_key(
open("my_rsa_public.pem").read()
)
cipher_rsa = PKCS1_v1_5.new(recipient_key) # 准备加密
en_data = cipher_rsa.encrypt(plaintext.encode("utf-8"))
return binascii.b2a_hex(en_data).decode() # 返回字符串
# print(len(en_data), en_data)
def decrypt(self, en_data, password):
"""
en_data:加密过后的数据
"""
# 读取私钥
private_key = RSA.import_key(
open("my_private_rsa_key.bin").read(),
passphrase=password
)
cipher_rsa = PKCS1_v1_5.new(private_key) # 准备解密
data = cipher_rsa.decrypt(binascii.a2b_hex(en_data.encode("utf-8")), None)
return data.decode()
# print(data)
mrsa = MyRSA()
mrsa.create_rsa_key('dyunren')
e = mrsa.encrypt('我叫阿登啊')
d = mrsa.decrypt(e, 'dyunren')
print(e)
print(d)
URLENCODE加密
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
===========================
# @Time : 2020/9/4 2:36
# @File : urlencode_.py
# @Author: adeng
# @Date : 2020/9/4
============================
"""
# urlencode在线解码:http://tool.chinaz.com/tools/urlencode.aspx
url = "www.baidu.com/?name=阿登,gender=男"
from urllib.parse import quote, unquote
# 加密
enc_url = f"www.baidu.com/?name={quote('阿登')},gender={quote('男')}"
print(enc_url)
# 解码
dec_url = unquote(enc_url)
print(dec_url)
#----------------------------------------
def url_decrypt(enc_url):
"""
enc_url:加密过的url,特征是一般是?后面有很多个%
"""
return unquote(enc_url)
网友评论