2015-05-26 53 views
0

我寫了下面的簡單的程序來生成一個RSA密鑰對,並在APDU響應公共密鑰傳輸到卡外:如何在卡外部傳輸RSA公共[/私人]密鑰?

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) 

回答

3
  1. getSize()返回鍵,而不是字節長度的比特長度。你可能用完了RAM。

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

這樣可不行!您要求將指數存儲在數組publicKey的偏移量publicKeySize中 - 也就是說,在數組的最後一個存儲精確的0個字節的位置。

順便說一下,下次遇到這樣的問題時,您可以使用ISOException向外界發送調試數據。例如,ISOException.throwIt(privateKeySize)將發現問題1.