我对跨语言的加密/解密有点问题。
下面是我的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 - 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;
}然而,解密后的值总是不正确地显示如下:

我想这和垫子有关,谁能建议怎么绕过这件事?
发布于 2015-11-17 13:01:12
问题不是填充物。是你还没切掉的静脉输液。IV不一定是秘密的,但每次加密都应该随机生成。由于您已经将IV包含到Python中的密文中,所以您必须在解密期间在C#中使用它(当然,应该对实际的密文进行解密,不包括IV):
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)
{
byte[] iv = new byte[16]; // change
Array.copy(bytes, iv, 16); // change
AesManaged algorithm = new AesManaged();
algorithm.IV = iv; // change
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, 16, bytes.Length - 16); // change
}
ret = msDecrypted.ToArray();
}
}
return ret;
}Python代码也不是没有问题的。你不需要通过静脉注射,因为你把它放在密文里。因此,您可以创建一个新的随机IV。此外,unpad函数是不正确的(或者至少不必要地复杂)。
class AESCipher:
def __init__( self, key):
self.key = base64.b64decode(key)
def encrypt( self, raw ):
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
raw = pad(raw)
iv = Random.new().read(BS)
cipher = AES.new(self.key, AES.MODE_CBC, iv)
res = iv + cipher.encrypt( raw )
return base64.b64encode(res)
def decrypt( self, enc ):
enc = base64.b64decode(enc)
BS = 16
iv = enc[:BS]
unpad = lambda s : s[:-ord(s[-1])]
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc[BS:] ))
crypt = AESCipher("key", "iv")
print "{0}".format(crypt.encrypt("Hallow"))别忘了验证你的密文。否则,可能会对您的系统发起填充oracle攻击,从而使攻击能够使用多个联机查询对每个密文进行解密。
您可以使用经过身份验证的模式,如GCM或EAX,也可以使用加密后MAC方案,使用强MAC(如HMAC-SHA256 256)。
https://stackoverflow.com/questions/33757283
复制相似问题