【问题标题】:decrypt encrypted string during different run在不同的运行期间解密加密的字符串
【发布时间】:2020-01-21 17:03:48
【问题描述】:

下面的代码可以正常工作并加密:

hello world

到:

BgGUY2eR7GfumjbQr58tBQ==

跑步。下一次可能会有所不同,例如:

CYIM7V/h3iXu5PYzwmQ33g==

我认为这是这个算法的重点。如何解密前段时间加密的字符串?

如果我这样做:

static void Main(string[] args)
{
    var key = @"abcdefghijklmnopqrstuvw==";

    using (var aesAlg = Aes.Create())
    {
    aesAlg.Mode = CipherMode.CBC;
    aesAlg.Padding = PaddingMode.PKCS7;
    aesAlg.Key = Convert.FromBase64String(key);
    aesAlg.GenerateIV();

    var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
    var helloWorld = DecryptProperty(decryptor, "CYIM7V/h3iXu5PYzwmQ33g==");
    }

}

我明白了:

System.Security.Cryptography.CryptographicException
  HResult=0x80131430
  Message=Padding is invalid and cannot be removed.
  Source=System.Core
  StackTrace:
   at System.Security.Cryptography.CapiSymmetricAlgorithm.DepadBlock(Byte[] block, Int32 offset, Int32 count)
   at System.Security.Cryptography.CapiSymmetricAlgorithm.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at System.Security.Cryptography.CryptoStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamReader.ReadBuffer()
   at System.IO.StreamReader.ReadToEnd()
   at crypt.Program.DecryptProperty(ICryptoTransform decryptor, String valueToDecrypt) 

有什么想法吗?如何解密过去使用密钥加密的字符串?谢谢!

工作代码:

using System;
using System.IO;
using System.Security.Cryptography;

namespace crypt
{
    class Program
    {
        static void Main(string[] args)
        {
            var key = @"abcdefghijklmnopqrstuvw==";

            using (var aesAlg = Aes.Create())
            {
                aesAlg.Mode = CipherMode.CBC;
                aesAlg.Padding = PaddingMode.PKCS7;
                aesAlg.Key = Convert.FromBase64String(key);
                aesAlg.GenerateIV();

                var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
                var encHelloWorld = EncryptProperty(encryptor, "hello world");

                var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                var helloWorld = DecryptProperty(decryptor, encHelloWorld);
            }

        }
        private static string EncryptProperty(ICryptoTransform encryptor, string valueToEncrypt)
        {
            byte[] encrypted;
            using (var msEncrypt = new MemoryStream())
            {
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(valueToEncrypt);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
            return Convert.ToBase64String(encrypted);
        }

        private static string DecryptProperty(ICryptoTransform decryptor, string valueToDecrypt)
        {
            string decrypted;

            using (var msDecrypt = new MemoryStream(Convert.FromBase64String(valueToDecrypt)))
            {
                using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (var srDecrypt = new StreamReader(csDecrypt))
                    {
                        decrypted = srDecrypt.ReadToEnd();
                    }
                }
            }
            return decrypted;
        }
    }
}

【问题讨论】:

  • 上一个问题的答案或多或少地预测了这一点:您不能为解密器创建新的密钥和 IV - 它们必须与用于加密的密钥相同。密钥通常由应用程序/操作系统/您管理,IV 可以附加或附加到数据中。如果目标不是某种数据存储,则找个地方存储它
  • 谢谢,那么我可以获取它们并以某种方式对其进行硬编码吗?存储不是问题(将进入 App.config 开始)。谢谢。
  • 永远不要对 IV 进行硬编码或重用它们。始终创建一个不同的并将其与加密块一起存储。
  • @BorisB。感谢在我们的案例中,我们将加密的数据发送给第 3 方,当我们取回它时,我们会对其进行解密。您是否建议发送带有加密数据的 IV?我可以不简单地将 IV 存储为我的应用程序/数据库中的字符串 (?) 吗?谢谢。抱歉,这对我来说是全新的。

标签: c# encryption


【解决方案1】:

您在每次解密时都会生成一个新的(随机)初始化向量。解密时需要使用与加密时相同的 IV。

您的示例代码有效,因为它在同一运行中使用相同的算法状态(包括 IV)进行加密和解密,但由于GenerateIV 每次都会创建一个新的随机缓冲区,因此无法跨运行。

通常会在加密值之前写入 IV,然后将它们存储在一起。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-04
  • 2020-06-03
  • 2012-07-01
  • 2018-08-26
  • 1970-01-01
相关资源
最近更新 更多