RSA 密钥对生成器小程序,生成固定的几乎为零的私有和 public 密钥

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

我编写了下面的 JavaCard 小程序来生成 512 位 RSA public 和卡上的私钥对,并通过 APDU 响应将它们传输到外部:

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);
        }
    }

}

问题是输出是固定的,几乎总是为零:

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 ................

怎么了?

提前致谢。

您可能会注意到,返回值并非全为零。响应的前 3 个字节包含指数。问题出在您对 getSize() 方法的使用上。此方法实际上 returns 密钥大小 KeyBuilder.LENGTH_RSA_512 而不是密钥组件的大小。指数的大小是getExponent()方法的返回值。

您可以通过执行以下操作检索 public 指数的长度:

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

您可以对私有指数执行相同的操作。

仅供参考,RSA 指数 = '01 00 01' 很常见,因此我相信这是您的代码生成的指数。