我已经开始走以下道路:
public static void DeriveKeyPair(string pass, byte[] salt)
{
using (var derived = new Rfc2898DeriveBytes(pass, salt, 10000))
{
var randomNum = new Random(BitConverter.ToInt32(derived.GetBytes(4), 0));
// Can't seem to find an asymmetric implementation that I can supply the seed to
}
}
忽略返回类型不会做任何有用的事情这一事实,我遇到的大问题是我似乎找不到可以播种或提供种子数的非对称加密提供程序发电机到。
我这样做是为了不必将私钥存储在任何地方,这是一种安全考虑并有助于可移植性,因为可以在提供相同密码(和盐 - 最初是独特且随机)。
最佳答案
经过一番探索后,我决定生成随机 RSA key 对,然后使用 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 只能加密较小的数据 than the key size
在我的新方案中:
- 用户身份是 RSA 公钥和 RSA 私钥,该私钥已通过使用密码和盐派生 AES key 进行 AES 加密
- 加密数据涉及:
- 生成随机 AES key
- 使用该 AES key 加密数据
- 使用发起者的 RSA 私钥生成加密数据的 RSA 签名
- 通过 RSA 使用目标的 RSA 公钥对随机 AES key 进行加密来授予对数据的访问权限
这允许我存储所有核心信息:
- 公钥
- 盐
- 初始化向量
- 加密私钥
几乎是我想要的,因为实际破解私钥需要密码。
解密也相对简单:
- 接收传入数据
- RSA 根据声称的发件人的 RSA 公钥对其进行验证
- 从派生密码 + salt AES key 解密接收者的 RSA 私钥
- 解密访问 key (嵌入/托管 AES key )
- 使用提供的 key 解密收到的数据
关于c# - 从密码短语派生公钥/ key 对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32793186/