错误:指定的密钥不是此算法的有效大小

时间:2017-12-21 04:43:19

标签: c# algorithm encryption

我坚持使用加密方法。我对加密或字节数组知之甚少,所以我很难解决这个问题。

这是我的代码:

<!DOCTYPE html>
<html>
<head>
    <title>Login page</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css"
          integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
            integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
            crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"
            integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh"
            crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"
            integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ"
            crossorigin="anonymous"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <a class="navbar-brand" href="#">User Management</a>
    <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item">
                <a class="nav-link" href="#">Home</a>
            </li>
        </ul>
        <span class="navbar-text">
         <div class="btn-group">
  <button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true"
          aria-expanded="false">
         button
  </button>
  <div class="dropdown-menu">
     <a class="dropdown-item" href="#">View Account</a>
    <a class="dropdown-item" href="#">Sign out</a>
  </div>
</div>
    </span>
    </div>
</nav>
</body>
</html>

但每当我传递一个字符串为 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; } } } 时它会提供错误指定的密钥不是此算法的有效大小。 如何解决这个问题,如何通过这种方法加密任何字符串(主要是1-8个字符)?

1 个答案:

答案 0 :(得分:2)

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

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

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

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

最后的说明。由于您将returnstring转换为Base64,因此无需替换所有这些特殊字符,例如'&amp;'和'$'。 Base64字符集由数字,数字和'+','/','='符号组成。你可以只替换这3个字符。

所以这里是根据以上评论编辑你的代码:

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;
    }
}