user2642459
user2642459

Reputation: 507

Generating RSA key with public exponent other than 65537 (0x10001 in hex)

I'm implementing a java card applet for 2048-bit RSA. I want to know how to create RSA key pair with a public exponent(e) other than 65537.

The card generates RSA key pair, and return its public exponent(e) and modulus(n). But the public exponent is 65537(0x10001 in hex) every time. My code is as follows

// Initialize objects for RSA Keys and Pair
objRSAPriKey = (RSAPrivateCrtKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_CRT_PRIVATE, KeyBuilder.LENGTH_RSA_2048, false);
objRSAPubKey = (RSAPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC,  KeyBuilder.LENGTH_RSA_2048, false);
objRSAKeyPair= new KeyPair(KeyPair.ALG_RSA_CRT, KeyBuilder.LENGTH_RSA_2048);

    ...

// Generate Key Pairs    
objRSAKeyPair.genKeyPair();

objRSAPriKey = (RSAPrivateCrtKey)objRSAKeyPair.getPrivate();
objRSAPubKey = (RSAPublicKey)objRSAKeyPair.getPublic();

GetResLen = objRSAPubKey.getModulus(Rb_GetRes, BAS);
GetResLen += objRSAPubKey.getExponent(Rb_GetRes, GetResLen);

Of course, I know that these keys is different, because the other values of key (n, d, p, q) are different every time the applet generates key. But I want to know how to generate RSA key pair with public exponent of 2048-bit size

Thanks.

Upvotes: 1

Views: 3281

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 94038

Usually key pair generation is restricted to certain values on Java Card by the platform implementation. This is certainly the case for the public key exponent.

Currently you are building a public and private key pair, just to overwrite the references to them with the ones generated by the genKeyPair. Instead you could just build the key pair like this:

objRSAPriKey = (RSAPrivateCrtKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_CRT_PRIVATE, KeyBuilder.LENGTH_RSA_2048, false);
objRSAPubKey = (RSAPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC,  KeyBuilder.LENGTH_RSA_2048, false);
objRSAPubKey.setExponent(myLargeExponent, 0, (short) myLargeExponent.length);
objRSAKeyPair= new KeyPair(objRSAPubKey, objRSAPriKey);
objRSAKeyPair.genKeyPair();

This will generate a public key with a static exponent of any value if supported by the platform. If it isn't supported, try with a RSAPrivateKey instead of one that uses CRT parameters as well. Now if you want to have a random public exponent, you can use a trick:

randomExponentRSAKeyPair = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048);
randomExponentRSAKeyPair.genKeyPair();
byte[] myLargeExponent = new byte[KeyBuilder.LENGTH_RSA_2048 / 8];
RSAPrivateKey tmpKey = (RSAPrivateKey)randomRSAKeyPair.getPrivate();
key.getExponent(myLargeExponent, (short) 0);

If this code runs you've created a horribly slow public key, that has no advantages over one with the other public key and which should not be used instead of a private key.

Note: the Java Card code above does not adhere to Java Card best practices, demonstration code only.

Upvotes: 2

Related Questions