Шифрование строки в .net и дешифрование в python - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь зашифровать пароль с помощью system.Security.Cryptography, которая работает правильно Это код (.Net)

if (clearText == null)
{
    clearText = "";
}
string EncryptionKey = "****";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
    encryptor.Key = pdb.GetBytes(32);
    encryptor.IV = pdb.GetBytes(16);
    using (MemoryStream ms = new MemoryStream())
    {
        using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
        {
            cs.Write(clearBytes, 0, clearBytes.Length);
            cs.Close();
        }
        clearText = Convert.ToBase64String(ms.ToArray());
    }
}
return clearText;

И это код расшифровки в Python, который не работает должным образом

def Decryptstr(self, text):
    try:
        EncryptionKey = "****"
        if text is None:
            return
        else:
            cipherbytes = base64.b64decode(text)
            salt = '\0x49\0x76\0x61\0x6e\0x20\0x4d\0x65\0x64\0x76\0x65\0x64\0x65\0x76'
            key_bytes = KDF.PBKDF2(EncryptionKey, salt, dkLen=32)
            iv = KDF.PBKDF2(EncryptionKey, salt,dkLen=16)
            cipher = AES.new(key_bytes, AES.MODE_CBC, iv)
            password = cipher.decrypt(cipherbytes).decode('utf-16')
            print(password)
            return password
    except Exception as err:
        print(err)

Ниже приведен вывод вышеуказанного кода для зашифрованной строки ('eet123'). 䏺 ꧴ 퐄 妯 ৞ 軸 힡 薟

Любая помощь будет оценена.

1 Ответ

0 голосов
/ 03 января 2019

Кажется, что ваше PBKDF2HMAC извлечение ключа на стороне Python неверно.Вам нужно передать правильные параметры и получить ключ на 48 байтов.Затем используйте первые 32 байта как Key и последние 16 байтов как IV (в вашем дизайне).

Вот рабочая пара кодов C# / Python.Первая C# часть:

static string encrypt(string clearText = "")
{
    if (clearText == null)
    {
        clearText = "";
    }

    string EncryptionKey = "****";
    byte[] clearBytes = Encoding.UTF8.GetBytes(clearText);
    using (Aes encryptor = Aes.Create())
    {
       Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }, 100000, HashAlgorithmName.SHA1);
       encryptor.Key = pdb.GetBytes(32);
       encryptor.IV = pdb.GetBytes(16);
       encryptor.Mode = CipherMode.CBC;
       using (MemoryStream ms = new MemoryStream())
       {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(clearBytes, 0, clearBytes.Length);
                cs.Close();
            }
        clearText = Convert.ToBase64String(ms.ToArray());
        }
    }
    return clearText;
} 

Об этом C# код:

  1. По умолчанию Rfc2898DeriveBytes использует SHA1 и только 1000 раундов.Я предлагаю вам использовать не менее 100 000Я видел кодовые приложения, которые используют 1 000 000 раундов.Вы также можете изменить хэш, но количество раундов важнее.
  2. Укажите и режим.Хотя он по умолчанию использует CBC, я думаю, что лучше его указать.
  3. Поскольку C# использует длину ключа для выбора алгоритма AES, этот код использует AES-256.

Сейчас Python part:

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend

def Decryptstr(self, text):
    try:
        if text is None:
            return
        else:
            backend = default_backend()
            EncryptionKey = "****"
            salt = bytes([ 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 ])
            kdf = PBKDF2HMAC(algorithm=hashes.SHA1(),length=48,salt=salt,iterations=100000,backend=backend)
            key_parts = kdf.derive(bytes(EncryptionKey, 'utf-8'))
            key = key_bytes[0:32]
            iv = key_bytes[32:]

            cipherbytes = base64.b64decode(text)
            cipher = AES.new(key, AES.MODE_CBC, iv)
            password = cipher.decrypt(cipherbytes).decode('utf-8')
            print(password)
            return password
    except Exception as err:
        print(err)

Как видите, я использовал другую библиотеку PBKDF2HMAC.Я использовал его для создания 48 байтов и использовал первые 32 как Key и последние 16 байтов как IV.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...