【问题标题】:Error: Specified key is not a valid size for this algorithm错误:指定的密钥不是此算法的有效大小
【发布时间】:2017-12-21 04:43:19
【问题描述】:

我被一种加密方法困住了。我对加密或字节数组知之甚少,所以我很难解决这个问题。

这是我的代码:

 public static class EncryptDecrypt {
    private static byte[] key = { };
    private static string sEncryptionKey = "B@|@j!";
    private static byte[] IV = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab};

public static string Encrypt(string stringToEncrypt)
    {
        string returnstring = "";
        try
        {

            key = System.Text.Encoding.UTF8.GetBytes(sEncryptionKey);
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToEncrypt);
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms,
                des.CreateEncryptor(key, IV), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();

            returnstring = Convert.ToBase64String(ms.ToArray());

            //URL Encryption Avoid Reserved Characters
            returnstring = returnstring.Replace("/", "-2F-");
            returnstring = returnstring.Replace("!", "-21-");
            returnstring = returnstring.Replace("#", "-23-");
            returnstring = returnstring.Replace("$", "-24-");
            returnstring = returnstring.Replace("&", "-26-");
            returnstring = returnstring.Replace("'", "-27-");
            returnstring = returnstring.Replace("(", "-28-");
            returnstring = returnstring.Replace(")", "-29-");
            returnstring = returnstring.Replace("*", "-2A-");
            returnstring = returnstring.Replace("+", "-2B-");
            returnstring = returnstring.Replace(",", "-2C-");
            returnstring = returnstring.Replace(":", "-3A-");
            returnstring = returnstring.Replace(";", "-3B-");
            returnstring = returnstring.Replace("=", "-3D-");
            returnstring = returnstring.Replace("?", "-3F-");
            returnstring = returnstring.Replace("@", "-40-");
            returnstring = returnstring.Replace("[", "-5B-");
            returnstring = returnstring.Replace("]", "-5D-");


            return returnstring;
        }
        catch (Exception e)
        {
            return e.Message;
        }
    }
}

但是每当我将字符串作为string encrypt= EncryptDecrypt.Encrypt("abcd"); 传递时,它都会提供错误Specified key is not a valid size for this algorithm。 如何解决这个问题以及如何通过这种方法加密任何字符串(主要是 1-8 个字符)?

【问题讨论】:

  • "如何解决这个问题" -- 根据错误消息,您似乎应该提供一个 is 有效的键值算法的大小。除此之外,请解决您的问题,以便您包含一个很好的 minimal reproducible example 来重现问题并解释为什么您认为您用于 sEncryptionKey 的值应该有效。
  • Base 64 只包含特殊字符+/=。所以不需要替换任何其他字符。如果您确实更换它们,您最好使用base 64 url。密码与密钥不同,如果您生活在 1970 年,使用 DES 当然很好。试试 AES-GCM。

标签: c# algorithm encryption


【解决方案1】:

DES 算法需要 64 位(8 字节)密钥。您的 sEncryptionKey 的长度为 6 个字符,这就是您收到“指定的密钥不是有效大小”错误的原因。

DES 使用 64 位密钥,这些密钥不应该是像“SomePass”这样的人类友好密码。它们应该是涵盖 64 位密钥(2^64 种不同组合)所有可能种类的二进制密钥。否则,您的加密将比 DES 标准所暗示的要弱得多。

这就是为什么在使用来自System.Security.Cryptography 的对称加密算法时,您不应将您的秘密视为将用于加密的最终密钥,而应将其视为您生成加密密钥的密码短语。您通过使用您的密码和一些盐(可以随机生成但也应该在解密期间使用)构造System.Security.Cryptography.Rfc2898DeriveBytes 的实例来执行此生成。

您的代码的另一个问题是您使用了 6 字节长度的初始化向量 (IV)。它也应该是 8 字节长度,并且您应该为每个加密使用 random 初始化向量。您可以通过调用DESCryptoServiceProvider.GenerateIV() 方法并访问DESCryptoServiceProvider.IV 属性来生成IV。

最后一点。由于您将returnstring 转换为Base64,因此无需替换所有这些特殊字符,例如'&' 和'$'。 Base64 字符集由数字、数字和“+”、“/”、“=”符号组成。您只能替换这 3 个字符。

所以这里是基于上述 cmets 的代码编辑:

public static class EncryptDecrypt
{
    private static string sEncryptionPassphrase = "B@|@j!";

    public static string Encrypt(string stringToEncrypt)
    {
        try
        {
            string returnstring;
            var salt = GenerateSalt();
            using (var keyBytes = new Rfc2898DeriveBytes(sEncryptionPassphrase, salt))
            {
                var key = keyBytes.GetBytes(8);

                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                des.GenerateIV();
                byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToEncrypt);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(key, des.IV), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                returnstring = Convert.ToBase64String(ms.ToArray());
            }

            //URL Encryption Avoid Reserved Characters
            returnstring = returnstring.Replace("/", "-2F-");
            returnstring = returnstring.Replace("+", "-2B-");
            returnstring = returnstring.Replace("=", "-3D-");

            return returnstring;
        }
        catch (Exception e)
        {
            return e.Message;
        }
    }

    private static byte[] GenerateSalt()
    {
        var randomBytes = new byte[8];
        using (var rngCsp = new RNGCryptoServiceProvider())
        {
            rngCsp.GetBytes(randomBytes);
        }
        return randomBytes;
    }
}

【讨论】:

  • 感谢您非常好的解释 :) 对理解密码学很有帮助...
  • 你能告诉我如何用你的方式解密字符串
猜你喜欢
  • 2011-02-24
  • 2010-12-22
  • 2020-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
相关资源
最近更新 更多