windows中使用Python进行AES加密解密-加密解密功能实现

PyCrypto是一款非常实用的Python加密模块,最近写了一个文件加密脚本需要用到AES加密(http://blog.csdn.net/u013578500/article/details/77916990),和大家分析一下心得。

下载与安装:PyCrypto项目已经于2015年7月停止了,下面是官方的下载地址。 https://www.dlitz.net/software/pycrypto/
如果是linux系统,PyCrypto的安装非常简单,解压直接安装即可:
python setup.py build
python setup.py install

但是在windows下就非常麻烦了,网上常见的方法都是需要MinGW或者VisualStudio。不过你也可以在下面的连接中获取windows适用的pycrypto安装包。
http://www.voidspace.org.uk/python/modules.shtml#pycrypto
 
OK,接下来是正题。
首先介绍一下项目背景,我的电脑里有一个文件,名叫PW.txt,这个文件里保存的都是我在各类网站论坛的账号密码,虽然方便,但是!这种明文保存的方式让我很没有安全感。恰逢最近在学Python,于是就写了一个用AES方式对文件加密的小脚本。
这里先和大家大家分享一下使用PyCrypto实现对字符串的加密与解密。

1.预处理

AES有三种密钥长度16(*AES-128*), 24 (*AES-192*), 和 32 (*AES-256*),在对字符进行加密时,密码和明文长度必须为16,24,或32。
因此要对密码和明文进行预处理,确保密码长度为16,24或32,明文长度为16,24或32的整数倍,这里以16(*AES-128*)为例,代码如下:
# 补全字符
def align(str, isKey=False):
    # 如果接受的字符串是密码,需要确保其长度为16
    if isKey:
        if len(str) > 16:
            return str[0:16]
        else:
            return align(str)
    # 如果接受的字符串是明文或长度不足的密码,则确保其长度为16的整数倍
    else:
        zerocount = 16-len(str) % 16
        for i in range(0, zerocount):
            str = str + '\0'
        return str


2.加密

要调用PyCrypto的AES加密模块,首先导入AES的包,另外为了确保编码的统一,我选择将密文保存为16进制,因此还需要从binascii中导入b2a_hex和a2b_hex。
from Crypto.Cipher import AES
from binascii import b2a_hex
from binascii import a2b_hex
这里加密函数的流程是:预处理密码和明文->初始化AES->加密->转码->输出结果,代码如下:
# ECB模式加密
def encrypt_ECB(str, key):
    # 补全字符串
    str = align(str)
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_ECB)
    # 加密
    cipher = AESCipher.encrypt(str)
    return b2a_hex(cipher)

这里使用的是ECB的加密模式,关于加密模式,AES共有五种加密模式(ECB,CBC,PCBC,CFB,OFB,CTR),感兴趣的同学可以自行查阅相关资料。


3.解密

这里解密的流程是:预处理密码->初始化AES->转码->解密->输出结果,代码如下:
# ECB模式解密
def decrypt_ECB(str, key):
    # 补全字符串
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_ECB)
    # 解密
    paint = AESCipher.decrypt(a2b_hex(str))
    # 去除/0  
    paint = paint.rstrip('\0')  
    return paint

4.AES加密模式——CBC

上面的示例代码使用的是ECB模式进行加密解密,这种模式比较简单,并且安全性相对较差,关于这一点,wiki上有张图我觉得十分形象。(https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Initialization_vector_.28IV.29) 大部分场景下,我们会使用CBC模式来进行AES加密,和ECB相比,CBC引入了初始向量IV(Initialization vector),每一次加密都使用随机产生的初始向量可以大大提高密文的安全性(这里的示例代码使用固定的IV),代码如下。
# CFB模式加密
def encrypt_CFB(str, key):
    # 补全字符串,虽然明文长度没有限制,但是密码仍然需要16位
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_CFB, '1234567890123456')
    # 加密
    cipher = AESCipher.encrypt(str)
    return b2a_hex(cipher)


# CFB模式解密
def decrypt_CFB(str, key):
    # 补全字符串
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_CFB, '1234567890123456')
    # 解密
    paint = AESCipher.decrypt(a2b_hex(str))
    # 去除/0
    paint = paint.rstrip('\0')
    return paint



5. AES加密模式——CFB

除了CBC模式,这里再介绍一种加密模式——CFB模式,这个模式下明文长度可以不为16的整数倍,代码如下:

# CFB模式加密
def encrypt_CFB(str, key):
    # 补全字符串,虽然明文长度没有限制,但是密码仍然需要16位
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_CFB, '1234567890123456')
    # 加密
    cipher = AESCipher.encrypt(str)
    return b2a_hex(cipher)


# CFB模式解密
def decrypt_CFB(str, key):
    # 补全字符串
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_CFB, '1234567890123456')
    # 解密
    paint = AESCipher.decrypt(a2b_hex(str))
    # 去除/0
    paint = paint.rstrip('\0')
    return paint


6.完整的实例代码如下

# -*- coding: UTF-8 -*-


from Crypto.Cipher import AES
from binascii import b2a_hex
from binascii import a2b_hex




# 补全字符
def align(str, isKey=False):
    # 如果是密码,需要确保其长度为16
    if isKey:
        if len(str) > 16:
            return str[0:16]
        else:
            return align(str)
    # 如果是被加密字符串或长度不足的密码,则确保其长度为16的整数倍
    else:
        zerocount = 16-len(str) % 16
        for i in range(0, zerocount):
            str = str + '\0'
        return str




# ECB模式加密
def encrypt_ECB(str, key):
    # 补全字符串
    str = align(str)
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_ECB)
    # 加密
    cipher = AESCipher.encrypt(str)
    return b2a_hex(cipher)




# ECB模式解密
def decrypt_ECB(str, key):
    # 补全字符串
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_ECB)
    # 解密
    paint = AESCipher.decrypt(a2b_hex(str))
    # 去除/0
    paint = paint.rstrip('\0')
    return paint




# CBC模式加密
def encrypt_CBC(str, key):
    # 补全字符串
    str = align(str)
    key = align(key, True)
    # 初始化AES,引入初始向量
    AESCipher = AES.new(key, AES.MODE_CBC, '1234567890123456')
    # 加密
    cipher = AESCipher.encrypt(str)
    return b2a_hex(cipher)




# CBC模式解密
def decrypt_CBC(str, key):
    # 补全字符串
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_CBC, '1234567890123456')
    # 解密
    paint = AESCipher.decrypt(a2b_hex(str))
    # 去除/0
    paint = paint.rstrip('\0')
    return paint




# CFB模式加密
def encrypt_CFB(str, key):
    # 补全字符串,虽然明文长度没有限制,但是密码仍然需要16位
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_CFB, '1234567890123456')
    # 加密
    cipher = AESCipher.encrypt(str)
    return b2a_hex(cipher)




# CFB模式解密
def decrypt_CFB(str, key):
    # 补全字符串
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_CFB, '1234567890123456')
    # 解密
    paint = AESCipher.decrypt(a2b_hex(str))
    # 去除/0
    paint = paint.rstrip('\0')
    return paint




# OFB模式加密
def encrypt_OFB(str, key):
    # 补全字符串
    str = align(str)
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_OFB, '1234567890123456')
    # 加密
    cipher = AESCipher.encrypt(str)
    return b2a_hex(cipher)




# OFB模式解密
def decrypt_OFB(str, key):
    # 补全字符串
    key = align(key, True)
    # 初始化AES
    AESCipher = AES.new(key, AES.MODE_OFB, '1234567890123456')
    # 解密
    paint = AESCipher.decrypt(a2b_hex(str))
    # 去除/0
    paint = paint.rstrip('\0')
    return paint


# 先设置一段明文和密码
Text = 'Suprise!!****** *****r!'
key = 'mor'


# ECB模式加密
ciphertext = encrypt_ECB(Text, key)
print ("ECB模式密文:" + ciphertext)
# ECB模式解密
plaintext = decrypt_ECB(ciphertext, key)
print ("ECB模式明文:" + plaintext)


# CBC模式加密
ciphertext = encrypt_CBC(Text, key)
print ("CBC模式密文:" + ciphertext)
# CBC模式解密
plaintext = decrypt_CBC(ciphertext, key)
print ("CBC模式明文:" + plaintext)


# CFB模式加密
ciphertext = encrypt_CFB(Text, key)
print ("CFB模式密文:" + ciphertext)
# CFB模式解密
plaintext = decrypt_CFB(ciphertext, key)
print ("CFB模式明文:" + plaintext)


# OFB模式加密
ciphertext = encrypt_OFB(Text, key)
print ("OFB模式密文:" + ciphertext)
# OFB模式解密
plaintext = decrypt_OFB(ciphertext, key)
print ("OFB模式明文:" + plaintext)





  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
你可以使用python的cryptography库来实现AES加密解密,以及使用zeropadding进行填充。 首先,你需要安装cryptography库。可以使用以下命令来安装: ``` pip install cryptography ``` 接下来,你可以使用以下代码示例来实现AES加密解密,并使用zeropadding进行填充: ```python from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import padding from cryptography.hazmat.backends import default_backend import os def aes_encrypt(plain_text, key): # 生成一个随机的初始化向量 iv = os.urandom(16) # 使用zeropadding进行填充 padder = padding.ZeroPadding(128).padder() padded_data = padder.update(plain_text) + padder.finalize() # 创建AES加密器对象 cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) encryptor = cipher.encryptor() # 执行加密操作 cipher_text = encryptor.update(padded_data) + encryptor.finalize() return iv + cipher_text def aes_decrypt(cipher_text, key): # 提取初始化向量和密文 iv = cipher_text[:16] cipher_text = cipher_text[16:] # 创建AES解密器对象 cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) decryptor = cipher.decryptor() # 执行解密操作 padded_data = decryptor.update(cipher_text) + decryptor.finalize() # 使用zeropadding进行取消填充 unpadder = padding.ZeroPadding(128).unpadder() plain_text = unpadder.update(padded_data) + unpadder.finalize() return plain_text # 测试代码 key = os.urandom(32) # 生成一个随机密钥 plain_text = b"Hello, AES!" # 原始文本 # 加密 cipher_text = aes_encrypt(plain_text, key) print("Cipher Text: ", cipher_text) # 解密 decrypted_text = aes_decrypt(cipher_text, key) print("Decrypted Text: ", decrypted_text) ``` 这段代码,我们使用AES加密算法和CBC模式来加密解密数据。同时,我们使用了zeropadding进行填充,确保数据长度满足加密算法的要求。需要注意的是,密钥的长度必须符合AES算法的要求(16、24、或32字节)。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值