设置模数RSA参数来自字符串公钥

时间:2016-06-30 10:53:01

标签: c# rsa

我在RSAParameter中设置模数参数时遇到问题。 我在字节数组中转换我的公钥字符串,我的问题是长度太长。

 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字符串进行了测试,但我遇到了同样的问题。

我需要帮助。谢谢你提前

4 个答案:

答案 0 :(得分:0)

如果您说原始公钥有问题或者您认为它是正确的并且您的代码无效,我真的不明白。我使用以下(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));
}

答案 1 :(得分:0)

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

所以程序似乎完全按照你所说的去做(模数的长度(以位为单位)是RSA密钥大小)。

因此,您所拥有的字符串并不代表RSA 1024位模数值,您必须复制错误的数据值。

答案 2 :(得分:0)

您的KeyString是base64编码的DER编码SubjectPublicKeyInfo对象,实际上包含1024位RSA模数。要亲眼看看,您可以使用lapo.it base64 ASN.1 decoder。只需将base64字符串复制并粘贴到那里,然后单击“解码”。

在Java中,PublicKey.getEncoded()方法返回了这种格式(没有base64编码)。

stackoverflow上有各种答案试图处理这个问题。在this answer中使用了bouncycastle C# library,并提供了以下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);

This answer包含更长的代码序列,但避免使用bouncycastle C#库。

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

答案 3 :(得分:0)

这是解决方案获得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();
    }

感谢您的帮助