RSA密钥对生成器applet,生成固定的几乎为零的私钥和公钥

时间:2015-05-27 08:57:03

标签: java rsa javacard

我编写了下面的JavaCard小程序,在卡上生成512位RSA公钥和私钥对,并通过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 ................

怎么了?

提前致谢。

1 个答案:

答案 0 :(得分:2)

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

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

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

你可以对私人指数做同样的事情。

仅供参考,RSA指数=' 01 00 01'很常见,所以我相信它是代码的生成指数。