2

I'm attempting to make an application that uses a modulus and exponent to generate a public key for RSA. However, there is the issue that the modulus and exponent are both possibly hex values. This is the code that I have for generating the key, the line marked with the -<--- is where the error is occuring.

RSAPublicKeySpec spec = new RSAPublicKeySpec(new BigInteger(1,hexToByte(rsaJSON.publickey_exp)),new BigInteger(1,hexToByte(rsaJSON.publickey_mod))); KeyFactory factory = KeyFactory.getInstance("RSA"); PublicKey pub = factory.generatePublic(spec); <--- Cipher cipher = cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC"); cipher.init(Cipher.ENCRYPT_MODE, pub); ..... String HEXES = "0123456789ABCDEF"; public static String byteToHex( byte [] raw ) { if ( raw == null ) { return null; } final StringBuilder hex = new StringBuilder( 2 * raw.length ); for ( final byte b : raw ) { hex.append(HEXES.charAt((b & 0xF0) >> 4)) .append(HEXES.charAt((b & 0x0F))); } return hex.toString(); } public static byte[] hexToByte( String hexString){ int len = hexString.length(); byte[] ba = new byte[len / 2]; for (int i = 0; i < len; i += 2) { ba[i/2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i+1), 16)); } return ba; } 

An example modulus and exponent that would be put into this are as follows:

modulus:"B31F9097CA38B4548D7300A0768F262C58D92B190355E382DACA4B79DA52226758FD8EB23CE29F404433411AC90308BEEED093BA157E03982E587496A15BB47A371C32C6B665FF75D6E900CF28CF679E871FB06FF0E90431E829DBE8EBDF7D5024A2D32F8B0D50C0D592E5D31046DE275F81B106088EBECA434493458DBF2B804BC46EC973E8F47408CC454F03F24933A5B100001B47239B44A52CF6A40670CED35060EB84BD6D0829DF8EC84EC49D784CA8583F353086071604DB2F43FA243A05F031033FFB179D8CB281A814B01F8CCC2EC29196BB136905104E23832FA923185743E18924C4E9772ED094D98643C677DE99EF1E598452728A7AC3DF5A1AB9" 

exponent:"010001"

The stack trace, for the most part:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: RSA keys must be at least 512 bits long at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(Unknown Source) at java.security.KeyFactory.generatePublic(Unknown Source) ..... 

I'm not going to pretend that I know why this error is happening because my knowledge with RSA encryption is somewhat limited. If anyone could help me figure out why this error keeps cropping up, it would be extremely helpful :)

3 Answers 3

4

According to http://docs.oracle.com/javase/7/docs/api/java/security/spec/RSAPublicKeySpec.html you swapped the arguments to the RSAPublicKeySpec constructor: The modulus goes first, the exponent second.

Also, don't implement the Hex -> BigInteger conversion yourself. Use new BigInteger( hexString, 16 ) (See this answer)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! I reversed the arguments and did the conversion the way you said and it worked :)
0

There isn't anything to "generate".

The (modulus, exponent) tuple is is the public key.

For example, I have a certificate for one of Google's web servers, and if I run openssl x509 -in certfile.pem -text, this is part of the output:

 Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:a7:4b:85:b2:80:e5:94:03:6f:ca:4a:e5:6c:a9: 71:80:a1:67:f7:b9:46:e8:26:b5:e9:bd:59:4f:7b: dd:1a:50:68:c7:3a:df:73:15:ce:a8:69:00:d4:27: 09:a9:cd:e1:d1:6e:2d:c6:a3:e9:3b:d6:aa:94:63: 83:1a:64:27:bf:fe:87:90:d4:e6:b8:e4:89:a8:76: 23:15:13:e0:27:6b:38:0a:fa:1f:b1:ec:71:0a:ec: 34:ff:0d:9c:1c:a7:d6:47:0f:ec:70:6c:2a:6b:89: 90:f5:de:58:e9:4e:ae:4d:6f:f0:f1:ca:7d:72:c0: 7a:79:94:28:fe:85:01:58:c9 Exponent: 65537 (0x10001) 

That's it. The RSA public key is the modulus and the exponent. I think you have what you need.

3 Comments

So then what causes the exception?
Poorly written APIs, for starters. ;-)
(Note, I wasn't trying to directly answer the question; rather, I was trying to address the OP's understanding of RSA public keys. On the other hand, the notion of "generating" a public key when you already have it seems counter-intuitive, and that's due to the API calls to create a public key object taking 3 lines of code instead of one.)
-1

May I help? I found the example and you answers told it is about the Interface RSAPublicKey. RSAPublicKey

Codes:

public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeySpecException { byte[] input = new byte[] { (byte)0xbe, (byte)0xef }; Cipher cipher = Cipher.getInstance("RSA"); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); SecureRandom random_1 = new SecureRandom(); KeyGenerator local_generator = KeyGenerator.getInstance("AES"); local_generator.init(256, random_1); SecretKey local_secretekey = local_generator.generateKey(); byte[] local_secrete_byte = local_secretekey.getEncoded(); StringBuilder local_target = new StringBuilder(); for ( Integer i = 0; i < local_secrete_byte.length; i = i + 1) { local_target.append( String.valueOf( String.valueOf( local_secrete_byte[i] ) ) ); } String local_target_key = Byte_to_Hex(local_secrete_byte); System.out.println("1. " + local_target_key); SecureRandom random_2 = new SecureRandom(); KeyGenerator generator = KeyGenerator.getInstance("AES"); generator.init(256, random_2); SecretKey secrete = generator.generateKey(); byte[] secrete_byte = secrete.getEncoded(); StringBuilder target = new StringBuilder(); for ( Integer i = 0; i < secrete_byte.length; i = i + 1) { target.append( String.valueOf( String.valueOf( secrete_byte[i] ) ) ); } String target_key = Byte_to_Hex(secrete_byte); System.out.println("2. " + target_key); // create the keys RSAPublicKeySpec thispubKeySpec = new RSAPublicKeySpec( new BigInteger(local_target_key, 16), new BigInteger("11", 16)); RSAPrivateKeySpec thisprivKeySpec = new RSAPrivateKeySpec( new BigInteger(local_target_key, 16), new BigInteger(target_key, 16)); System.out.println( "3. PubKeySpec Modulus: " + String.valueOf(thispubKeySpec.getModulus() ) ); System.out.println( "4. PubKeySpec PublicExponent: " + String.valueOf(thispubKeySpec.getPublicExponent() ) ); System.out.println( "5. PrivKeySpec Modulus: " + String.valueOf(thisprivKeySpec.getModulus() ) ); System.out.println( "6. PrivKeySpec PrivateExponent: " + String.valueOf(thisprivKeySpec.getPrivateExponent() ) ); RSAPublicKey pubKey = (RSAPublicKey)keyFactory.generatePublic(thispubKeySpec); RSAPrivateKey privKey = (RSAPrivateKey)keyFactory.generatePrivate(thisprivKeySpec); } 

Sample:

1. 29ffffff88ffffffc5ffffffab532b78ffffffae2c7e655cffffffc827ffffff98ffffffa2fffffff3affffff93ffffffb6fffffff215affffffe8ffffff8dffffffe6fffffff9ffffff93ffffff84ffffff832e12 2. ffffffdf5a6fffffffb039ffffff90ffffffcd57568fffffff66efffffff8ffffffbb215c13615e29fffffff64b2ffffffbfffffffe83bffffffdd5bffffffe8ffffffde1a7f 3. PubKeySpec Modulus: 823012395647503095848585629229488318125967956976077303153367268008550106317041442963571737703173703074958557361211053894437266913428830158109326184433594384517646730543359896256927103502344702260527967762 4. PubKeySpec PublicExponent: 17 5. PrivKeySpec Modulus: 823012395647503095848585629229488318125967956976077303153367268008550106317041442963571737703173703074958557361211053894437266913428830158109326184433594384517646730543359896256927103502344702260527967762 6. PrivKeySpec PrivateExponent: 3773962396135053605043641120341188078791329268791861200186343972537554558744515494911672553538182853867677334755781969985158396166815578794979135230532051607332765702783 

1 Comment

He doesn't want to generate keys. He wants to load existing keys, Please read the question thoroughly before answering.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.