После некоторой охоты я решил остановиться на генерации случайной пары ключей RSA, а затем симметрично зашифровать закрытый ключ с помощью AES.
Это приводит меня к двум следующим методам:
public static byte[] EncryptData(string pass, byte[] salt, byte[] encryptedPrivateKey, byte[] targetPublicKey,
byte[] iv, byte[] data)
{
using (var rfc = new Rfc2898DeriveBytes(pass, salt, IterationCount))
{
using (var aes = new AesCryptoServiceProvider())
{
aes.KeySize = AesKeySize;
aes.Key = rfc.GetBytes(aes.KeySize / 8);
aes.IV = iv;
using (var dec = aes.CreateDecryptor(aes.Key, aes.IV))
{
using (var ms = new MemoryStream(encryptedPrivateKey))
{
using (var cs = new CryptoStream(ms, dec, CryptoStreamMode.Read))
{
var privKey = new byte[RsaKeySize];
cs.Read(privKey, 0, privKey.Length);
return RsaEncrypt(targetPublicKey, data);
}
}
}
}
}
}
public static byte[] DecryptData(string pass, byte[] salt, byte[] encryptedPrivateKey, byte[] iv, byte[] data)
{
using (var rfc = new Rfc2898DeriveBytes(pass, salt, IterationCount))
{
using (var aes = new AesCryptoServiceProvider())
{
aes.KeySize = AesKeySize;
aes.Key = rfc.GetBytes(aes.KeySize/8);
aes.IV = iv;
using (var dec = aes.CreateDecryptor(aes.Key, aes.IV))
{
using (var ms = new MemoryStream(encryptedPrivateKey))
{
using (var cs = new CryptoStream(ms, dec, CryptoStreamMode.Read))
{
var privKey = new byte[RsaKeySize];
cs.Read(privKey, 0, privKey.Length);
return RsaDecrypt(privKey, data);
}
}
}
}
}
}
RSA недостаточно.
По сути, RSA может шифровать только данные меньшего размера , чем размер ключа
В моей новой схеме:
- Идентификатор пользователя - это открытый ключ RSA и закрытый ключ RSA, зашифрованный с помощью AES путем получения ключа AES с использованием пароля и соли.
- Encrypting data involves:
- Generating a random AES key
- Шифрование данных с помощью этого ключа AES
- Создание подписи RSA для зашифрованных данных с использованием закрытого ключа RSA отправителя
- Доступ к данным предоставляется RSA, шифруя случайный ключ AES с открытым ключом RSA цели.
Это позволяет мне хранить всю основную информацию:
- Открытый ключ
- Поваренная соль
- Вектор инициализации
- Зашифрованный закрытый ключ
в основном там, где я хочу, потому что пароль нужен, чтобы действительно взломать закрытый ключ.
Расшифровка тоже относительно проста:
- Получать входящие данные
- RSA сверяет его с открытым ключом RSA предполагаемого отправителя.
- Расшифровать закрытый ключ RSA получателя из производного пароля + солевого ключа AES
- Расшифровать ключ доступа (встроенный / размещенный ключ AES)
- Расшифровать полученные данные с помощью предоставленного ключа
person
Clint
schedule
26.09.2015