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

问题描述 投票:0回答:4

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

我需要帮助。谢谢你的提前

c# rsa
4个回答
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));
}

0
投票

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

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

因此,您在那里的字符串不代表RSA 1024位模数值,您必须复制错误的数据值。


0
投票

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

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

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#库。

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


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();
    }

谢谢您的帮助

© www.soinside.com 2019 - 2024. All rights reserved.