要解密的数据超过36个字节的模数的最大值

我正在努力使密码安全,但我使用RSA的方式有问题。 inheritance我的代码:

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个字节的模数的最大值。

这里的方法存在一些主要问题。 第一个,正如您在另一个答案的评论中提到的那样,您正在使用Guid构建RSA模数,这完全无效。 您不能使用随机数据直接构造公钥,原因如下:

  1. 模数必须符合特定的结构,即它是两个素数的乘积,而你的二进制forms的Guid通常不会。
  2. 为了解密RSA加密的数据,您必须知道用于生成模数的两个素数。 即使你的随机模数神奇地是两个大素数的乘积,你也无法确定它们,因为这需要将模数分解,这是一个故意难以做到的事情(事实上,困难在于RSA的整个基础)安全)。

您应该使用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密钥。

最后,尽管这可能有效,但我仍然不会依赖它来保证安全性,因为几乎总是存在滚动自己的加密方案的问题。

RSA的模数应至少为1024位(128字节)。 任何不足都将是完全不安全的。 对于现代应用,甚至建议使用2048或更大的模数。

其次,您没有正确生成RSA密钥! 你不应该只使用密码作为模数..

必须选择公共指数和模数,使得对于除去模数的所有素数p ,指数对于p-1是相对素数。 如果您只是将模数设置为密码的二进制表示( PWDKEY ),则不太可能选择合适的指数/模数对。 正如我之前所说,模数必须是一个相对较大的数字,通常选择为1024,2048或4096位长。