Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python AES加密填充导致C#解密问题_C#_Python_Encryption_Cryptography - Fatal编程技术网

Python AES加密填充导致C#解密问题

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 -

我在跨语言加密/解密方面有点问题

下面是我加密一些文本的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;
}
但是,解密后的值总是错误地显示为:


我认为这与填充物有关,有人能建议如何避开吗?

问题不在于填充物。这是你没有切掉的静脉注射。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”)
to
algorithm.Key=Encoding.UTF8.GetBytes(Key)