我坚持使用加密方法。我对加密或字节数组知之甚少,所以我很难解决这个问题。
这是我的代码:
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");
它提供了一个错误指定键不是这个算法的有效大小。如何解决这个问题,如何通过这种方法加密任何字符串(主要是1-8个字符)?
DES算法需要64位(8字节)密钥。你的sEncryptionKey
长度为6个字符,这就是你得到“指定密钥不是有效大小”错误的原因。
DES使用64位密钥,这些密钥不应该是像SomePass这样的人性化密码。它们应该是二进制密钥,涵盖了64位密钥的所有可能变化(2 ^ 64种不同的组合)。否则,您的加密将比DES标准暗示的要弱得多。
这就是为什么当使用来自System.Security.Cryptography
的对称加密算法时,你应该将你的秘密视为将用作加密的最终密钥,而不是作为生成加密密钥的密码。你通过使用passprase和一些盐构建System.Security.Cryptography.Rfc2898DeriveBytes
实例来执行这一代(可以随机生成但也应该在解密期间使用)。
您的代码的另一个问题是您正在使用长度为6个字节的初始化向量(IV
)。它也应该是8字节长度,你应该使用随机初始化向量进行每次加密。您可以通过调用DESCryptoServiceProvider.GenerateIV()
方法并访问DESCryptoServiceProvider.IV
属性来生成IV。
最后的说明。由于您将returnstring
转换为Base64,因此无需替换所有这些特殊字符,例如'&'和'$'。 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;
}
}