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中调用ggplot的三种方法
Apr 08 Python
列举Python中吸引人的一些特性
Apr 09 Python
python冒泡排序简单实现方法
Jul 09 Python
详解python开发环境搭建
Dec 16 Python
用python实现简单EXCEL数据统计的实例
Jan 24 Python
python如何读写json数据
Mar 21 Python
python制作填词游戏步骤详解
May 05 Python
Python中的上下文管理器相关知识详解
Sep 19 Python
Python搭建HTTP服务过程图解
Dec 14 Python
Python实现在Windows平台修改文件属性
Mar 05 Python
Python常用扩展插件使用教程解析
Nov 02 Python
anaconda升级sklearn版本的实现方法
Feb 22 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边学边教》(01.开篇――准备工作)
2006/12/13 PHP
PHP持久连接mysql_pconnect()函数使用介绍
2012/02/05 PHP
php调用shell的方法
2014/11/05 PHP
PHP中模糊查询并关联三个select框
2017/06/19 PHP
解密效果
2006/06/23 Javascript
JavaScript Undefined,Null类型和NaN值区别
2008/10/22 Javascript
javascript脚本调试方法小结
2008/11/24 Javascript
Prototype RegExp对象 学习
2009/07/19 Javascript
基于jQuery的input输入框下拉提示层(自动邮箱后缀名)
2012/06/14 Javascript
图片放大镜jquery.jqzoom.js使用实例附放大镜图标
2014/06/19 Javascript
详解javascript中原始数据类型Null和Undefined
2015/12/17 Javascript
jQuery实现模仿微博下拉滚动条加载数据效果
2015/12/25 Javascript
Bootstrap作品展示站点实战项目2
2016/10/14 Javascript
Asp.Net之JS生成分页条的方法
2016/11/23 Javascript
Javascript 数组去重的方法(四种)详解及实例代码
2016/11/24 Javascript
vue-cli webpack2项目打包优化分享
2018/02/07 Javascript
一步步教会你微信小程序的登录鉴权
2018/04/09 Javascript
JS实现百度网盘任意文件强制下载功能
2018/08/31 Javascript
深入理解 Koa 框架中间件原理
2018/10/18 Javascript
举例讲解Linux系统下Python调用系统Shell的方法
2015/11/07 Python
python基于event实现线程间通信控制
2020/01/13 Python
Python3.7黑帽编程之病毒篇(基础篇)
2020/02/04 Python
使用Python实现批量ping操作方法
2020/05/06 Python
Python如何对XML 解析
2020/06/28 Python
简历自我评价怎么写呢?
2014/01/06 职场文书
单位实习证明怎么写
2014/01/17 职场文书
财务支持类个人的自我评价
2014/02/14 职场文书
婚前保证书
2014/04/29 职场文书
大学学习计划书范文
2014/05/02 职场文书
中国梦团日活动总结
2014/07/07 职场文书
雷锋式好少年事迹材料
2014/08/17 职场文书
新闻发布会活动策划方案
2014/09/15 职场文书
工作保证书
2015/01/17 职场文书
办公室规章制度范本
2015/08/04 职场文书
小学英语听课心得体会
2016/01/14 职场文书
Mysql 性能监控及调优
2021/04/06 MySQL