1、AESCryptoHelper
class AESCryptoHelper():
def encrypt(data, key):
"""
加密时使用的key,只能是长度16,24和32的字符串
data: 要加密的内容,bytes
key:密钥,len必须是16, 24, 32之一 bytes
result:加密内容,bytes
"""
keySzie = len(key)
if keySzie == 16 or keySzie == 24 or keySzie == 32:
cipher = AES.new(key, AES.MODE_ECB)
padData = AESCryptoHelper._padData(data)
encrypted = cipher.encrypt(padData)
result = base64.b64encode(encrypted)
return result
else:
# 加密失败,返回原数据
return data
def _padData(data):
"""
按AES加密的要求,填充内容,使其为block_size的整数倍
"""
block_size = 16
padding = b"\0"
padData = data + (block_size - len(data) % block_size) * padding
return padData
# 解密后,去掉补足的空格用strip() 去掉
def decrypt(data, key):
"""
加密时使用的key,只能是长度16,24和32的字符串
data: 要解密的内容,bytes
key:密钥,bytes
result:解密的内容,bytes
"""
keySzie = len(key)
if keySzie == 16 or keySzie == 24 or keySzie == 32:
cipher = AES.new(key, AES.MODE_ECB)
tmpData = base64.b64decode(data)
decrypted = cipher.decrypt(tmpData)
result = AESCryptoHelper._unpadData(decrypted)
return result
else:
# 解密失败,返回原数据
return data
def _unpadData(data):
"""
删除填充数据
"""
padding = b"\0"
index = -1
while data[index] == padding[0]:
index += -1
if index != -1:
return data[0: index+1]
else:
return data
2、功能测试
1)编程环境
- Python3.6
- pyCryptodome
2)测试代码
# -*- coding: utf-8 -*-
from Crypto.Cipher import AES
import base64
if __name__ == "__main__":
key = "0123456789ABCDEF"
data = "人生苦短,我用python!"
print("原文: {}".format(data))
# 加密
encrypted = AESCryptoHelper.encrypt(data.encode('utf-8'), key.encode('utf-8'))
print("加密:{}".format(encrypted.decode(encoding='utf-8')))
# 解密
decrypted = AESCryptoHelper.decrypt(encrypted, key.encode('utf-8'))
print("解密:{}".format(decrypted.decode(encoding='utf-8')))
打印结果:
原文: 人生苦短,我用python!
加密:BougbSDKKKBBkp9iz+Q1gbhyK3BD2I3C7Dw4/FlVMXI=
解密:人生苦短,我用python!
3)C#部分
注意:PaddingMode必须为PaddingMode.None(与python对应),如果需要其他PaddingMode,需要修改Python中的_padData和_unpadData函数。
using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
class AESHelper
{
public static string AESEncrypt(String Data, String Key)
{
if (Key.Length == 16 || Key.Length == 24 || Key.Length == 32)
{
MemoryStream mStream = new MemoryStream();
RijndaelManaged aes = new RijndaelManaged();
byte[] plainBytes = AesTool.PadData(Encoding.UTF8.GetBytes(Data));
byte[] bKey = Encoding.UTF8.GetBytes(Key);
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.None;
aes.KeySize = 128;
aes.Key = bKey;
CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write);
try
{
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(mStream.ToArray());
}
finally
{
cryptoStream.Close();
mStream.Close();
aes.Clear();
}
}
else
{
return Data;
}
}
public static byte[] PadData(byte[] data)
{
var blockSize = 16;
byte padding = 0;
var dataList = new List<byte>(data);
while (dataList.Count % blockSize != 0)
{
dataList.Add(padding);
}
return dataList.ToArray();
}
public static string AESDecrypt(String Data, String Key)
{
if (Key.Length == 16 || Key.Length == 24 || Key.Length == 32)
{
byte[] encryptedBytes = Convert.FromBase64String(Data);
byte[] bKey = Encoding.UTF8.GetBytes(Key);
MemoryStream mStream = new MemoryStream(encryptedBytes);
RijndaelManaged aes = new RijndaelManaged();
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.None;
aes.KeySize = 128;
aes.Key = bKey;
CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Read);
try
{
byte[] tmp = new byte[encryptedBytes.Length + 32];
int len = cryptoStream.Read(tmp, 0, encryptedBytes.Length + 32);
byte[] ret = new byte[len];
Array.Copy(tmp, 0, ret, 0, len);
ret = AesTool.UnpadData(ret);
return Encoding.UTF8.GetString(ret);
}
finally
{
cryptoStream.Close();
mStream.Close();
aes.Clear();
}
}
else
{
return Data;
}
}
public static byte[] UnpadData(byte[] data)
{
byte padding = 0;
var dataList = new List<byte>(data);
var index = dataList.Count - 1;
while (dataList[dataList.Count - 1] == padding)
{
dataList.RemoveAt(dataList.Count - 1);
}
return dataList.ToArray();
}
}
4)参考
pycryptodome
AES Encryption in Python Using PyCrypto
python3.6 实现AES加密----pyCryptodome
python AES 加密与解密
TypeError: Object type <class 'str'> cannot be passed to C code
网友评论