我正在努力使密码安全,但我使用RSA的方式有问题。 继承我的代码:
private void testencodedecode()
{
string mehdi = "mehdi";
var enc = encodePass(mehdi);
var dec = decodePass(enc);
}
private RSAParameters rsaKey()
{
var setting = context.Settings.First(s => s.ID == 1);
byte[] pwd = Encoding.ASCII.GetBytes(setting.PWDKEY);
byte[] expo = {1,0,1};
var key = new System.Security.Cryptography.RSAParameters();
key.Exponent = expo;
key.Modulus = pwd;
return key;
}
private string encodePass(string pass)
{
var provider = new RSACryptoServiceProvider();
provider.ImportParameters(rsaKey());
var encryptedBytes = provider.Encrypt(Encoding.UTF8.GetBytes(pass), false);
return Encoding.UTF8.GetString(encryptedBytes);
}
private string decodePass(string pass)
{
var provider = new RSACryptoServiceProvider();
provider.ImportParameters(rsaKey());
string decrypted = Encoding.UTF8.GetString(provider.Decrypt(Encoding.UTF8.GetBytes(pass), true));
return decrypted;
}
似乎加密很好,但在解密时有以下错误:
要解密的数据超过此模数36个字节的最大值。
答案 0 :(得分:2)
此方法存在一些主要问题。第一个,正如您在另一个答案的评论中提到的那样,您使用Guid
来构建RSA模数,这完全无效。您不能使用随机数据直接构造公钥,原因如下:
Guid
通常不会。您应该使用RsaCryptoServiceProvider
构造函数生成RSA密钥,例如:
// Construct the RsaCryptoServiceProvider, and create a new 2048bit key
var csp = new RsaCryptoServiceProvider(2048);
然后可以导出这个新生成的密钥的参数:
// Export the RSA parameters, including the private parameters
var parameters = csp.ExportParameters(true);
然后可以存储参数(安全)并用于重新初始化CSP以便以后解密。
还有其他明显的问题,例如您可以使用RSA实际加密的数据量受密钥大小限制,因此使用上面创建的2048位密钥,您可以加密2048/8 - 11 = 245字节(其中11个字节是应用的PKCS#1 v1.5填充的结果)。如果要加密更多,通常的方法是使用对称密码(例如AES)加密数据,然后仅使用RSA加密AES密钥。
最后,虽然这可能有用,但我仍然不会依赖它来保证安全性,因为几乎总是存在滚动自己的加密方案的问题。
答案 1 :(得分:0)
RSA的模数应至少为1024位(128字节)。任何不足都将是完全不安全的。对于现代应用,甚至建议使用2048或更大的模数。
其次,您没有正确生成RSA密钥!您不应该只使用密码作为模数..
必须选择公共指数和模数,使得对于除模数的所有素数p-1
,指数相对于p
的素数。如果您只是将模数设置为密码的二进制表示(PWDKEY
),则不太可能选择合适的指数/模数对。正如我之前所说,模数必须是一个相对较大的数字,通常选择为1024,2048或4096位。