简体   繁体   中英

Error: Specified key is not a valid size for this algorithm

I am stuck with an encryption method. I don't have very much knowledge on encryption or Byte array so its been difficult to me to solve this issue.

Here is my Code:

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

But whenever I passed a string as string encrypt= EncryptDecrypt.Encrypt("abcd"); It provides an error Specified key is not a valid size for this algorithm. How to solve this problem and how could I able to encrypt any string (mostly 1-8 character) though this method?

DES algorithm expects 64-bit (8 bytes) key. Your sEncryptionKey has length of 6 chars, that's why you get "Specified key is not a valid size" error.

DES works with 64-bit keys and these keys should not be human-friendly passprases like 'SomePass'. They should be binary keys that cover all possible variety for 64-bit keys (2^64 different combinations). Otherwise your encryption will be much more weaker than DES standard implies.

That's why when using symmetric encryption algorithms from System.Security.Cryptography , you should treat your secret not as final key that will be used for encryption but as a passphrase from which you generate encryption key. You perform this generation by constructing instance of System.Security.Cryptography.Rfc2898DeriveBytes with your passprase and some salt (which could be randomly generated but should also be used during decryption).

Another problem with your code is that you're using initialization vector ( IV ) with 6 bytes length. It should also be 8-bytes length and you should use random initialization vector for each encryption. You could generate IV by calling DESCryptoServiceProvider.GenerateIV() method and accessing DESCryptoServiceProvider.IV property.

And final note. Since you convert returnstring to Base64 there is no need in replacing all those special characters, like '&' and '$'. Base64 charset consists from digits, numbers and '+', '/', '=' symbols. You could replace only these 3 chars.

So here is edit of your code based on above comments:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM