想写这篇博文很久了,最初起源是SSL,再到今年看到别人成功利用网关设备破解了https,到最近的TOTP的一个实战,对加解密有一些感触,记录下来
- python密码学库
pip install pycryptodome
# hashlib
这个看到许多人使用pip install pycrypto
安装报错,因此就直接安装上面的库
1)MD5
import hashlib
md5 = hashlib.md5()
md5.update(b"hello")
md5.hexdigest()
- sha1
hashlib.sha1(b"hello").hexdigest()
2)DES加密(分组加密)
补充(分组加密的5钟模式):
- 电码本模式(Electronic Codebook Book (ECB))
明文分片再逐一加密- 密码分组链接模式(Cipher Block Chaining (CBC))
将明文块与iv或上一段的密文块异或后加密
计算器模式(Counter (CTR))
计数器加密后与明文异或
- 密码反馈模式(Cipher FeedBack (CFB))
将加密得到的密文n位替换偏移得iv密钥,加密下一组明文
- 输出反馈模式(Output FeedBack (OFB))
将加密得到的密钥的n位替换偏移得iv密钥,加密下一组明文
from Crypto.Cipher import DES
key = "helllo"
# pad函数
def pad(text):
while len(text)%8!=0:
text+=' '
return text.encode()
a=DES.new(pad(key),DES.MODE_ECB) #这里可选CBC,ECB,CFB
text = pad("hello world")
a.encrypt(text)
# Out[151]: b'\xca\xbb\xef\xadd\xfb\xfd$V\x92%\x19O\xe3\xcf7'
a.encrypt(text).hex()
# Out[152]: 'cabbefad64fbfd24569225194fe3cf37'
a.decrypt(en).decode().strip()
# Out[163]: 'hello world'
这里简单介绍一下DES
DES(Data Encryption Standard)加密过程:
- 移位和循环移位
- 置换
- 扩展
- 压缩
- 亦或
这里的异或是算法为对称加密的关键,一个数对相同的数异或两次,数不变,这是可以解密的关键- 迭代
- AES(Advanced Encryption Standard)加密
取代DES
- 字节代替
- 行移位
- 列混淆
- 轮密钥加
from Crypto.Cipher import AES
import base64
def pad(text):
while len(text) % 16 != 0:
text += '\0'
return text
def encrypt(data,key,iv):
iv = pad(iv).encode('utf-8')
data = pad(data).encode('utf-8')
key=pad(key).encode('utf-8')
cipher = AES.new(key, AES.MODE_CBC, iv)
r = cipher.encrypt(data)
return str(base64.encodebytes(r), encoding='utf-8')
def decrypt(encrypted_data,key,iv):
key = pad(key).encode('utf-8')
iv=pad(iv).encode('utf-8')
encrypted_data = base64.decodebytes(encrypted_data.encode(encoding='utf-8'))
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = str(cipher.decrypt(encrypted_data), encoding='utf-8').replace('\0', '')
return decrypted
if __name__=="__main__":
en=encrypt("hello wolrd","mcc","str")
print("密文是 : "+en)
de=decrypt(en,"mcc","str")
print("名文是 : "+de)
3)RSA加密
# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@version:
author:MCC
@time: 2019/12/09
@file: rsa2_mcc.py
@function:
@modify:
"""
from Crypto.PublicKey import RSA
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES, PKCS1_OAEP
import os
import base64
def CreateRSAKeys():
code = 'passwd'
key = RSA.generate(2048)
encrypted_key = key.exportKey(passphrase=code, pkcs=8, protection="scryptAndAES128-CBC")
# 私钥
with open('test.key', 'wb') as f:
f.write(encrypted_key)
# 公钥
with open('test.pub', 'wb') as f:
f.write(key.publickey().exportKey())
def Encrypt(filename):
data = ''
with open(filename, 'rb') as f:
data = f.read()
with open(filename, 'wb') as out_file:
# 收件人秘钥 - 公钥
recipient_key = RSA.import_key(open('test.pub').read())
session_key = get_random_bytes(16)
# Encrypt the session key with the public RSA key
cipher_rsa = PKCS1_OAEP.new(recipient_key)
out_file.write(cipher_rsa.encrypt(session_key))
# Encrypt the data with the AES session key
cipher_aes = AES.new(session_key, AES.MODE_EAX)
ciphertext, tag = cipher_aes.encrypt_and_digest(data)
out_file.write(cipher_aes.nonce)
out_file.write(tag)
out_file.write(ciphertext)
def Descrypt(filename):
code = 'passwd'
with open(filename, 'rb') as fobj:
private_key = RSA.import_key(open('test.key').read(), passphrase=code)
enc_session_key, nonce, tag, ciphertext = [fobj.read(x)
for x in (private_key.size_in_bytes(),
16, 16, -1)]
cipher_rsa = PKCS1_OAEP.new(private_key)
session_key = cipher_rsa.decrypt(enc_session_key)
cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
data = cipher_aes.decrypt_and_verify(ciphertext, tag)
with open(filename, 'wb') as wobj:
wobj.write(data)
def RenameFile(dir, filename):
filename_bytes = filename.encode('utf-8')
filename_bytes_base64 = base64.encodestring(filename_bytes)
filename_bytes_base64 = filename_bytes_base64[::-1][1:]
new_filename = filename_bytes_base64.decode('utf-8') + '.crypt1'
print(os.path.join(dir, filename))
print(os.path.join(dir, new_filename))
os.rename(os.path.join(dir, filename), os.path.join(dir, new_filename))
def ReserveFilename(dir, filename):
f = filename
filename = filename[::-1][7:][::-1]
filename_base64 = filename[::-1] + '\n'
filename_bytes_base64 = filename_base64.encode('utf-8')
ori_filename = base64.decodestring(filename_bytes_base64).decode('utf-8')
print(os.path.join(dir, f))
print(os.path.join(dir, ori_filename))
os.rename(os.path.join(dir, f), os.path.join(dir, ori_filename))
def Main(rootDir):
list_dirs = os.walk(rootDir)
for root, dirs, files in list_dirs:
# 切换加密和解密过程
if False:
#if True:
# 遍历文件,加密并且改名
for f in files:
filename = os.path.join(root, f)
Encrypt(filename)
RenameFile(root, f)
else:
# 遍历文件,解密并且恢复名字
for f in files:
filename = os.path.join(root, f)
Descrypt(filename)
ReserveFilename(root, f)
if __name__ == '__main__':
# CreateRSAKeys()
d = 'D:\ss'
Main(d)