1

i got problem Encrypting a string using RSA. my RSA is in XML format, it looks like that:

<RSAKeyValue><Modulus>lT8ykfyV0R8o3mJZZezLKTKJpYB90Pzvp0moLzh9CTGfgsxLKYiAl+YGaoRfQ7hVQos5UlLIONHWKPNco9kKcmL6EBJvFc8wqBnhX0p4ML2WSv1yDIRsm9XXra82WHIa3+fxK8bNUJHrucxmpr9pDRPdZGZkz+Q9s94FcOyFKbs=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

and i'm trying to encrypt a string using this class:

import java.io.BufferedReader;
import java.io.StringReader;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.Security;
import javax.crypto.Cipher;
import org.bouncycastle.openssl.PEMReader;
import android.util.Base64;
import android.util.Log;

public class RsaEncryption {

private String publicKey;

public RsaEncryption(String publicKey)
{
    this.publicKey = publicKey;

}


/*
 * Function to encrypt the data.
 *
 */

public String encrypt( String data ) throws Exception
{



    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");


    byte[] keyBytes =   Base64.decode( this.publicKey, 0 );

    PublicKey publickey       = strToPublicKey(new String(keyBytes));
    cipher.init( Cipher.ENCRYPT_MODE , publickey );

    // Base 64 encode the encrypted data
    byte[] encryptedBytes = Base64.encode( cipher.doFinal(data.getBytes()), 0 );

    return new String(encryptedBytes);


}


public static PublicKey strToPublicKey(String s)
{

    PublicKey pbKey = null;
    try {

        BufferedReader br   = new BufferedReader( new StringReader(s) );
        PEMReader pr        = new PEMReader(br);
        Object obj = pr.readObject();

        if( obj instanceof PublicKey )
        {
            pbKey = (PublicKey) pr.readObject();
        }
        else if( obj instanceof KeyPair )
        {
            KeyPair kp = (KeyPair) pr.readObject();
            pbKey = kp.getPublic();
        }
        pr.close();

    }
    catch( Exception e )
    {
        Log.d("CIPHER", e.getMessage() );
    }

    return pbKey;
}

}

as you can see i'm using bouncycastle's jar the error that i get is: java.security.InvalidKeyException: unknown key type passed to RSA

I'm not sure about this part

Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");

maybe this is the problem? if it is, what need to be there instead?

i did hours of research and still didn't find a solution...

Thanks in advance :)

Tomer Ofer
  • 378
  • 3
  • 15

2 Answers2

2
Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");

maybe this is the problem?

No it's not.

OAEPWith<digest>And<mgf>Padding

Means Optimal Asymmetric Encryption Padding scheme defined in PKCS1, where <digest> should be replaced by the message digest algorithm and <mgf> by the mask generation function. Examples: OAEPWithMD5AndMGF1Padding and OAEPWithSHA-512AndMGF1Padding.

Reference Standard Names and RFC 4055.

The problem is in your Public Key generation. As your key is in XML, and Base64 encoded:

  • First you need to separate modulus and exponent.
  • Then Base64 decode both modulus and exponent.

After decoding you will get the byte array of modulus and exponent, so you can easily prepare public key object like the following procedure:

BigInteger modBigInteger = new BigInteger(1, modulus);//modulus must be byte array
BigInteger exBigInteger = new BigInteger(1, exponent);//exp must be byte array

RSAPublicKeySpec spec = new RSAPublicKeySpec(modBigInteger, exBigInteger);
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey publicKey = factory.generatePublic(spec);
mazhar islam
  • 5,561
  • 3
  • 20
  • 41
  • Thank you, but now i got other problem wen i'm using your method **java.lang.NumberFormatException: Invalid int: "pD"** – Tomer Ofer Jul 22 '15 at 08:44
  • The modulus and exponent are Base64 encoded, you need to decode them first. Please take a look, when I decode your exponent `AQAB` I got hex `010001` which is `65537` generally used as public exponent. – mazhar islam Jul 22 '15 at 08:46
  • that's what i get wen i'm trying to base64 decode it: Exponent﹕ �� it won't give me a number – Tomer Ofer Jul 22 '15 at 08:56
  • @TomerOfer, that means your decoding procedure fails, [decode here](http://tomeko.net/online_tools/base64.php?lang=en) to see the results. – mazhar islam Jul 22 '15 at 08:58
  • @TomerOfer, after base64 decoding you may get the `byte array` instead of _hex string_, so you can use them directly. See my edited answer. – mazhar islam Jul 22 '15 at 09:39
  • ok, now it seems to be working, now i got this error wen i do cipher.doFinal() **W/System.err﹕ com.android.org.bouncycastle.crypto.DataLengthException: input too large for RSA cipher.** – Tomer Ofer Jul 22 '15 at 09:56
  • @TomerOfer, I mentioned some reference which you need to study. If you don't know what padding, block size etc means then you will get so many errors and can not fix them by yourself. Best of luck, although its good to know that the problem you asked in this question is solved now. – mazhar islam Jul 22 '15 at 10:00
  • OK, Thank you very much! :) – Tomer Ofer Jul 22 '15 at 10:08
  • @TomerOfer, I edited my answer, `BigInteger(int signum, byte[] magnitude)`. Now check again. – mazhar islam Jul 22 '15 at 10:18
  • YaY! now it's working! but why? what is it the signum? – Tomer Ofer Jul 22 '15 at 12:18
  • It is sign-magnitude representation. The sign is represented as an integer `signum` value: `-1` for negative, `0` for zero, or `1` for positive. Read more [here](http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#BigInteger(int,%20byte[])). And don't forget to accept the answer it it worked! – mazhar islam Jul 22 '15 at 12:22
1

XML is not PEM.

You need to extract the modulus and the public exponent from the XML and then generate a key using an "RSA" KeyFactory instance and a RSAPublicKeySpec.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thanks, now i'm trying to use the Modulus and Exponent that i extracted from the XML, how do i do that? i did try what raked.void suggested but didn't succeed yet. – Tomer Ofer Jul 22 '15 at 08:46