盒子
盒子
文章目录
  1. 基础
    1. base64
  2. AES
    1. CBC
    2. CFB
    3. DES

加解密

基础

base64

# python2
print '我们'.encode('base64')
print 'ztLDxw=='.decode('base64')
# python2
import base64

s = '我是字符串'
a = base64.b64encode(s)
print base64.b64decode(a)
# -*- coding: gbk -*-
# pyton3
class P3:
@staticmethod
def b2s(b):
return b.decode('gbk')

@staticmethod
def s2b(s, s16=False):
"""
:param s:
:param s16: 是否是16进制字符串, 比如:616263646566
:return:
"""
if s16:
return bytes.fromhex(s)
return s.encode('gbk')

def encode(self, s, s16=False):
# 注意bytes和str之间的转化
s = self.s2b(s, s16)
return base64.b64encode(s)

@staticmethod
def decode(s, out_hex=False):
# python3: b64decode -> bytes -> hex()
re = base64.b64decode(s)
if out_hex:
return re.hex()
return re

AES

pip install crypto
# 如果提示找不到Crypto.Cipher,近Python第三方安装包目录,把crypto 改为 Crypto 即可
# 如果还提示找不到,更换模块:pycrypto -> pycryptodome
pip uninstall pycrypto
pip install pycryptodome

CBC

# coding=utf8
"""
AES/CBC/PKCS7Padding
"""

from Crypto.Cipher import AES
import copy
import base64
import estools


class ESCBC:
def __init__(self):
self.cfg = estools.get_cfg()
self.mode = AES.MODE_CBC

self.key = self.cfg['cbc']['key'] # type: str
self.vi = self.cfg['cbc']['vi'] # type: str
self.key = self.key.decode("hex")
self.vi = self.vi.decode("hex")

@staticmethod
def pkcs7padding(data):
# AES.block_size 16位
bs = AES.block_size
padding = bs - len(data) % bs
padding_text = chr(padding) * padding
return data + padding_text

@staticmethod
def pkcs7unpadding(data):
lengt = len(data)
unpadding = ord(data[lengt - 1])
return data[0:lengt - unpadding]

def encrypt(self, s):
s = copy.deepcopy(s)
cipher = AES.new(self.key, self.mode, self.vi)
return cipher.encrypt(self.pkcs7padding(s))

def decrypt(self, s):
s = copy.deepcopy(s)
cipher = AES.new(self.key, self.mode, self.vi)
decrypted = cipher.decrypt(s)
return self.pkcs7unpadding(decrypted)

@staticmethod
def b64encode(s):
return base64.b64encode(s)

@staticmethod
def b64decode(s):
return base64.b64decode(s)


def test():
cbc = ESCBC()
text = 'abcdeft'
encrypted = cbc.encrypt(text)
print base64.b64encode(encrypted)
print cbc.decrypt(encrypted)

if __name__ == '__main__':
test()

CFB

# coding=utf8
"""
AES/CFB/NOPADDING加解密
等价于PHP: AES-128-CFB+OPENSSL_ZERO_PADDING
"""

from Crypto.Cipher import AES
import copy
import base64


class ESCFB:
def __init__(self):
self.mode = AES.MODE_CFB

self.key = 'ba0d1eba1b5aa3dc6f465f0d03d1a1f3' # type: str
self.vi = '15b32d0a12b89b7857c75556ff8176aa' # type: str
self.key = self.key.decode("hex")
self.vi = self.vi.decode("hex")

@staticmethod
def zero_padding(data):
bs = AES.block_size
num = bs - len(data) % bs
padding_text = '\0' * num
return data + padding_text, num

def encrypt(self, s):
s = copy.deepcopy(s)
cipher = AES.new(self.key, self.mode, self.vi, segment_size=128)
s, n = self.zero_padding(s)
s = cipher.encrypt(s)
if n == 0:
return s
return s[0:-n]

def decrypt(self, s):
s = copy.deepcopy(s)
cipher = AES.new(self.key, self.mode, self.vi, segment_size=128)
s, n = self.zero_padding(s)
s = cipher.decrypt(s)
if n == 0:
return s
return s[0:-n]

@staticmethod
def b64encode(s):
return base64.b64encode(s)

@staticmethod
def b64decode(s):
return base64.b64decode(s)


def test():
cbc = ESCFB()
text = '1ffedd4c51506214a1a196f4128c4267b3c9911wD'
encrypted = cbc.encrypt(text)
print base64.b64encode(encrypted)
print cbc.decrypt(encrypted)

if __name__ == '__main__':
test()

DES

"""
简单应用
"""
from Crypto.Cipher import DES

mode = DES.MODE_CBC
key = '01234567'
vi = '01234567'
text = '12345678123456789'

def encrypt(text):
cipher = DES.new(key, mode, vi)
return cipher.encrypt(text + '\0' * (8 - len(text) % 8))

encrypted = encrypt(text)
print encrypted.encode('hex')
# MODE_CBC must reset vi
cipher = DES.new(key, mode, vi)
decrypted = cipher.decrypt(encrypted)
print decrypted.rstrip('\0')
# coding=gbk
"""
文件加解密封装
"""
from Crypto.Cipher import DES


class EsCBC:
mode = DES.MODE_CBC
key = '01234567'
vi = '01234567'

def __init__(self):
self.cipher = None
pass

@staticmethod
def inttobytes(i):
def itoc(v):
return chr(v)

b = bytearray()
b.append(itoc(i & 0xFF))
b.append(itoc((i >> 8) & 0xFF))
b.append(itoc((i >> 16) & 0xFF))
b.append(itoc((i >> 24) & 0xFF))
return b

@staticmethod
def bytestoint(b):
return ord(b[0]) + (ord(b[1]) << 8) + (ord(b[2]) << 16) + (ord(b[3]) << 24)

# 加密
def encrypt(self, fn, new_fn):
self.cipher = DES.new(EsCBC.key, EsCBC.mode, EsCBC.vi)
with open(fn, 'rb') as f:
data = f.read()
data = bytearray(data)
data.extend(inttobytes(len(data))) # 追加长度
data.extend(bytearray(['A', 'B', 'C', 'D'])) # 追加尾部标示
if len(data) % 8:
data.extend(bytearray(8 - len(data) % 8)) # 长度补全
new_data = self.cipher.encrypt(str(data))
with open(new_fn, 'wb') as new_f:
new_f.write(new_data)

# 解密
def decrypt(self, fn, new_fn):
self.cipher = DES.new(EsCBC.key, EsCBC.mode, EsCBC.vi)
with open(fn, 'rb') as f:
data = f.read()
new_data = self.cipher.decrypt(data)
new_data = bytearray(new_data)
new_data = new_data.rstrip(b'\x00')
if (chr(new_data[-4]), chr(new_data[-3]), chr(new_data[-2]), chr(new_data[-1])) != ('A', 'B', 'C', 'D'):
raise SyntaxError, 'zip error'
return
new_data = str(new_data[:-4])
new_datalen = EsCBC.bytestoint(new_data[-4:])
new_data = str(new_data[:-4])
# print new_datalen
# print new_data.encode('hex')
with open(new_fn, 'wb') as new_f:
new_f.write(new_data)

if __name__ == '__main__':
cbc = EsCBC()
cbc.encrypt('1.txt', '2.txt')
cbc.decrypt('2.txt', '3.txt')
支持一下
扫一扫,支持一下
  • 微信扫一扫
  • 支付宝扫一扫