我正在尝试确保密码安全,但我使用 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;
}
似乎加密得很好,但解密时出现以下错误:
The data to be decrypted exceeds the maximum for this modulus of 36 bytes.
最佳答案
这里的方法存在一些主要问题。首先,正如您在另一个答案的评论中提到的那样,您正在使用 Guid
来构造 RSA 模数,这是完全无效的。由于多种原因,您不能使用随机数据直接构造公钥:
- 模数必须符合特定的结构,即它是两个大素数的乘积,而二进制形式的
Guid
通常不会。< - 为了解密 RSA 加密数据,您必须知道用于生成模数的两个素数。即使你的随机模数神奇地是两个大素数的乘积,你也无法确定它们,因为这需要对模数进行因式分解,这是一件故意困难的事情(事实上,困难在于 RSA 的整个基础)安全)。
您应该使用 RsaCryptoServiceProvider
构造函数生成 RSA key ,例如:
// Construct the RsaCryptoServiceProvider, and create a new 2048bit key
var csp = new RsaCryptoServiceProvider(2048);
然后可以导出这个新生成的 key 的参数:
// Export the RSA parameters, including the private parameters
var parameters = csp.ExportParameters(true);
然后可以(安全)存储参数并用于重新初始化 CSP 以便稍后解密。
还有其他明显的问题,例如您可以使用 RSA 实际加密的数据量受到 key 大小的限制,因此使用上面创建的 2048 位 key ,您可以加密 2048/8 - 11 = 245 字节(其中 11 字节是应用 PKCS#1 v1.5 填充的结果)。如果您想加密更多内容,一般方法是使用对称密码(例如 AES)来加密数据,然后仅使用 RSA 来加密 AES key 。
最后,虽然这可能有效,但我仍然不会依赖它来保证安全,因为自行设计的加密方案几乎总是存在问题。
关于c# - 要解密的数据超出了该模数的最大值 36 字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15389421/