Конвертировать алгоритм шифрования C # в Python 3 - PullRequest
0 голосов
/ 02 мая 2019

Мне дали существующий алгоритм шифрования, который необходим для шифрования пароля перед его отправкой через API.

У меня нет опыта работы с другими языками, кроме Python, и поэтому я не могу понять, чтофункционально мне нужно сделать, чтобы повторить это.

Я считаю, что режимом по умолчанию для AES в C # является 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.

Ответы [ 2 ]

1 голос
/ 03 мая 2019

Я считаю, что добился успеха, используя комбинацию ответов и комментариев здесь. Заполнение ключа не требовалось, поскольку хэш уже кратен 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)
1 голос
/ 02 мая 2019

Глядя на документы , вы неправильно используете модуль шифрования.

При вызове AES.new() передаваемый ключ должен быть длиной 16-байтовой строки,поэтому вам нужно дополнить свой атрибут key длиной 16 байт.

Метод encrypt() принимает в качестве входных данных строку байтов, где, как вы, похоже, пытаетесь передать длину (чтодаже не определен в вашем примере).

Ваши комментарии предполагают, что вы сделали это, хотя, иначе вы бы не увидели исключение AttributeError.

Вы видите AttributeError, потому что Cipher.encrypt() возвращает байтовый массив, а байтовый массив не имеет encode() метода.Вы должны сначала преобразовать ваш байтовый массив в строку.Следующий фрагмент кода из здесь должен помочь:

import array
decoded = array.array('b', your_input).tostring().decode('utf-8') 

Очевидно, вы должны заменить 'utf-8' на 'base64'.

...