Я думаю, что вы ищете для получения ключа на основе пароля.Существует класс Rfc2898DeriveBytes
, который его реализует.
Rfc2898DeriveBytes
берет пароль, соль и счетчик итераций, а затем генерирует ключи посредством вызовов метода GetBytes
.
RFC 2898 включает методы для создания ключа и вектора инициализации (IV) из пароля и соли.Вы можете использовать PBKDF2, функцию получения ключей на основе пароля, для получения ключей с использованием псевдослучайной функции, которая позволяет генерировать ключи практически неограниченной длины.Класс Rfc2898DeriveBytes можно использовать для создания производного ключа из базового ключа и других параметров.В функции получения ключа на основе пароля базовый ключ представляет собой пароль, а другие параметры - это солт-значение и счетчик итераций.
Для получения дополнительной информации о PBKDF2 см. RFC 2898, «PKCS # 5: Пароль».Спецификация криптографии на основе версии 2.0, ".
Пример:
public static byte[] CreateKey(string password)
{
var salt = new byte[] { 1, 2, 23, 234, 37, 48, 134, 63, 248, 4 };
const int Iterations = 9872;
using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, Iterations))
return rfc2898DeriveBytes.GetBytes(32);
}
Вы можете использовать DeriveBytes
в любом симметричном алгоритме, а не только Rijndael
.
Пример:
public static SymmetricAlgorithm InitSymmetric(SymmetricAlgorithm algorithm, string password, int keyBitLength)
{
var salt = new byte[] { 1, 2, 23, 234, 37, 48, 134, 63, 248, 4 };
const int Iterations = 234;
using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, Iterations))
{
if (!algorithm.ValidKeySize(keyBitLength))
throw new InvalidOperationException("Invalid size key");
algorithm.Key = rfc2898DeriveBytes.GetBytes(keyBitLength / 8);
algorithm.IV = rfc2898DeriveBytes.GetBytes(algorithm.BlockSize / 8);
return algorithm;
}
}
private static byte[] Transform(byte[] bytes, Func<ICryptoTransform> selectCryptoTransform)
{
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, selectCryptoTransform(), CryptoStreamMode.Write))
cryptoStream.Write(bytes, 0, bytes.Length);
return memoryStream.ToArray();
}
}
Использование:
public static void Main()
{
using (var rijndael = InitSymmetric(Rijndael.Create(), "TestPassword", 256))
{
var text = "Some text to encrypt";
var bytes = Encoding.UTF8.GetBytes(text);
var encryptedBytes = Transform(bytes, rijndael.CreateEncryptor);
var decryptedBytes = Transform(encryptedBytes, rijndael.CreateDecryptor);
var decryptedText = Encoding.UTF8.GetString(decryptedBytes);
Debug.Assert(text == decryptedText);
}
}
Обязательно измените параметры salt
и iterations
.