2

我正在尝试使密码安全,但是我使用 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 字节模数的最大值。

4

2 回答 2

3

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

  1. 模数必须符合特定的结构,即它是两个素数的乘积,而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);

The parameters can then be stored (securely) and used to re-initialize the CSP for decryption later.

There are also other obvious problems, such as the fact that the amount of data you can actually encrypt with RSA is limited by the key size, so with a 2048 bit key as created above, you can encrypt 2048 / 8 - 11 = 245 bytes (where the 11 bytes is a result of the PKCS#1 v1.5 padding that is applied). If you want to encrypt more than this, the general method is to use a symmetric cipher (e.g. AES) to encrypt the data, and then use RSA only to encrypt the AES key.

Finally, whilst this may work, I still wouldn't rely on it for security as there are almost always issues with roll-your-own encryption schemes.

于 2013-03-13T16:43:21.457 回答
0

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

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

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

于 2013-03-13T15:25:19.973 回答