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

Robin Green
  • 32,079
  • 16
  • 104
  • 187
VoidWhisperer
  • 75
  • 1
  • 3
  • 14

3 Answers3

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)

Community
  • 1
  • 1
svckr
  • 791
  • 6
  • 11
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.

mpontillo
  • 13,559
  • 7
  • 62
  • 90
  • So then *what* causes the exception? – user2864740 Dec 09 '13 at 20:51
  • Poorly written APIs, for starters. ;-) – mpontillo Dec 09 '13 at 20:52
  • 1
    (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.) – mpontillo Dec 09 '13 at 21:03
-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
General Grievance
  • 4,555
  • 31
  • 31
  • 45
  • 2
    He doesn't want to generate keys. He wants to load existing keys, Please read the question thoroughly before answering. – user207421 Aug 25 '22 at 04:49