繁体   English   中英

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

[英]set modulus RSA Parameter from string public key

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

我需要帮助。 提前致谢

这是在 DER 编码 blob 的公钥中获取模数的 ce 解决方案。

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

谢谢你的帮助

我真的不明白您是说原始公钥有问题,还是您认为它是正确的并且您的代码不起作用。 我使用以下(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 位模数值,您一定复制了错误的数据值。

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

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

stackoverflow 上有各种试图解决这个问题的答案。 这个答案中使用bouncycastle C# 库,并提供了以下 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# 库。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM