在 Python 中解密使用 .NET 加密的字符串

本文关键字:NET 加密 字符串 密使 Python 解密 | 更新日期: 2023-09-27 18:33:55

我正在尝试使用 C# 加密字符串并使用 Python 解密它。加密/解密部分按预期工作(即我能够解密我最初加密的字符串)。但是,Python 返回的字符串在开头有 2 个额外的字节,每个字符用空格分隔。

**Original string** (before encryption -- encrypted using C#) = "Something you want to keep private with AES"
**Decrypted string** (using Python) = "��S o m e t h i n g  y o u   w a n t   t o   k e e p   p r i v a t e   w i t h  A E S"

为什么我在字符串的开头得到这两个额外的字节?为什么解密字符串中有所有这些空格?知道为什么吗?

谢谢!

使用 C# 加密

public static string Encrypt<T>(string value, string password, string salt)
         where T : SymmetricAlgorithm, new()
{
    DeriveBytes rgb = new Rfc2898DeriveBytes(password, Encoding.Unicode.GetBytes(salt));
    SymmetricAlgorithm algorithm = new T();
    byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
    byte[] rgbIV = rgb.GetBytes(algorithm.BlockSize >> 3);
    ICryptoTransform transform = algorithm.CreateEncryptor(rgbKey, rgbIV);
    using (MemoryStream buffer = new MemoryStream())
    {
        using (CryptoStream stream = new CryptoStream(buffer, transform, CryptoStreamMode.Write))
        {
            using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
            {
                writer.Write(value);
            }
        }
        return Convert.ToBase64String(buffer.ToArray());
    }
}

string plain = "Something you want to keep private with AES";
string encrypted = CipherUtility.Encrypt<AesManaged>(plain, "password", "salt");

使用 Python + pycrypto 解密

import base64, sys
import Crypto.Cipher.AES
password = base64.b64decode('PSCIQGfoZidjEuWtJAdn1JGYzKDonk9YblI0uv96O8s=') # See rgbKey
salt = base64.b64decode('ehjtnMiGhNhoxRuUzfBOXw==') # See rgbIV
aes = Crypto.Cipher.AES.new(password, Crypto.Cipher.AES.MODE_CBC, salt)
text = base64.b64decode('QpHn/fnraLswwI2Znt1xTaBzRtDqO4V5QI78jLOlVsbvaIs0yXMUlqJhQtK+su2hYn28G2vNyLkj0zLOs+RIjElCSqJv1aK/Yu8uY07oAeStqRt4u/DVUzoWlxdrlF0u')
print aes.decrypt(text)

在 Python 中解密使用 .NET 加密的字符串

字符串使用 UTF-16 编码编码为字节。前两个字节是材料明细表。然后将每个字符编码为两个字节。

Encoding.Unicode文档中:

使用小字节序字节顺序获取 UTF-16 格式的编码。

要获取原始字符串,您需要将其从 UTF-16 字节解码回 Unicode 字符串。

print aes.decrypt(text).decode('utf-16')
 def decrypted(self) -> str:
    _pwd = base64.b64decode(self._key)
    _salt = base64.b64decode(self._salt)
    _aes = Crypto.Cipher.AES.new(_pwd, Crypto.Cipher.AES.MODE_CBC, _salt)
    _text = base64.b64decode(self._encrypted_str)
    _decode = _aes.decrypt(_text).decode('utf-16')
    _regex = '[a-zA-Z0-9 +-,'/ ]+'
    return re.findall(_regex, _decode)

正在使用正则表达式