Python AES加密填充导致C#解密问题
我在跨语言加密/解密方面有点问题 下面是我加密一些文本的python代码:Python AES加密填充导致C#解密问题,c#,python,encryption,cryptography,C#,Python,Encryption,Cryptography,我在跨语言加密/解密方面有点问题 下面是我加密一些文本的python代码: class AESCipher: def __init__( self, key, iv ): self.key = base64.b64decode(key) self.iv = base64.b64decode(iv) def encrypt( self, raw ): BS = 16 pad = lambda s: s + (BS -
class AESCipher:
def __init__( self, key, iv ):
self.key = base64.b64decode(key)
self.iv = base64.b64decode(iv)
def encrypt( self, raw ):
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
raw = pad(raw)
cipher = AES.new( self.key, AES.MODE_CBC, self.iv)
res = self.iv + cipher.encrypt( raw )
return base64.b64encode(res)
def decrypt( self, enc ):
enc = base64.b64decode(enc)
unpad = lambda s : s[:-ord(s[len(s)-1:])]
cipher = AES.new(self.key, AES.MODE_CBC, self.iv )
return unpad(cipher.decrypt( enc[16:] ))
crypt = AESCipher("key", "iv")
print "{0}".format(crypt.encrypt("Hallow"))
和C#解密:
public static string DecryptStringFromBase64(string base64String)
{
byte[] bytes = Decrypt(Convert.FromBase64String(base64String));
var utf8 = Encoding.UTF8.GetString(bytes);
return utf8;
}
public static byte[] Decrypt(byte[] bytes)
{
AesManaged algorithm = new AesManaged();
algorithm.IV = Convert.FromBase64String("IV");
algorithm.Key = Convert.FromBase64String("KEY");
byte[] ret = null;
using (var decryptor = algorithm.CreateDecryptor())
{
using (MemoryStream msDecrypted = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msDecrypted, decryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(bytes, 0, bytes.Length);
}
ret = msDecrypted.ToArray();
}
}
return ret;
}
但是,解密后的值总是错误地显示为:
我认为这与填充物有关,有人能建议如何避开吗?问题不在于填充物。这是你没有切掉的静脉注射。IV不必是秘密的,但应该为每次加密随机生成。由于已经在Python中将IV包含到密文中,因此在解密过程中必须在C#中使用它(当然,解密应该在实际密文上完成,不包括IV): #
公共静态字符串解密StringFromBase64(字符串base64String)
{
byte[]bytes=解密(Convert.FromBase64String(base64String));
var utf8=Encoding.utf8.GetString(字节);
返回utf8;
}
公共静态字节[]解密(字节[]字节)
{
字节[]iv=新字节[16];//更改
Array.copy(字节,iv,16);//更改
AES托管算法=新AES托管();
算法IV=IV;//更改
算法.Key=Convert.FromBase64String(“Key”);
字节[]ret=null;
使用(var decryptor=algorithm.CreateDecryptor())
{
使用(MemoryStream msDecrypted=new MemoryStream())
{
使用(CryptoStream csEncrypt=new CryptoStream(msDecrypted、decryptor、CryptoStreamMode.Write))
{
csEncrypt.Write(字节,16,字节.长度-16);//更改
}
ret=msDecrypted.ToArray();
}
}
返回ret;
}
Python代码也并非没有问题。你不需要通过IV,因为你要把它输入密文。因此,您可以创建一个新的random IV。此外,unpad
函数不正确(或者至少不必要地复杂)
类密码:
def uuu init uuuu(self,key):
self.key=base64.b64解码(key)
def加密(自身、原始):
BS=16
pad=λs:s+(BS-长度%BS)*chr(BS-长度%BS)
原始=焊盘(原始)
iv=随机。新建()。读取(BS)
密码=AES.new(self.key,AES.MODE_CBC,iv)
res=iv+加密(原始)
返回base64.b64编码(res)
def解密(自我,加密):
enc=base64.b64解码(enc)
BS=16
iv=附件[:BS]
unpad=lambda s:s[:-ord(s[-1])]
密码=AES.new(self.key,AES.MODE_CBC,iv)
返回unpad(cipher.decrypt(enc[BS:]))
crypt=AESChipher(“密钥”、“iv”)
打印“{0}”。格式(crypt.encrypt(“Hallow”))
别忘了验证你的密文。否则,可能会对您的系统发起填充oracle攻击,从而使攻击能够通过多个在线查询解密每个密文
您可以使用经过身份验证的模式,如GCM或EAX,或者使用加密后的MAC方案,使用强MAC,如HMAC-SHA256。我对此进行了一次尝试,并且行
csEncrypt.Write(bytes,16,bytes.Length);//change
引发错误:在mscorlib.dll中发生类型为“System.ArgumentException”的未处理异常。其他信息:偏移量和长度超出数组的界限,或者计数大于从索引到源集合结尾的元素数。
抱歉,我以为第三个参数是结束索引,但它是一个计数。现在应该可以了。对我来说效果很好,谢谢,只需更改algorithm.Key=Convert.FromBase64String(“Key”)
toalgorithm.Key=Encoding.UTF8.GetBytes(Key)代码>