使用 AES/CBC/NoPadding 将 C# 转换为 Python
Convert C# to Python using AES/CBC/NoPadding
我正在尝试将此 C# 代码转换为 Python (2.7)。问题是解密的结果是python码错误。 IV 和密钥正确。
我发现很多主题都在谈论 Python 和 C#,但我没有找到答案。
C#加密:
class Tracer
{
private static readonly int BlockBitSize = 128;
private static readonly int KeyBitSize = 256;
internal static byte[] In(byte[] plainBytes, byte[] uid)
{
using (var sha = new SHA512Managed())
{
var hash = sha.ComputeHash(uid);
return In(plainBytes, hash.Skip(32).Take(32).ToArray(), hash.Take(16).ToArray());
}
}
internal static byte[] In(byte[] plainBytes, byte[] key, byte[] iv)
{
if (key == null || key.Length != KeyBitSize / 8)
throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key");
if (iv == null || iv.Length != BlockBitSize / 8)
throw new ArgumentException(String.Format("IV needs to be {0} bit!", BlockBitSize), "iv");
using (AesManaged aes = new AesManaged())
{
aes.KeySize = KeyBitSize;
aes.BlockSize = BlockBitSize;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.None;
using (ICryptoTransform encrypter = aes.CreateEncryptor(key, iv))
using (MemoryStream cipherStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write))
{
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
cryptoStream.FlushFinalBlock();
}
return cipherStream.ToArray();
}
}
}
internal static byte[] Out(byte[] cipherBytes, byte[] uid)
{
using (var sha = new SHA512Managed())
{
var hash = sha.ComputeHash(uid);
return Out(cipherBytes, hash.Skip(32).Take(32).ToArray(), hash.Take(16).ToArray());
}
}
internal static byte[] Out(byte[] cipherBytes, byte[] key, byte[] iv)
{
if (key == null || key.Length != KeyBitSize / 8)
throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key");
if (iv == null || iv.Length != BlockBitSize / 8)
throw new ArgumentException(String.Format("IV needs to be {0} bit!", BlockBitSize), "iv");
using (AesManaged aes = new AesManaged())
{
aes.KeySize = KeyBitSize;
aes.BlockSize = BlockBitSize;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.None;
using (ICryptoTransform decrypter = aes.CreateDecryptor(key, iv))
using (MemoryStream plainStream = new MemoryStream())
{
using (var decrypterStream = new CryptoStream(plainStream, decrypter, CryptoStreamMode.Write))
using (var binaryWriter = new BinaryWriter(decrypterStream))
{
//Decrypt Cipher Text from Message
binaryWriter.Write(cipherBytes, 0, cipherBytes.Length);
}
//Return Plain Text
return plainStream.ToArray();
}
}
}
}
Python解密
def AESdecrypt(ciphertext, UID):
from Crypto.Cipher import AES
digest = hashlib.sha512(UID).hexdigest()
iv = BitArray(hex=digest[:32])
key = BitArray(hex=digest[64:128])
block40Str = BitArray(hex=ciphertext[1].encode('hex'))
cipherSpec = AES.new(key.bytes, AES.MODE_CBC, iv.bytes)
plaintextWithPadding = cipherSpec.decrypt(block40Str.bytes)
注意:对不起我的英文
感谢您的帮助!
编辑:AES 解密 Python return 64 个字符,这是错误的。原来的明文是32.
EDIT2:Python 代码已更新。解密函数return现在是32个字符,但还是出错
用于生成密钥和 iv 的摘要是使用正确的数据生成的,但在字符串中。相反,C# 使用数据的 ByteArray 生成摘要。感谢 BitArray Python library ,我解决了我的问题 :
新 Python 代码:
def AESdecrypt(ciphertext, UID):
from Crypto.Cipher import AES
UIDBytes = BitArray(hex=UID)
digest = hashlib.sha512(UIDBytes.bytes).hexdigest()
iv = BitArray(hex=digest[:32])
key = BitArray(hex=digest[64:128])
cipherSpec = AES.new(key.bytes, AES.MODE_CBC, iv.bytes)
plaintextWithoutPadding = cipherSpec.decrypt(ciphertext[1])
我正在尝试将此 C# 代码转换为 Python (2.7)。问题是解密的结果是python码错误。 IV 和密钥正确。
我发现很多主题都在谈论 Python 和 C#,但我没有找到答案。
C#加密:
class Tracer
{
private static readonly int BlockBitSize = 128;
private static readonly int KeyBitSize = 256;
internal static byte[] In(byte[] plainBytes, byte[] uid)
{
using (var sha = new SHA512Managed())
{
var hash = sha.ComputeHash(uid);
return In(plainBytes, hash.Skip(32).Take(32).ToArray(), hash.Take(16).ToArray());
}
}
internal static byte[] In(byte[] plainBytes, byte[] key, byte[] iv)
{
if (key == null || key.Length != KeyBitSize / 8)
throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key");
if (iv == null || iv.Length != BlockBitSize / 8)
throw new ArgumentException(String.Format("IV needs to be {0} bit!", BlockBitSize), "iv");
using (AesManaged aes = new AesManaged())
{
aes.KeySize = KeyBitSize;
aes.BlockSize = BlockBitSize;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.None;
using (ICryptoTransform encrypter = aes.CreateEncryptor(key, iv))
using (MemoryStream cipherStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write))
{
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
cryptoStream.FlushFinalBlock();
}
return cipherStream.ToArray();
}
}
}
internal static byte[] Out(byte[] cipherBytes, byte[] uid)
{
using (var sha = new SHA512Managed())
{
var hash = sha.ComputeHash(uid);
return Out(cipherBytes, hash.Skip(32).Take(32).ToArray(), hash.Take(16).ToArray());
}
}
internal static byte[] Out(byte[] cipherBytes, byte[] key, byte[] iv)
{
if (key == null || key.Length != KeyBitSize / 8)
throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key");
if (iv == null || iv.Length != BlockBitSize / 8)
throw new ArgumentException(String.Format("IV needs to be {0} bit!", BlockBitSize), "iv");
using (AesManaged aes = new AesManaged())
{
aes.KeySize = KeyBitSize;
aes.BlockSize = BlockBitSize;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.None;
using (ICryptoTransform decrypter = aes.CreateDecryptor(key, iv))
using (MemoryStream plainStream = new MemoryStream())
{
using (var decrypterStream = new CryptoStream(plainStream, decrypter, CryptoStreamMode.Write))
using (var binaryWriter = new BinaryWriter(decrypterStream))
{
//Decrypt Cipher Text from Message
binaryWriter.Write(cipherBytes, 0, cipherBytes.Length);
}
//Return Plain Text
return plainStream.ToArray();
}
}
}
}
Python解密
def AESdecrypt(ciphertext, UID):
from Crypto.Cipher import AES
digest = hashlib.sha512(UID).hexdigest()
iv = BitArray(hex=digest[:32])
key = BitArray(hex=digest[64:128])
block40Str = BitArray(hex=ciphertext[1].encode('hex'))
cipherSpec = AES.new(key.bytes, AES.MODE_CBC, iv.bytes)
plaintextWithPadding = cipherSpec.decrypt(block40Str.bytes)
注意:对不起我的英文
感谢您的帮助!
编辑:AES 解密 Python return 64 个字符,这是错误的。原来的明文是32.
EDIT2:Python 代码已更新。解密函数return现在是32个字符,但还是出错
用于生成密钥和 iv 的摘要是使用正确的数据生成的,但在字符串中。相反,C# 使用数据的 ByteArray 生成摘要。感谢 BitArray Python library ,我解决了我的问题 :
新 Python 代码:
def AESdecrypt(ciphertext, UID):
from Crypto.Cipher import AES
UIDBytes = BitArray(hex=UID)
digest = hashlib.sha512(UIDBytes.bytes).hexdigest()
iv = BitArray(hex=digest[:32])
key = BitArray(hex=digest[64:128])
cipherSpec = AES.new(key.bytes, AES.MODE_CBC, iv.bytes)
plaintextWithoutPadding = cipherSpec.decrypt(ciphertext[1])