已为我提供了一种现有的加密算法,该算法需要在通过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'对象没有属性'encode'”
我希望可以阅读此代码的人可以帮助我完成在Python中重新创建功能的最后步骤。
答案 0 :(得分:1)
看着docs,您没有正确使用密码模块。
调用AES.new()
时,您传递的密钥必须是16个字符的字节字符串,因此您需要填充key
属性以使其具有16个字节的长度。
encrypt()
方法采用字节字符串作为输入,因为您似乎试图传递一个长度(在示例中甚至没有定义)。
您的评论建议您还是通过了它,否则您将看不到AttributeError
异常。
您看到的AttributeError
是因为Cipher.encrypt()
返回一个字节数组,而字节数组没有encode()
方法。您首先需要将字节数组转换为字符串。来自here的以下代码段应有所帮助:
import array
decoded = array.array('b', your_input).tostring().decode('utf-8')
您显然应该将'utf-8'
替换为'base64'
。
答案 1 :(得分:1)
我相信我已经成功了,这里结合了答案和评论。不需要填充密钥,因为哈希已经是16的倍数。(希望成功的)以下代码供参考。 (不幸的是,在测试连接之前,我还有另外两节C#代码要翻译!)
Python Conversion
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import hashlib
import base64
username = "example"
password = "example"
mode = AES.MODE_CBC
bytes = username.encode('utf-8')
data_for_padding = password + '0' + str(len(password))
padded = pad(data_for_padding)
key = hashlib.sha256(bytes).digest()
iv = hashlib.md5(bytes).digest()
encryptor = AES.new(key, mode, IV = iv)
clearbytes = padded.encode('utf-8')
ciphertext = encryptor.encrypt(clearbytes)
result = base64.b64encode(ciphertext)