C# 要解密的数据超过此模数36字节的最大值

C# 要解密的数据超过此模数36字节的最大值,c#,rsa,C#,Rsa,我试图使密码安全,但我如何使用RSA有问题。 这是我的密码: private void testencodedecode() { string mehdi = "mehdi"; var enc = encodePass(mehdi); var dec = decodePass(enc); } private RSAParameters rsaKey() { var setting = cont

我试图使密码安全,但我如何使用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字节的最大值


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

其次,您没有正确生成RSA密钥!你不应该只把密码当作模数


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

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

  • 模数必须符合特定的结构,即它是两个大素数的乘积,而二进制形式的
    Guid
    通常不会
  • 为了解密RSA加密的数据,必须知道用于生成模的两个素数。即使你的随机模神奇地是两个大素数的乘积,你也无法确定它们,因为这需要对模进行因式分解,这是一件非常困难的事情(事实上,困难是RSA安全性的全部基础)
  • 您应该使用
    rsacyptoserviceprovider
    构造函数生成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密钥


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

    我正在为其pwd使用指南,这还不够吗?Guid g=Guid.NewGuid();setting.PWDKEY=g.ToString();所以我需要除以模,找到合适的指数?我是rsa编码新手,我只想用一种简单的方法来做。不建议手动生成rsa密钥。NET提供了生成密钥对的标准方法(您需要公钥和私钥才能执行任何有用的操作),您应该使用该方法,或者导入以前生成的密钥对。请看一看:首先,使用GUID不是一个好主意的原因是,尽管GUID是唯一的并且看起来是随机的,但它们在加密方面并不安全。第二个是GUID是128位的数字,而RSA模数至少应该是1024位。除非您有绝对要求以纯文本检索密码(大多数应用程序不需要),否则您应该进行散列(使用salt),而不是加密。@Damien_不信者,正如我提到的,它是密码安全的,因此,用户需要查看他保存的密码,我考虑过sha1和md5,但没有办法检索它们,所以有必要对其进行加密。啊。我把“安全”理解为形容词,而不是名词。我以为你是想让它免受攻击。@Damien_不信者没关系:)