如何将RSApublic[/private]密钥传到卡外?

How to transfer RSA public[/private] key outside the card?

我写了下面的简单程序来生成一个RSA密钥对,并在APDU响应中将public密钥传输到卡外:

public class CryptoRSA extends Applet {

    //Abbreviations
    private static final boolean NO_EXTERNAL_ACCESS = false;

    //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 = thePrivateKey.getSize();
                    privateKeySize = thePrivateKey.getSize();

                    byte[] publicKey = JCSystem.makeTransientByteArray((short) (publicKeySize), JCSystem.CLEAR_ON_DESELECT);
                    ((RSAPublicKey) thePrivateKey).getExponent(publicKey, (short) publicKeySize);

                    Util.arrayCopyNonAtomic(publicKey, (short) 0, buffer, (short) 0, (short) (publicKeySize ));
                    apdu.setOutgoingAndSend((short) 0, (short) (publicKeySize));
                    break;

                default:
                    ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            }
        } catch (Exception e) {
            if (e instanceof CryptoException) {
                short r = ((CryptoException) e).getReason();
                ISOException.throwIt(r);
            } else {
                ISOException.throwIt((short) 0x8888);
            }
        }

    }
}

但是当我向卡发送相关的APDU命令时,我收到0x8888如下:

OSC:: 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=0x88, SW2=0x88)
  1. getSize() returns 密钥的位长,而不是字节长度。您可能 运行 内存不足。

2.((RSAPublicKey) thePrivateKey).getExponent(publicKey, (short) publicKeySize);

这行不通!您要求将指数存储在数组 publicKey 中的偏移量 publicKeySize 处——也就是说,在数组的最后,正好有 0 个字节可以存储它。

顺便说一下,下次遇到这样的问题可以使用ISOException向外界发送调试数据。例如,ISOException.throwIt(privateKeySize) 会找到问题 1。