简体   繁体   中英

RSA key pair generator applet, generate fixed almost zero private and public keys

I wrote the below JavaCard applet to generate 512 bit RSA public and private key pairs on the card and transfer them through the APDU responses to the outside:

public class CryptoRSA extends Applet {

    //Abbreviations
    private static final boolean NO_EXTERNAL_ACCESS = false;

    //arrays for generated keys in byte. (I know that 64 byte is enough)
    byte[] publicKey = new byte[128];
    byte[] privateKey = new byte[128];

    //Switch case parameters for selecting instruction =  INS in apdu command
    private static final byte GENERATE_KEY_PAIR = (byte) 0xC0;

    //Create object of keys
    RSAPrivateKey thePrivateKey = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_512, NO_EXTERNAL_ACCESS);
    RSAPublicKey thePublickKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_512, NO_EXTERNAL_ACCESS);
    KeyPair theKeyPair = new KeyPair(thePublickKey, thePrivateKey);

    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new CryptoRSA();
    }

    protected CryptoRSA() {
        register();
    }

    public void process(APDU apdu) {
        if (selectingApplet()) {
            return;
        }

        byte[] buffer = apdu.getBuffer();
        short privateKeySize = 0;
        short publicKeySize = 0;
        byte[] publicArray;
        byte[] privateArray;
        try {
            switch (buffer[ISO7816.OFFSET_INS]) {

                case GENERATE_KEY_PAIR:

                    theKeyPair.genKeyPair();

                    PrivateKey thePrivateKey = theKeyPair.getPrivate();
                    PublicKey thePublicKey = theKeyPair.getPublic();

                    publicKeySize = thePublicKey.getSize();
                    privateKeySize = thePrivateKey.getSize();

             //In the first program I used the followin transient arrays,
             //... and output was zero always. As I was thought
             //... that the origin of my problem is these transient arrays,
             //... (I think we cannot copy transient array to APDU buffer, Am I right?)
             //... I use above global arrays, but the problem remained
             //... as the first program.  

             //       byte[] publicKey = JCSystem.makeTransientByteArray((short) (publicKeySize / 8), JCSystem.CLEAR_ON_DESELECT);
             //       byte[] privateKey = JCSystem.makeTransientByteArray((short) (privateKeySize / 8), JCSystem.CLEAR_ON_DESELECT);

                    ((RSAPublicKey) thePublicKey).getExponent(publicKey, (short) 0);
                    ((RSAPrivateKey) thePrivateKey).getExponent(privateKey, (short) 0);


                    Util.arrayCopyNonAtomic(publicKey, (short) 0, buffer, (short) 0, (short) (publicKeySize / 8));
                    Util.arrayCopyNonAtomic(privateKey, (short) 0, buffer, (short) publicKeySize, (short) (privateKeySize / 8));
                    apdu.setOutgoingAndSend((short) 0, (short) ((short)(publicKeySize+privateKeySize) / 8));
                    break;

                default:
                    ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            }
        } catch (CryptoException e) {
            short r = e.getReason();
            ISOException.throwIt(r);
        }
    }

}

The problem is that the output is fixed and is almost zero always :

OpenSC:: opensc-tool.exe -s 00a40400060102030405DD -s 00c00000
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 DD
Received (SW1=0x90, SW2=0x00)
Sending: 00 C0 00 00
Received (SW1=0x90, SW2=0x00):
01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

OpenSC:: opensc-tool.exe -s 00a40400060102030405DD -s 00c00000
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 01 02 03 04 05 DD
Received (SW1=0x90, SW2=0x00)
Sending: 00 C0 00 00
Received (SW1=0x90, SW2=0x00):
01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

What's wrong?

Thanks in advance.

As you may notice, the returned values are not all zeros. The first 3 bytes of the response contains the exponent. What's wrong is your usage of getSize() method. This method actually returns the key size KeyBuilder.LENGTH_RSA_512 and not the size of the key component. The size of the exponent is the returned value of getExponent() method.

You can retrieve the length of the public exponent by doing this:

publicKeySize = ((RSAPublicKey) thePublicKey).getExponent(publicKey, (short) 0);

You can do the same with the private exponent.

FYI, an RSA exponent = '01 00 01' is very common so I am confident that it was the generated exponent of your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM