有没有人知道从任何长度的密码短语生成256位密钥值的方法?加密不能被加密,因为需要再次生成加密值并在数据库中进行比较。因此,每次加密时,值必须生成相同的加密字符串。
目前我正在使用一个32字符键来处理可能不正确的假设这是256位?
那么,我想要将“快速棕色狐狸”转换为合适的AES 256位密钥?
您可以使用任意大小的密码构造Rfc2898DeriveBytes Class
,然后在这种情况下派生所需大小的密钥,256位(32字节):
private static byte[] CreateKey(string password, int keyBytes = 32)
{
const int Iterations = 300;
var keyGenerator = new Rfc2898DeriveBytes(password, Salt, Iterations);
return keyGenerator.GetBytes(keyBytes);
}
为了产生确定性输出(即相同的输入将产生相同的输出),您将需要对盐进行硬编码。盐必须至少为8个字节:
private static readonly byte[] Salt =
new byte[] { 10, 20, 30 , 40, 50, 60, 70, 80};
可能最好的方法是使用SHA256(它将生成256位输出)和特定于应用程序的盐和迭代计数来使用PBKDF2。您应该知道,使用特定于应用程序的盐可以从PBKDF2中删除相当多的保护,因此您可能需要额外的保护来缓解此问题。一种方法是确保数据库是安全的,并且可以使用最大量的尝试。
你在规定32字符密码不是256位密钥时是正确的。它不包含足够的熵,有些字节甚至可能没有有效的字符表示。
public static string GenerateBitKey(int letterCount = 44)
{
// Get the number of words and letters per word.
int num_letters = letterCount;
// Make an array of the letters we will use.
char[] letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".ToCharArray();
// Make a random number generator.
Random rand = new Random();
// Make the words.
// Make a word.
string word = "";
for (int j = 1; j <= num_letters; j++)
{
// Pick a random number between 0 and 25
// to select a letter from the letters array.
int letter_num = rand.Next(0, letters.Length - 1);
// Append the letter.
word += letters[letter_num];
}
return word;
}
private static IBuffer GetMD5Hash(string key)
{
IBuffer bufferUTF8Msg = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
HashAlgorithmProvider hashAlgorithmProvider = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
IBuffer hashBuffer = hashAlgorithmProvider.HashData(bufferUTF8Msg);
if (hashBuffer.Length != hashAlgorithmProvider.HashLength)
{
throw new Exception("There was an error creating the hash");
}
return hashBuffer;
}
#region Static
public static string GenerateKey(string password, int resultKeyLength = 68)
{
if (password.Length < 6)
throw new ArgumentException("password length must atleast 6 characters or above");
string key = "";
var hashKey = GetMD5Hash(password);
var decryptBuffer = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8);
var AES = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
var symmetricKey = AES.CreateSymmetricKey(hashKey);
var encryptedBuffer = CryptographicEngine.Encrypt(symmetricKey, decryptBuffer, null);
key = CryptographicBuffer.EncodeToBase64String(encryptedBuffer);
string cleanKey = key.Trim(new char[] { ' ', '\r', '\t', '\n', '/', '+', '=' });
cleanKey = cleanKey.Replace("/", string.Empty).Replace("+", string.Empty).Replace("=", string.Empty);
key = cleanKey;
if(key.Length > resultKeyLength)
{
key = key.Substring(0, Math.Min(key.Length, resultKeyLength));
}
else if(key.Length == resultKeyLength)
{
return key;
}
else if (key.Length < resultKeyLength)
{
key = GenerateKey(key);
}
return key;
}
//获取AES密钥的前44个字符和AES IV的剩余字符
您可以使用一些散列函数,从任意长度的输入提供256位输出,例如SHA256。