解密使用AES / CBC / NoPadding算法串 [英] Decrypt string using AES/CBC/NoPadding algorithm

查看:4511
本文介绍了解密使用AES / CBC / NoPadding算法串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在C#中的Windows Phone 8应用程序解密使用 AES / CBC / Nopadding 加密的刺痛。我的字符串是在 IsolatedSorage 的文件。我粘贴字符串这里这是垃圾邮件。

I want to decrypt an Encrypted Sting using AES/CBC/Nopadding in c# Windows Phone 8 application. My string is in file of IsolatedSorage. I pasted the string HERE which is junk.

从这文章,我使用的 AesManaged 类来解密。
,而如何因为默认情况下边距设置为 NoPadding 填充来自的 PKCS7 = http://qdevblog.blogspot.in/2011/08/c-aes-encryption-on-wp7.html相对=nofollow>这里

From this Article I am using AesManaged class to decrypt. But how to set padding to NoPadding because by default the padding set to PKCS7 from here.

        string fileName = "titlepage.xhtml";

        if (fileStorage.FileExists(fileName))
        {
            IsolatedStorageFileStream someStream = fileStorage.OpenFile(fileName, System.IO.FileMode.Open, FileAccess.Read);
            using (StreamReader reader = new StreamReader(someStream))
            {
                str1 = reader.ReadToEnd();

                MessageBox.Show(str1);

                try
                {
                    string text = Decrypt(str1, "****************", "****************");

                    MessageBox.Show(text);
                }
                catch (CryptographicException cryptEx)
                {
                    MessageBox.Show(cryptEx.Message, "Encryption Error", MessageBoxButton.OK);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "General Error", MessageBoxButton.OK);
                }
            }
        }

    public string Decrypt(string dataToDecrypt, string password, string salt)
    {
        AesManaged aes = null;
        MemoryStream memoryStream = null;

        try
        {
            //Generate a Key based on a Password and HMACSHA1 pseudo-random number generator
            //Salt must be at least 8 bytes long
            //Use an iteration count of at least 1000
            Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt), 10000);               

            //Create AES algorithm
            aes = new AesManaged();
            //Key derived from byte array with 32 pseudo-random key bytes
            aes.Key = rfc2898.GetBytes(32);
            //IV derived from byte array with 16 pseudo-random key bytes
            aes.IV = rfc2898.GetBytes(16);

            //Create Memory and Crypto Streams
            memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Write);

            byte[] data = Convert.FromBase64String(dataToDecrypt);
            cryptoStream.Write(data, 0, data.Length);
            cryptoStream.FlushFinalBlock();

            //Return Decrypted String
            byte[] decryptBytes = memoryStream.ToArray();

            //Dispose
            if (cryptoStream != null)
                cryptoStream.Dispose();

            //Retval
            return Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);
        }
        finally
        {
            if (memoryStream != null)
                memoryStream.Dispose();

            if (aes != null)
                aes.Clear();
        }            
    }

修改1:

当我解密我的加密字符串变薄行

When I am decrypting my Encrypted string in thins line

 byte[] data = Convert.FromBase64String(dataToDecrypt);



移动到最后阻止和获取的例外输入不是一个有效的Base-64字符串,因为它包含非基本64字符,两个以上的填充字符,或在解密的字符串填充字符中的非法字符。

正是在这里面是支持类的Windows Phone解密混淆位。

It is bit of confuse on this which is supported class to Decrypt in windows phone.

如果我是完全错误的建议我文章的网址关于算法的Windows Phone

If I am completely wrong suggest me url of article regarding algorithm in Windows Phone

编辑2:

如下回答表明我得到cyperText的字节它在解密侧的罚款。但它给人一种异常的描述

As Below answer suggested " I am getting cyperText as bytes it is fine in decryption side. But it is giving an exception with the description

       [Cryptography_SSD_InvalidDataSize]
    Arguments: 
    Debugging resource strings are unavailable. Often the key and arguments provide 
sufficient information to diagnose the problem

我认为问题是IV [盐键]或设置填充,以AesManged。
但是我不能填充属性更改为的 AesManaged Windows Phone中。
默认情况下填充,以AesManged是 PKCS7 。我想更改为 NoPadding 。因为我cyperText使用AES / CBC / NoPadding算法

I believe that problem is IV[salt key] or setting padding to AesManged. But I can't change padding property to AesManaged in Windows Phone. By default padding to AesManged is PKCS7. I want to change to NoPadding. Because my cyperText is encrypted using AES/CBC/NoPadding algorithm "

推荐答案

如果我理解这个问题,你的数据已经加密在AES CBC模式加密,不填充。但要对数据进行解密在手机上,你唯一的选择是PKCS#7填充。

If I understand the problem, you have data that is already encrypted in AES CBC mode, with no padding. But on the phone where you want to decrypt the data, the only option you have is PKCS#7 padding.

好吧,你很幸运!你可以使用PKCS#7填充。所有你需要做的就是填充添加到密文,在手机上,然后将其解密解密密文。

Well, you are in luck! You can decrypt the ciphertext using PKCS#7 padding. All you need to do is add the padding to the ciphertext, on the phone, and then decrypt it.

要在事后添加填充,可以将加密数据的小一点,并把它添加到密文。然后,您解密修改后的密文,并采取数据的小一点了,你有原始明文。

To add padding after the fact, you will encrypt a small bit of data and append it to the ciphertext. Then, you decrypt the modified ciphertext, and take that small bit of data off, and you have the original plaintext.

下面是你如何做到这一点:

Here is how you do it:


  1. 以密文的。手机这是16字节的倍数,即使是没有填充有没有其他的可能性。 - AES密文始终是16字节的倍数

  1. Take a ciphertext on the phone. This is a multiple of 16 bytes, even if there is no padding. There is no other possibility -- AES ciphertext is always a multiple of 16 bytes.

取最后16个字节的密文的一边,并设置为你的AES ENCRYPT的IV。 (加密,没有解密。)使用你打算使用后解密相同的密钥。

Take the LAST 16 bytes of the ciphertext aside, and set that as the IV of your AES ENCRYPT. (Encrypt, not decrypt.) Use the same key as you are going to use to decrypt later.

现在加密的东西比16字节小,例如,字符$。这款手机将7填充添加PKCS#这一点。

Now encrypt something smaller than 16 bytes, for example, the character '$'. The phone is going to add PKCS#7 padding to this.

从第1步,现在追加密文的产生的16字节到原来的密文,和你有一个适当的PKCS#7填密文,其包括原始明文加加入'$'

Append the resulting 16-bytes of ciphertext to the original ciphertext from step 1, and you now have a properly PKCS#7-padded ciphertext which includes the original plaintext plus the added '$'.

使用原始IV和相同的密钥,并现在解密此结合密文。现在,您可以删除'$'将出现在您的明文端(或者你在步骤3中添加。)

Use the original IV, and the same key, and now DECRYPT this combined ciphertext. You can now remove the '$' that will appear at the end of your plaintext (or whatever you added in step 3.)

在小位与原始密文的最后16字节加密,你实际上是扩大在真正的AES CBC模式的密文,和你碰巧做与PKCS#7填充,所以你现在可以解密整个事情,并采取小咬下。你将有原始明文其中有没有填充

When the small bit is encrypted with the last 16-bytes of the original ciphertext, you are actually extending the ciphertext in true AES CBC mode, and you happen to be doing that with PKCS#7 padding, so you can now decrypt the whole thing and take the small bit off. You will have the original plaintext which had no padding.

我认为这将是有趣的代码来显示:

I thought this would be interesting to show in code:

var rfc2898 = new Rfc2898DeriveBytes("password", new byte[8]);

using (var aes = new AesManaged())
{
    aes.Key = rfc2898.GetBytes(32);
    aes.IV = rfc2898.GetBytes(16);

    var originalIV = aes.IV; // keep a copy

    // Prepare sample plaintext that has no padding
    aes.Padding = PaddingMode.None;
    var plaintext = Encoding.UTF8.GetBytes("this plaintext has 32 characters");
    byte[] ciphertext;
    using (var encryptor = aes.CreateEncryptor())
    {
        ciphertext = encryptor.TransformFinalBlock(plaintext, 0, plaintext.Length);
        Console.WriteLine("ciphertext: " + BitConverter.ToString(ciphertext));
    }

    // From this point on we do everything with PKCS#7 padding
    aes.Padding = PaddingMode.PKCS7;

    // This won't decrypt -- wrong padding
    try
    {
        using (var decryptor = aes.CreateDecryptor())
        {
            var oops = decryptor.TransformFinalBlock(ciphertext, 0, ciphertext.Length);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("caught: " + e.Message);
    }

    // Last block of ciphertext is used as IV to encrypt a little bit more
    var lastBlock = new byte[16];
    var modifiedCiphertext = new byte[ciphertext.Length + 16];

    Array.Copy(ciphertext, ciphertext.Length - 16, lastBlock, 0, 16);
    aes.IV = lastBlock;

    using (var encryptor = aes.CreateEncryptor())
    {
        var dummy = Encoding.UTF8.GetBytes("$");
        var padded = encryptor.TransformFinalBlock(dummy, 0, dummy.Length);

        // Set modifiedCiphertext = ciphertext + padded
        Array.Copy(ciphertext, modifiedCiphertext, ciphertext.Length);
        Array.Copy(padded, 0, modifiedCiphertext, ciphertext.Length, padded.Length);
        Console.WriteLine("modified ciphertext: " + BitConverter.ToString(modifiedCiphertext));
    }

    // Put back the original IV, and now we can decrypt...
    aes.IV = originalIV;

    using (var decryptor = aes.CreateDecryptor())
    {
        var recovered = decryptor.TransformFinalBlock(modifiedCiphertext, 0, modifiedCiphertext.Length);
        var str = Encoding.UTF8.GetString(recovered);
        Console.WriteLine(str);

        // Now you can remove the '$' from the end
    }
}

这篇关于解密使用AES / CBC / NoPadding算法串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆