c#AES解密错误,“填充无效,无法删除”。

问题描述 投票:0回答:1

我正在尝试编写客户端软件,该软件使用c#对设备执行AES加密和解密消息。

使用System.Security.Cryptography中的AES类,将加密消息发送到设备没有问题。设备成功解密。

解密从设备收到的消息时会出现问题。我们收到消息:“填充无效,无法删除。”

我在网上搜索并尝试了三种不同的方法,但都有相同的错误 - 见下文。我还尝试了三种方法而没有设置KeySize属性。

除了使用C#编写的客户端之外,还编写了一个python客户端,其中一切正常 - 使用python aes库。因此,有了python版本,我能够比较接收到的cipherText的长度,该长度为32字节,是一个字节数组。 15个字节是填充。我真的很感激帮助。

Option 1
byte[] messageBuffer = null;
using (Aes aesAlg = Aes.Create())
{
    aesAlg.BlockSize = 128;
    aesAlg.KeySize = 128;
    aesAlg.Mode = CipherMode.CBC;
    aesAlg.Key = encryptionKey;  //used by device to encrypt. encryptionKey is a 16 byte array
    aesAlg.IV = sentIV; //This agrees with the IV that was used to encrypt the message by the device. sentIV is a 16 byte array
    //aesAlg.Padding = PaddingMode.PKCS7;  // this makes no difference

    byte[] cipherText = encryptedMessagePart;   //encryptedMessagePart is byte[] encryptedMessagePart

    // Create a decrytor to perform the stream transform. 
    ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

    try
    {
        messageBuffer = decryptor.TransformFinalBlock(cipherText, 0, cipherText.Length);  //****fails here ********************
    }

    catch (Exception ex)
    {
        ....;
    }
}



Option 2
byte[] messageBuffer = new byte [1024];
using (Aes aesAlg = Aes.Create())
{
    aesAlg.BlockSize = 128;
    aesAlg.KeySize = 128;
    aesAlg.Mode = CipherMode.CBC;
    aesAlg.Key = encryptionKey;  //used by device to encrypt. encryptionKey is a 16 byte array
    aesAlg.IV = sentIV; //This agrees with the IV that was used to encrypt the message by the device. sentIV is a 16 byte array
    //aesAlg.Padding = PaddingMode.PKCS7;  // this makes no difference

    byte[] cipherText = encryptedMessagePart; //encryptedMessagePart is byte[] encryptedMessagePart

    // Create a decrytor to perform the stream transform. 
    ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
    using (var msDecrypt = new MemoryStream(cipherText))
    {
        using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
        {
            try
            {
                var zx = csDecrypt.Read(messageBuffer, 0, cipherText.Length); //****fails here ********************
            }
            catch (Exception ex)
            {
                ....;
            }
       }
    }
}


Option 3
byte[] messageBuffer = new byte [1024];
using (Aes aesAlg = Aes.Create())
{
    aesAlg.BlockSize = 128;
    aesAlg.KeySize = 128;
    aesAlg.Mode = CipherMode.CBC;
    aesAlg.Key = encryptionKey;  //used by device to encrypt. encryptionKey is a 16 byte array
    aesAlg.IV = sentIV; //This agrees with the IV that was used to encrypt the message by the device. sentIV is a 16 byte array
    //aesAlg.Padding = PaddingMode.PKCS7;  // this makes no difference

    byte[] cipherText = encryptedMessagePart; //encryptedMessagePart is byte[] encryptedMessagePart

    // Create a decrytor to perform the stream transform. 
    ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
    using (var msDecrypt = new MemoryStream(cipherText))
    {
        using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
        {
        using (var srDecrypt = new StreamReader(csDecrypt))
            {
                try
                {
                    // Read the decrypted bytes from the decrypting stream 
                    // and place them in a string. 
                    var pt = srDecrypt.ReadToEnd(); //****fails here ********************
                    messageBuffer = Utils.GetBytes(pt); //convert to bytes
                }
                catch (Exception ex)
                {
                    ....;
                }
            }
        }
    }
}
c# encryption cryptography aes
1个回答
1
投票

对于密钥或消息已损坏的任何内容,预计会出现填充错误。对于小于一个块的小消息,也可能是IV处理不正确。由于该设备似乎正在使用C#,这是最可能的原因。

使用ISO 10126 padding的可能性要小得多,但可能性很小。 PKCS#7填充消息可以使用ISO 10126 unpadding例程取消填充。然而,反之亦然,因为PKCS#7依赖于填充中的所有值是正确的,而不仅仅是最后一个。在ISO 10126填充中,只有最后一个字节表示使用的填充字节数;其他字节可以有任何值。

你当然可以随时看看。只需指示“无填充”并以十六进制打印出消息。如果消息是完全垃圾,则消息或更可能是密钥不正确。如果它看起来没问题那么你应该能够区分填充方法和最后一个字节;关于填充的维基百科文章列出了所有常见的方案。

© www.soinside.com 2019 - 2024. All rights reserved.