Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.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
C# AES-CBC中的填充_C#_Cryptography_Encryption Symmetric_Rijndaelmanaged_Cbc Mode - Fatal编程技术网

C# AES-CBC中的填充

C# AES-CBC中的填充,c#,cryptography,encryption-symmetric,rijndaelmanaged,cbc-mode,C#,Cryptography,Encryption Symmetric,Rijndaelmanaged,Cbc Mode,我正在尝试使用C#中的(128位AES)随机IV测试CBC 在我要解决的问题中,我有12字节的输入消息。条件是,如果纯文本小于块大小(16字节),则要使用的填充从0x01开始,然后最多为6 0x00 示例: in ASCII PT = Pay Bob 100% in hex PT = 50 61 79 20 42 6f 62 20 31 30 30 24 PT with Padding = 50 61 79 20 42 6f 62 20 31 30 30 24 01 00

我正在尝试使用C#中的(128位AES)随机IV测试CBC

在我要解决的问题中,我有12字节的输入消息。条件是,如果纯文本小于块大小(16字节),则要使用的填充从0x01开始,然后最多为6 0x00

示例:

in ASCII PT     = Pay Bob 100%

in hex PT       = 50 61 79 20 42 6f 62 20 31 30 30 24

PT with Padding = 50 61 79 20 42 6f 62 20 31 30 30 24 01 00 00 00
public class CBC
{
    public CBC()
    {

    }

    private static readonly byte[] SALT = new byte[]
        {0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c};

    public static byte[] EncryptCBC(string plainText, string passPhrase, PaddingMode paddingMode )
    {
        byte[] result;
        using (RijndaelManaged cryptoProvider = new RijndaelManaged())
        {
            Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(passPhrase, SALT);
            cryptoProvider.Mode = CipherMode.CBC;
            cryptoProvider.GenerateIV(); // generate random IV

            cryptoProvider.Padding = paddingMode;

            cryptoProvider.Key = derivedKey.GetBytes(cryptoProvider.KeySize / 8);

            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (ICryptoTransform encryptor = cryptoProvider.CreateEncryptor(cryptoProvider.Key, cryptoProvider.IV))
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(plainText);
                        }
                    }
                }
                // concatenate iv to ciphertext
                result = cryptoProvider.IV.Concat(msEncrypt.ToArray()).ToArray();
            }
            cryptoProvider.Clear();
        }
        return result;
    }

    public static string DecryptCBC(byte[] cipherTextBytes, string passPhrase, PaddingMode paddingMode)
    {
        string result = null;
        using (RijndaelManaged cryptoProvider = new RijndaelManaged())
        {
            Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(passPhrase, SALT);
            cryptoProvider.Mode = CipherMode.CBC;
            // take the iv off the beginning of the ciphertext message
            cryptoProvider.IV = cipherTextBytes.Take(cryptoProvider.BlockSize / 8).ToArray();


            cryptoProvider.Padding = paddingMode;//PaddingMode.ANSIX923;



            cryptoProvider.Key = derivedKey.GetBytes(cryptoProvider.KeySize / 8);

            using (MemoryStream msEncrypt = new MemoryStream(cipherTextBytes.Skip(cryptoProvider.BlockSize / 8).ToArray())) // skip the IV bytes
            {
                using (ICryptoTransform encryptor = cryptoProvider.CreateDecryptor(cryptoProvider.Key, cryptoProvider.IV))
                {
                    using (CryptoStream cryptoStream = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Read))
                    {
                        byte[] plainTextBytes = new byte[cipherTextBytes.Length - cryptoProvider.BlockSize / 8];
                        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

                        result = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                        cryptoStream.Close();
                    }
                }
            }

            cryptoProvider.Clear();
        }
        return result;
    }

}
我似乎无法在RijndaelManaged中找到此填充模式

有人能建议我怎么做吗

  • 可变长度填充
编辑:

in ASCII PT     = Pay Bob 100%

in hex PT       = 50 61 79 20 42 6f 62 20 31 30 30 24

PT with Padding = 50 61 79 20 42 6f 62 20 31 30 30 24 01 00 00 00
public class CBC
{
    public CBC()
    {

    }

    private static readonly byte[] SALT = new byte[]
        {0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c};

    public static byte[] EncryptCBC(string plainText, string passPhrase, PaddingMode paddingMode )
    {
        byte[] result;
        using (RijndaelManaged cryptoProvider = new RijndaelManaged())
        {
            Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(passPhrase, SALT);
            cryptoProvider.Mode = CipherMode.CBC;
            cryptoProvider.GenerateIV(); // generate random IV

            cryptoProvider.Padding = paddingMode;

            cryptoProvider.Key = derivedKey.GetBytes(cryptoProvider.KeySize / 8);

            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (ICryptoTransform encryptor = cryptoProvider.CreateEncryptor(cryptoProvider.Key, cryptoProvider.IV))
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(plainText);
                        }
                    }
                }
                // concatenate iv to ciphertext
                result = cryptoProvider.IV.Concat(msEncrypt.ToArray()).ToArray();
            }
            cryptoProvider.Clear();
        }
        return result;
    }

    public static string DecryptCBC(byte[] cipherTextBytes, string passPhrase, PaddingMode paddingMode)
    {
        string result = null;
        using (RijndaelManaged cryptoProvider = new RijndaelManaged())
        {
            Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(passPhrase, SALT);
            cryptoProvider.Mode = CipherMode.CBC;
            // take the iv off the beginning of the ciphertext message
            cryptoProvider.IV = cipherTextBytes.Take(cryptoProvider.BlockSize / 8).ToArray();


            cryptoProvider.Padding = paddingMode;//PaddingMode.ANSIX923;



            cryptoProvider.Key = derivedKey.GetBytes(cryptoProvider.KeySize / 8);

            using (MemoryStream msEncrypt = new MemoryStream(cipherTextBytes.Skip(cryptoProvider.BlockSize / 8).ToArray())) // skip the IV bytes
            {
                using (ICryptoTransform encryptor = cryptoProvider.CreateDecryptor(cryptoProvider.Key, cryptoProvider.IV))
                {
                    using (CryptoStream cryptoStream = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Read))
                    {
                        byte[] plainTextBytes = new byte[cipherTextBytes.Length - cryptoProvider.BlockSize / 8];
                        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

                        result = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                        cryptoStream.Close();
                    }
                }
            }

            cryptoProvider.Clear();
        }
        return result;
    }

}
我的填充功能

        private byte[] PaddPlainTextBytes(byte[] plainTextBytes )
    {
        byte[] padding = utils.HexToBytes("01000000");
        MemoryStream s = new MemoryStream();

        s.Write(plainTextBytes, 0, plainTextBytes.Length);
        s.Write(padding, 0, padding.Length);

        byte[] paddedPt = s.ToArray();

        return paddedPt;
    }
测试我的CBC的方法

        private void btnTestCBC_Click(object sender, EventArgs e)
    {
        string plainText = "Pay Bob 100%";

        string passPhrase = "Thisismypassphrase";
        ShowMessage(@"Plain Text = " + plainText);

        byte[] pBytes = PaddPlainTextBytes(Encoding.ASCII.GetBytes(plainText));

        string message = Encoding.ASCII.GetString(pBytes);

        byte[] encryptedBytes = CBC.EncryptCBC(plainText: message, passPhrase: passPhrase, paddingMode: PaddingMode.None);

        ShowMessage("Encrypted String = " + Encoding.ASCII.GetString(encryptedBytes));
        ShowMessage("Encrypted HEX = " + utils.BytesToHex(encryptedBytes));


        string decryptedString = CBC.DecryptCBC(encryptedBytes, passPhrase, PaddingMode.None);
        ShowMessage("Deccrypted String = " + decryptedString);
    }

我不熟悉您的填充方案,但它肯定不是内置在.net中的。您应该能够将
PaddingMode
设置为
None
,并将pad后挂到输入消息中,无论解密的是什么,结果都应该相同。如果您要解密它,您必须自己删除pad。

我不熟悉您的填充方案,但它肯定没有内置到.net中。您应该能够将
PaddingMode
设置为
None
,并将pad后挂到输入消息中,无论解密的是什么,结果都应该相同。如果你要解密它,你必须自己移除pad。

你描述的填充方案看起来很像,请参阅Wikipedia paddings页面(我刚刚编辑过)了解填充方法。通常,您首先将一个位设置为1,而不是一个字节,因此第一个字节将是0x80,而不是0x01


此填充节点可能不是内置的。如果你想进行实验,我建议你使用Bouncy Castle LIB,否则就改用几乎无处不在的PKCS#7填充。

你所描述的填充方案看起来很像,请参阅维基百科页面上的填充(我刚刚编辑过)了解填充方法。通常,您首先将一个位设置为1,而不是一个字节,因此第一个字节将是0x80,而不是0x01


此填充节点可能不是内置的。如果您想进行实验,我建议您使用Bouncy Castle LIB,否则请切换到几乎无处不在的PKCS#7填充。

您也可以使用不需要填充的操作模式,如CTR。唉,这不是内置的。您似乎认为填充始终是固定长度,而不是对齐功能。您还可以使用不需要填充的操作模式,如CTR。不是内置的,唉。您似乎认为填充始终是固定长度的,而不是对齐函数。您的输出工作正常,您的问题是,填充函数不工作可变长度的消息。
100..00
中没有“
”。不做选择的密文攻击作业,第一个问题是如何在c#中进行某种填充,修改后的问题不是堆栈溢出问题,如果您问的问题确实与CBC的工作方式有关,则可能是crypto.stackoverflow问题。那么我如何将此问题移至crypto.stackoverflow?将此问题还原为有关填充的问题,然后问一个关于加密的新问题,关于如何用填充方案修改CBC加密的填充块。我已经更新了这个问题。你能为处理最后一个块的可变长度的填充函数提供一个例子吗?你的输出有效,你的问题是,填充函数不能处理可变长度的消息在
100..00
中没有“
”。没有做选择的密文攻击作业,第一个问题是如何在c#中进行某种填充,修改后的问题不是堆栈溢出问题,如果您问的问题确实与CBC的工作方式有关,则可能是crypto.stackoverflow问题。那么我如何将此问题移至crypto.stackoverflow?将此问题还原为有关填充的问题,然后问一个关于加密的新问题,关于如何用填充方案修改CBC加密的填充块。我已经更新了这个问题。你能提供一个处理最后一块可变长度的填充函数的例子吗?@KhurramMajeed谢谢,从我的智能手机上发布,难以编辑:)@KhurramMajeed谢谢,从我的智能手机上发布,难以编辑:)