简体   繁体   English

RSA密钥对生成器小程序,生成几乎固定的零个私钥和公钥

[英]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: 我写了下面的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);
        }
    }

}

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. 响应的前3个字节包含指数。 What's wrong is your usage of getSize() method. 出问题的是您使用getSize()方法。 This method actually returns the key size KeyBuilder.LENGTH_RSA_512 and not the size of the key component. 此方法实际上返回密钥大小KeyBuilder.LENGTH_RSA_512而不是密钥组件的大小。 The size of the exponent is the returned value of getExponent() method. 指数的大小是getExponent()方法的返回值。

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. 仅供参考,RSA指数= '01 00 01'非常常见,因此我相信它是您的代码生成的指数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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