Python3对称加密算法AES、DES3实例详解


Posted in Python onDecember 06, 2018

本文实例讲述了Python3对称加密算法AES、DES3。分享给大家供大家参考,具体如下:

python3.6此库安装方式,需要pip3 install pycryptodome。

如有site-packages中存在crypto、pycrypto,在pip之前,需要pip3 uninstall cryptopip3 uninstall pycrypto,否则无法安装成功。

C:\WINDOWS\system32>pip3 install pycryptodome
Collecting pycryptodome
  Downloading https://files.pythonhosted.org/packages/0f/5d/a429a53eacae3e13143248c3868c76985bcd0d75858bd4c25b574e51bd4d/pycryptodome-3.6.3-cp36-cp36m-win_amd64.whl (7.9MB)
    100% |????????????????????????????????| 7.9MB 111kB/s
Installing collected packages: pycryptodome
Successfully installed pycryptodome-3.6.3

这里顺带说一下pycrypto,这个库已经有很久没有人维护了,如果需要安装此库,需要先安装 VC++ build tools

然后将 ~\BuildTools\VC\Tools\MSVC\14.15.26726\include 目录下的 stdint.h 拷贝到 C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt 下。(Win10 需管理员权限)

接着将同目录下的 inttypes.h 中的 #include <stdint.h> (第十四行),改成 #include "stdint.h"

然后使用 pip3 install pycrypto,就能直接安装了。

注:如果不是业务需要,请尽可能使用 pycryptodome。

AES:

import Crypto.Cipher.AES
import Crypto.Random
import base64
import binascii
def auto_fill(x):
  if len(x) <= 32:
    while len(x) not in [16, 24, 32]:
      x += " "
    return x.encode()
  else:
    raise "密钥长度不能大于32位!"
key = "asd"
content = "abcdefg1234567"
x = Crypto.Cipher.AES.new(auto_fill(key), Crypto.Cipher.AES.MODE_ECB)
a = base64.encodebytes(x.encrypt(auto_fill(content)))
b = x.decrypt(base64.decodebytes(a))
print(a)
print(b)
a = binascii.b2a_base64(x.encrypt(auto_fill(content)))
b = x.decrypt(binascii.a2b_base64(a))
print(a)
print(b)
key = "dsa"
iv = Crypto.Random.new().read(16)  # 向量,必须为16字节
content = "1234567abcdefg"
y = Crypto.Cipher.AES.new(auto_fill(key), Crypto.Cipher.AES.MODE_CBC, iv)
c = binascii.b2a_base64(y.encrypt(auto_fill(content)))
z = Crypto.Cipher.AES.new(auto_fill(key), Crypto.Cipher.AES.MODE_CBC, iv)
d = z.decrypt(binascii.a2b_base64(c))
print(c)
print(d)

运行结果:

b'jr/EIUp32kLHc3ypZZ1cyg==\n'
b'abcdefg1234567  '
b'jr/EIUp32kLHc3ypZZ1cyg==\n'
b'abcdefg1234567  '
b'j+Ul9KQd0HnuiHW3z9tD7A==\n'
b'1234567abcdefg  '

DES3:

import Crypto.Cipher.DES3
import base64
import binascii
def auto_fill(x):
  if len(x) > 24:
    raise "密钥长度不能大于等于24位!"
  else:
    while len(x) < 16:
      x += " "
    return x.encode()
key = "asd"
content = "abcdefg1234567"
x = Crypto.Cipher.DES3.new(auto_fill(key), Crypto.Cipher.DES3.MODE_ECB)
a = base64.encodebytes(x.encrypt(auto_fill(content)))
print(a)
b = x.decrypt(base64.decodebytes(a))
print(b)
a = binascii.b2a_base64(x.encrypt(auto_fill(content)))
b = x.decrypt(binascii.a2b_base64(a))
print(a)
print(b)

运行结果:

b'/ee3NFKeNqEk/qMNd1mjog==\n'
b'abcdefg1234567  '
b'/ee3NFKeNqEk/qMNd1mjog==\n'
b'abcdefg1234567  '

附:AES的工厂模式封装Cipher_AES.py(封装Crypto.Cipher.AES)

'''
Created on 2018年7月7日
@author: ray
'''
import Crypto.Cipher.AES
import Crypto.Random
import base64
import binascii
class Cipher_AES:
  pad_default = lambda x, y: x + (y - len(x) % y) * " ".encode("utf-8")
  unpad_default = lambda x: x.rstrip()
  pad_user_defined = lambda x, y, z: x + (y - len(x) % y) * z.encode("utf-8")
  unpad_user_defined = lambda x, z: x.rstrip(z)
  pad_pkcs5 = lambda x, y: x + (y - len(x) % y) * chr(y - len(x) % y).encode("utf-8")
  unpad_pkcs5 = lambda x: x[:-ord(x[-1])]
  def __init__(self, key="abcdefgh12345678", iv=Crypto.Random.new().read(Crypto.Cipher.AES.block_size)):
    self.__key = key
    self.__iv = iv
  def set_key(self, key):
    self.__key = key
  def get_key(self):
    return self.__key
  def set_iv(self, iv):
    self.__iv = iv
  def get_iv(self):
    return self.__iv
  def Cipher_MODE_ECB(self):
    self.__x = Crypto.Cipher.AES.new(self.__key.encode("utf-8"), Crypto.Cipher.AES.MODE_ECB)
  def Cipher_MODE_CBC(self):
    self.__x = Crypto.Cipher.AES.new(self.__key.encode("utf-8"), Crypto.Cipher.AES.MODE_CBC, self.__iv.encode("utf-8"))
  def encrypt(self, text, cipher_method, pad_method="", code_method=""):
    if cipher_method.upper() == "MODE_ECB":
      self.Cipher_MODE_ECB()
    elif cipher_method.upper() == "MODE_CBC":
      self.Cipher_MODE_CBC()
    cipher_text = b"".join([self.__x.encrypt(i) for i in self.text_verify(text.encode("utf-8"), pad_method)])
    if code_method.lower() == "base64":
      return base64.encodebytes(cipher_text).decode("utf-8").rstrip()
    elif code_method.lower() == "hex":
      return binascii.b2a_hex(cipher_text).decode("utf-8").rstrip()
    else:
      return cipher_text.decode("utf-8").rstrip()
  def decrypt(self, cipher_text, cipher_method, pad_method="", code_method=""):
    if cipher_method.upper() == "MODE_ECB":
      self.Cipher_MODE_ECB()
    elif cipher_method.upper() == "MODE_CBC":
      self.Cipher_MODE_CBC()
    if code_method.lower() == "base64":
      cipher_text = base64.decodebytes(cipher_text.encode("utf-8"))
    elif code_method.lower() == "hex":
      cipher_text = binascii.a2b_hex(cipher_text.encode("utf-8"))
    else:
      cipher_text = cipher_text.encode("utf-8")
    return self.unpad_method(self.__x.decrypt(cipher_text).decode("utf-8"), pad_method)
  def text_verify(self, text, method):
    while len(text) > len(self.__key):
      text_slice = text[:len(self.__key)]
      text = text[len(self.__key):]
      yield text_slice
    else:
      if len(text) == len(self.__key):
        yield text
      else:
        yield self.pad_method(text, method)
  def pad_method(self, text, method):
    if method == "":
      return Cipher_AES.pad_default(text, len(self.__key))
    elif method == "PKCS5Padding":
      return Cipher_AES.pad_pkcs5(text, len(self.__key))
    else:
      return Cipher_AES.pad_user_defined(text, len(self.__key), method)
  def unpad_method(self, text, method):
    if method == "":
      return Cipher_AES.unpad_default(text)
    elif method == "PKCS5Padding":
      return Cipher_AES.unpad_pkcs5(text)
    else:
      return Cipher_AES.unpad_user_defined(text, method)

使用方法:

        加密:Cipher_AES(key [, iv]).encrypt(text, cipher_method [, pad_method [, code_method]])

        解密:Cipher_AES(key [, iv]).decrypt(cipher_text, cipher_method [, pad_method [, code_method]])

key:密钥(长度必须为16、24、32)

iv:向量(长度与密钥一致,ECB模式不需要)

text:明文(需要加密的内容)

cipher_text:密文(需要解密的内容)

cipher_method:加密方法,目前只有"MODE_ECB"、"MODE_CBC"两种

pad_method:填充方式,解决 Java 问题选用"PKCS5Padding"

code_method:编码方式,目前只有"base64"、"hex"两种

来段调用封装类 Cipher_AES 的 demo_Cipher_AES.py,方便大家理解:

import Cipher_AES
key = "qwedsazxc123321a"
iv = key[::-1]
text = "我爱小姐姐,可小姐姐不爱我 - -"
cipher_method = "MODE_CBC"
pad_method = "PKCS5Padding"
code_method = "base64"
cipher_text = Cipher_AES(key, iv).encrypt(text, cipher_method, pad_method, code_method)
print(cipher_text)
text = Cipher_AES(key, iv).decrypt(cipher_text, cipher_method, pad_method, code_method)
print(text)
'''
运行结果:
uxhf+MoSko4xa+jGOyzJvYH9n5NvrCwEHbwm/A977CmGqzg+fYE0GeL5/M5v9O1o
我爱小姐姐,可小姐姐不爱我 - -
'''
Python 相关文章推荐
python使用scrapy解析js示例
Jan 23 Python
使用Python神器对付12306变态验证码
Jan 05 Python
Python字符编码与函数的基本使用方法
Sep 30 Python
python使用threading获取线程函数返回值的实现方法
Nov 15 Python
Python中使用支持向量机(SVM)算法
Dec 26 Python
python实现画圆功能
Jan 25 Python
python 实现将字典dict、列表list中的中文正常显示方法
Jul 06 Python
python中ASCII码和字符的转换方法
Jul 09 Python
python 3调用百度OCR API实现剪贴板文字识别
Sep 04 Python
python3+PyQt5 数据库编程--增删改实例
Jun 17 Python
解决django接口无法通过ip进行访问的问题
Mar 27 Python
python网络编程:socketserver的基本使用方法实例分析
Apr 09 Python
Python http接口自动化测试框架实现方法示例
Dec 06 #Python
python的常用模块之collections模块详解
Dec 06 #Python
Django管理员账号和密码忘记的完美解决方法
Dec 06 #Python
Python操作json的方法实例分析
Dec 06 #Python
Python多线程应用于自动化测试操作示例
Dec 06 #Python
Python实现多属性排序的方法
Dec 05 #Python
python通过ffmgep从视频中抽帧的方法
Dec 05 #Python
You might like
php file_put_contents()功能函数(集成了fopen、fwrite、fclose)
2011/05/24 PHP
php上传apk后自动提取apk包信息的使用(示例下载)
2013/04/26 PHP
用ASP将SQL搜索出来的内容导出为TXT的代码
2007/07/27 Javascript
javascript下IE与FF兼容函数收集
2008/09/17 Javascript
jQuery ajax在GBK编码下表单提交终极解决方案(非二次编码方法)
2010/10/20 Javascript
html a标签-超链接中confirm方法使用介绍
2013/01/04 Javascript
js动画效果制件让图片组成动画代码分享
2014/01/14 Javascript
a标签click和href执行顺序探讨
2014/06/23 Javascript
JS+CSS简单树形菜单实现方法
2015/09/12 Javascript
JavaScript html5 canvas绘制时钟效果
2016/03/01 Javascript
BootStrap智能表单实战系列(四)表单布局介绍
2016/06/13 Javascript
深入浅析Vue组件开发
2016/11/25 Javascript
vue-cli脚手架引入图片的几种方法总结
2018/03/13 Javascript
Makefile/cmake/node-gyp中区分判断不同平台的方法
2018/12/18 Javascript
js中let能否完全替代IIFE
2019/06/15 Javascript
LayUI数据接口返回实体封装的例子
2019/09/12 Javascript
js仿360开机效果
2019/12/26 Javascript
js实现消灭星星(web简易版)
2020/03/24 Javascript
VUE中V-IF条件判断改变元素的样式操作
2020/08/09 Javascript
[05:35]DOTA2英雄梦之声_第13期_拉比克
2014/06/21 DOTA
python实现划词翻译
2020/04/23 Python
Python实现更改图片尺寸大小的方法(基于Pillow包)
2016/09/19 Python
Python爬虫实现全国失信被执行人名单查询功能示例
2018/05/03 Python
详解Python 数据库的Connection、Cursor两大对象
2018/06/25 Python
numpy库与pandas库axis=0,axis= 1轴的用法详解
2019/05/27 Python
Python搭建Keras CNN模型破解网站验证码的实现
2020/04/07 Python
python将unicode和str互相转化的实现
2020/05/11 Python
HTML5中图片之间的缝隙完美解决方法
2017/07/07 HTML / CSS
ASOS亚洲:ASOS Asia
2018/03/04 全球购物
什么是WEB控件?使用WEB控件有哪些优势?
2012/01/21 面试题
外贸实习生自荐信范文
2013/11/24 职场文书
采购内勤岗位职责
2013/12/10 职场文书
赤壁观后感(2)
2015/06/15 职场文书
职位证明模板
2015/06/23 职场文书
卫生主题班会
2015/08/14 职场文书
2016年社区服务活动总结
2016/04/06 职场文书