通过提供模数和指数进行RSA加密

时间:2012-03-23 12:34:55

标签: c# winforms encryption rsa

我正在创建一个C#Winforms应用程序,它通过HTTPS将数据发送到服务器。

登录机制应该是这样的:

  1. 我将用户名发送到服务器,它以rsa-modulus和rsa-exponent响应

  2. 我使用这些给定的参数加密密码,并将用户名+密码发送到服务器进行身份验证

  3. 我已经尝试了RSACryptoServiceProvider课程,但我找不到样本或任何说明我们如何使用给定的模数和指数进行加密?

    我认为没有指定任何值,它会做默认加密参数..

    所以如果以前有人这样做过,他们可以给我一些提示吗?感谢

    更新:根据Carsten Konig先生的建议,。我试图用RSAParameters和RSA.ImportParameters来做,但它返回带有加密异常的“BAD DATA”错误。我的代码如下。

    我也试过RSA.FromXmlString(mykey); (其中mykey包含一个带有模数和exp的xml字符串)但是我还得到一个带有加密异常的“BAD DATA”错误...任何人都有什么想法?或者如果它的一些微软bug,谁能建议其他一些体面的库容易做到这一点?

    RSAParameters rsaparam = new RSAParameters(); 
    rsaparam.Modulus = modbytes; 
    rsaparam.Exponent = expbytes; 
    RSACryptoServiceProvider RSA = new RSACryptoServiceProvider() ; 
    RSA.ImportParameters(rsaparam); 
    byte[] encryptedData = RSA.Encrypt(dataToEncrypt, false)
    

3 个答案:

答案 0 :(得分:7)

您可以使用RSACryptoServiceProvider.Encrypt方法执行此操作。您还需要使用RSACryptoServiceProvider.ImportParameters方法并将其传递给RSAParameters结构(这是您设置指数,模数等的位置)。

请查看RSAParameters链接中的文档 - 它已经很好地记录了你必须传递什么参数的结构字段 - 如果你现在算法应该没问题。

编辑:这是直接来自MSDN-site

的示例
class RSACSPSample
{

    static void Main()
    {
        try
        {       //initialze the byte arrays to the public key information.
            byte[] PublicKey = {214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56,
                                   74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222,
                                   207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175,
                                   108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194,
                                   240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139,
                                   168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171,
                                   38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93,
                                   106,99,179,68,175,211,164,116,64,148,226,254,172,147};

            byte[] Exponent = {1,0,1};

            //Values to store encrypted symmetric keys.
            byte[] EncryptedSymmetricKey;
            byte[] EncryptedSymmetricIV;

            //Create a new instance of RSACryptoServiceProvider.
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

            //Create a new instance of RSAParameters.
            RSAParameters RSAKeyInfo = new RSAParameters();

            //Set RSAKeyInfo to the public key values. 
            RSAKeyInfo.Modulus = PublicKey;
            RSAKeyInfo.Exponent = Exponent;

            //Import key parameters into RSA.
            RSA.ImportParameters(RSAKeyInfo);

            //Create a new instance of the RijndaelManaged class.
            RijndaelManaged RM = new RijndaelManaged();

            //Encrypt the symmetric key and IV.
            EncryptedSymmetricKey = RSA.Encrypt(RM.Key, false);
            EncryptedSymmetricIV = RSA.Encrypt(RM.IV, false);

            Console.WriteLine("RijndaelManaged Key and IV have been encrypted with RSACryptoServiceProvider."); 

        }
        //Catch and display a CryptographicException  
        //to the console.
        catch(CryptographicException e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

请注意,只有密钥/ iv加密 - 而不是任意字节 - 这些字节的长度也很重要!

允许的长度在MSDN中描述,取决于操作系统!

答案 1 :(得分:1)

如果您使用RSACryptoServiceProvider.ToXmlString导出服务器发送的模数和指数,则需要使用Convert.FromBase64String。

    public RSAParameters SetPublicKey(string modulus, string exponent)
    {
        RSAParameters result = new RSAParameters();
        result.Modulus = Convert.FromBase64String(modulus);
        result.Exponent = Convert.FromBase64String(exponent);

        return result;
    }

答案 2 :(得分:0)

另一个对我非常有用的提示:

在这一行中,

//Set RSAKeyInfo to the public key values. 
SAKeyInfo.Modulus = PublicKey;

PublicKey也可以是直接,直接的字节数组,您可以从X509证书的“公钥”字段(直接)获得。