C# 从字符串公钥设置模数RSA参数

C# 从字符串公钥设置模数RSA参数,c#,rsa,C#,Rsa,在参数中设置模数参数有一个问题。 我在字节数组中转换公钥字符串,我的问题是长度太长 byte[] lExponent = { 1, 0, 1 }; //Create a new instance of the RSACryptoServiceProvider class. RSACryptoServiceProvider lRSA = new RSACryptoServiceProvider(); //Create a new instance of the RSAParamete

在参数中设置模数参数有一个问题。 我在字节数组中转换公钥字符串,我的问题是长度太长

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

 //Create a new instance of the RSACryptoServiceProvider class.
 RSACryptoServiceProvider lRSA = new RSACryptoServiceProvider();


 //Create a new instance of the RSAParameters structure.
 RSAParameters lRSAKeyInfo = new RSAParameters();

//Set RSAKeyInfo to the public key values. 
string KeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCV/eUrmhIZul32nN41sF0y/k4detUxPTQngHFQGOoQNCRa84+2mGdCAg3EN9DPsUtCSHjscfp5xC9otgZsj13Rn7atbGZhJn5eZpIzPZV/psfeueL0Idq7b1msyBNG8dqR0WblYvzSY8uWwIIWyOkrQvtUwHJoxrBD4iLO/NEvzQIDAQAB";
PublicKey = Convert.FromBase64String(KeyString);


lRSAKeyInfo.Modulus = PublicKey;
lRSAKeyInfo.Exponent = lExponent;

lRSA.ImportParameters(lRSAKeyInfo);

return Convert.ToBase64String(lRSA.Encrypt(InputStringbytes, false));
问题是我的密钥大小是1296,而不是1024。我已经用XMLParameter字符串进行了测试,但我有同样的问题


我需要帮助。谢谢大家,我真的不明白你是说原始公钥有问题,还是你认为它是正确的,而你的代码不起作用。我使用以下(BouncyCastle库)进行加密:

public string PublicKeyEncrypt(string plaintext, Stream publickey)
{
    try
    {
        var rsaKeyParameters = (RsaKeyParameters)PublicKeyFactory.CreateKey(publickey);
        var rsaParameters = new RSAParameters();
        rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned();
        rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned();
        var rsa = new RSACryptoServiceProvider();
        rsa.ImportParameters(rsaParameters);
        return Convert.ToBase64String(rsa.Encrypt(Encoding.UTF8.GetBytes(plaintext), true));
    }
    catch (Exception e)
    {
        // Whatever
    }
}
如果需要使用密钥的字节数组调用它:

public string PublicKeyEncrypt(string plaintext, byte[] publickey)
{
    return PublicKeyEncrypt(plaintext, new MemoryStream(publickey, false));
}

您的字符串长度为216个字符,这意味着它代表162个字节。162字节是1296位

因此,该程序似乎完全按照您的要求执行(模的长度(以位为单位)是RSA密钥的大小)


因此,您的字符串不代表RSA 1024位模数值,您一定复制了错误的数据值。

您的
键串是一个base64编码的DER编码对象,实际上包含1024位RSA模数。要亲自查看,您可以使用。只需复制并粘贴base64字符串,然后单击decode

在Java中,此格式(不带base64编码)由
PublicKey.getEncoded()
方法返回

关于stackoverflow,有各种各样的答案试图解决这个问题。在中使用,并提供以下C#片段:

byte[] publicKeyBytes = Convert.FromBase64String(publicKeyString);
AsymmetricKeyParameter asymmetricKeyParameter = PublicKeyFactory.CreateKey(publicKeyBytes);
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters) asymmetricKeyParameter;
RSAParameters rsaParameters = new RSAParameters();
rsaParameters.Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned();
rsaParameters.Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned();
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParameters);
包含较长的代码序列,但避免使用bouncycastle C#库


我还没有测试其中任何一个。

这是一个ce解决方案,用于获取DER编码blob公钥中的模

private string Encrypt(string pPublicKey, string pInputString)
    {
        //Create a new instance of the RSACryptoServiceProvider class.
        RSACryptoServiceProvider lRSA = new RSACryptoServiceProvider();

        //Import key parameters into RSA.
        lRSA.ImportParameters(GetRSAParameters(pPublicKey));

        return Convert.ToBase64String(lRSA.Encrypt(Encoding.UTF8.GetBytes(pInputString), false));
    }

    private static RSAParameters GetRSAParameters(string pPublicKey)
    {
        byte[] lDer;

        //Set RSAKeyInfo to the public key values. 
        int lBeginStart = "-----BEGIN PUBLIC KEY-----".Length;
        int lEndLenght = "-----END PUBLIC KEY-----".Length;
        string KeyString = pPublicKey.Substring(lBeginStart, (pPublicKey.Length - lBeginStart - lEndLenght));
        lDer = Convert.FromBase64String(KeyString);


        //Create a new instance of the RSAParameters structure.
        RSAParameters lRSAKeyInfo = new RSAParameters();

        lRSAKeyInfo.Modulus = GetModulus(lDer);
        lRSAKeyInfo.Exponent = GetExponent(lDer);

        return lRSAKeyInfo;
    }

    private static byte[] GetModulus(byte[] pDer)
    {
        //Size header is 29 bits
        //The key size modulus is 128 bits, but in hexa string the size is 2 digits => 256 
        string lModulus = BitConverter.ToString(pDer).Replace("-", "").Substring(58, 256);

        return StringHexToByteArray(lModulus);
    }

    private static byte[] GetExponent(byte[] pDer)
    {
        int lExponentLenght = pDer[pDer.Length - 3];
        string lExponent = BitConverter.ToString(pDer).Replace("-", "").Substring((pDer.Length * 2) - lExponentLenght * 2, lExponentLenght * 2);

        return StringHexToByteArray(lExponent);
    }    

    public static byte[] StringHexToByteArray(string hex)
    {
        return Enumerable.Range(0, hex.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                         .ToArray();
    }

感谢您的帮助

通常情况下,公钥是好的,因为使用库javascript,公钥可以工作()。我不想使用他的库,而是想在.NET中实现加密。对我来说,我的代码不起作用,我看到了。我以为钥匙串有问题。我没有复制错误的数据。我让ujst剪切包含------开始公钥------和------结束公钥------的原始字符串。在我的项目中,我需要加密一个密码,以便在打开AM时使用SSO lgin。实际上,它已经与这个公钥一起使用,密码是用JSENCRYPT.JS加密的。没有问题。这就是为什么我在c语言开发中遇到问题的原因,目前我将尝试生成另一个公钥并测试其中的内容--BEGIN public key--大于模数值。它是(对于RSA)序列(序列(OID:RSA加密,NULL)、位字符串(序列(整数:模,整数:指数))的DER编码blob;你只需要模量部分。没有办法打开这个结构,从盒子里拿出你想要的.NET。如果您需要一次性回答,
openssl rsa-pubin-in pubkey.pem-text-noout
并刮取模数和指数十六进制值。谢谢,这对我来说更好我明白:)