【发布时间】:2019-09-21 03:52:07
【问题描述】:
我获得了一个现有的加密算法,需要在将密码发送到 API 之前对其进行加密。
我以前没有使用 Python 以外的任何其他语言的经验,因此我无法理解在功能上我需要做什么才能复制它。
我相信 C# 中 AES 的默认模式是 CBC。我想我已经复制了大部分所需的工作,但我需要填充数据,而且我不知道具体发生在哪个阶段,或者在哪里添加了长度。我不明白 C 代码中发生的事情的顺序。我也相信默认的填充方法是 PKCS#7,尽管我很高兴在这方面得到更正。
Original code
public static string EncryptStringToBytes_Aes(string username, string password)
{
string encrypted = string.Empty;
byte[] clearBytes = Encoding. UTF8.GetBytes(password);
using (Aes aesAlg = Aes.Create())
{
byte[] k;
byte[] iv;
byte[] bytes = Encoding.UTF8.GetBytes(username);
k = SHA256.Create().ComputeHash(bytes);
iv = MD5.Create().ComputeHash(bytes);
aesAlg.Key = k;
aesAlg.IV = iv;
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key,
aesAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt,
encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(clearBytes, 0, clearBytes.Length);
}
encrypted = Convert.ToBase64String(msEncrypt.ToArray());
}
}
return encrypted;
}
python recreation
from Crypto.Cipher import AES
import hashlib
username = "example"
password = "example2"
mode = AES.MODE_CBC
clearbytes = password.encode('utf-8')
bytes = username.encode('utf-8')
key = hashlib.sha256(bytes).digest()
iv = hashlib.md5(bytes).digest()
encryptor = AES.new(key, mode, IV = iv)
length = password + '0' + str(len(clearbytes))
encrypted= encryptor.encrypt(length).encode('base64')
我收到“ValueError:输入字符串的长度必须是 16 的倍数”。
当我尝试了一些填充时,编码状态“AttributeError: 'bytes' object has no attribute 'encode'”
我希望能够阅读此代码的人可以帮助我完成在 Python 中重新创建功能的最后步骤。
【问题讨论】:
-
您可以在
Crypto.Util.Padding中找到填充函数,或者如果您使用的是 PyCrypto,您可以复制 PyCryptodome 的填充函数 from github。但是,您的 C# 代码看起来不太好:它使用散列作为 kdf、确定性 IV,并且没有身份验证。这些因素可能会降低甚至破坏您的加密方案的安全性。 -
感谢您的帮助!是的,我知道加密不是很好,它是一个外部公司的 API,所以我们必须根据需要跳过箍。幸运的是,它不是我们特别需要确保安全的东西:我们只需要它工作!
标签: c# python .net encryption aes