1

I have a problem to set modulus parameter in RSAParameter. I convert my public key string in byte array and my problem is that the lenght is too long.

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

The problim is that my key size is 1296 and not 1024. I have tested with XMLParameter string but I have the same problem.

I need help. Thanks per advance

Christophe
  • 71
  • 1
  • 1
  • 6

4 Answers4

2

This is ce solution get to modulus in public key of DER-encoded 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();
    }

Thank you for your help

Christophe
  • 71
  • 1
  • 1
  • 6
0

I don't really understand if you are saying there is something wrong with the original public key or you think it is correct and your code is not working. I use the following (BouncyCastle library) for encryption:

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
    }
}

And if you need to call it with a byte array for the key:

public string PublicKeyEncrypt(string plaintext, byte[] publickey)
{
    return PublicKeyEncrypt(plaintext, new MemoryStream(publickey, false));
}
Lukos
  • 1,826
  • 1
  • 15
  • 29
  • Normally, the public key is good, because with library javascript the public key work (https://github.com/travist/jsencrypt). I would like don't use his library but realise the encryption in .NET. For me it's my code doesn't work. – Christophe Jun 30 '16 at 12:41
0

Your string is 216 characters long, which means it represents 162 bytes. And 162 bytes is 1296 bits.

So the program seems to be doing exactly what you've told it to do (the length of modulus (in bits) is the RSA key size).

So the string you have there doesn't represent an RSA 1024-bit modulus value, you must have copied the wrong data values.

bartonjs
  • 30,352
  • 2
  • 71
  • 111
  • I had saw that. I supposed that there was a problem with the key string. I don't have copied the wrong data. I have ujst cut the original string who containt -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- – Christophe Jul 01 '16 at 14:19
  • In my project I need to encryption a password for to use an SSO lgin with Open AM. Actually it's already use with this public key and the password is encrypt with JSENCRYPT.JS. And there is no problem. This is reason that I have an issue with the development in c# – Christophe Jul 01 '16 at 14:24
  • For The moment I will try to generate another public key and test – Christophe Jul 01 '16 at 14:26
  • The contents inside -----BEGIN PUBLIC KEY----- are more than the modulus value. It is a DER-encoded blob of (for RSA) SEQUENCE(SEQUENCE(OID: rsaEncryption, NULL), BIT STRING(SEQUENCE(INTEGER: modulus, INTEGER: exponent))); and you need only the modulus part. There's no way to crack that structure open and get what you want with .NET out of the box. If you need a one-off answer, `openssl rsa -pubin -in pubkey.pem -text -noout` and scrape the modulus and exponent hex values. – bartonjs Jul 01 '16 at 15:25
  • Thank you, it's better for me I'm understand :) – Christophe Jul 05 '16 at 12:28
0

Your KeyString is a base64-encoded DER-encoded SubjectPublicKeyInfo object that does, in fact, contain a 1024-bit RSA modulus. To see for yourself you can use the lapo.it base64 ASN.1 decoder. Just copy and paste the base64 string in there and click on decode.

In Java, this format (without the base64 encoding) is returned by the PublicKey.getEncoded() method.

There are various answers on stackoverflow that attempt to deal with this question. In this answer the bouncycastle C# library is used, and the following C# fragment is supplied:

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 contains a longer sequence of code but avoids using the bouncycastle C# library.

I haven't tested either one of these.

Community
  • 1
  • 1
President James K. Polk
  • 40,516
  • 21
  • 95
  • 125