3

Java Card (JCOP 2.4.2) に ECDSA アルゴリズムを実装したいと考えています。これは私のソースコードです:

package hashPack;

import javacard.framework.*;
import javacard.security.*;
import javacardx.crypto.*;

public class MyECDSA extends Applet{

    private byte[] PLAINTEXT ;

    private ECPrivateKey            objECDSAPriKey=null;    // Object for ECDSA Private Key
    private ECPublicKey             objECDSAPubKey=null;    // Object for ECDSA Public Key
    private KeyPair                 objECDSAKeyPair=null;   // Object for ECDSA Key Pair
    private Signature               objECDSASign=null;      // Object for ECDSA Signature

    final static short  BAS     =  0;

    final static byte[] SecP192r1_P = {     // 24
        (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
        (byte)0xFE,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
        (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
    final static byte[] SecP192r1_A = {     // 24
        (byte)0xFC,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
        (byte)0xFE,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
        (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
    final static byte[] SecP192r1_B = {     // 24
      (byte)0xB1,(byte)0xB9,(byte)0x46,(byte)0xC1,(byte)0xEC,(byte)0xDE,(byte)0xB8,(byte)0xFE,
      (byte)0x49,(byte)0x30,(byte)0x24,(byte)0x72,(byte)0xAB,(byte)0xE9,(byte)0xA7,(byte)0x0F,
      (byte)0xE7,(byte)0x80,(byte)0x9C,(byte)0xE5,(byte)0x19,(byte)0x05,(byte)0x21,(byte)0x64};
    final static byte[] SecP192r1_S = {     // 20
      (byte)0xD5,(byte)0x96,(byte)0x21,(byte)0xE1,(byte)0xEA,(byte)0x20,(byte)0x81,(byte)0xD3,
      (byte)0x28,(byte)0x95,(byte)0x57,(byte)0xED,(byte)0x64,(byte)0x2F,(byte)0x42,(byte)0xC8,
      (byte)0x6F,(byte)0xAE,(byte)0x45,(byte)0x30};
    final static byte[] SecP192r1_G = {     // 25
      (byte)0x12,(byte)0x10,(byte)0xFF,(byte)0x82,(byte)0xFD,(byte)0x0A,(byte)0xFF,(byte)0xF4,
      (byte)0x00,(byte)0x88,(byte)0xA1,(byte)0x43,(byte)0xEB,(byte)0x20,(byte)0xBF,(byte)0x7C,
      (byte)0xF6,(byte)0x90,(byte)0x30,(byte)0xB0,(byte)0x0E,(byte)0xA8,(byte)0x8D,(byte)0x18,(byte)0x03};
    final static byte[] SecP192r1_N = {     // 24
      (byte)0x31,(byte)0x28,(byte)0xD2,(byte)0xB4,(byte)0xB1,(byte)0xC9,(byte)0x6B,(byte)0x14,
      (byte)0x36,(byte)0xF8,(byte)0xDE,(byte)0x99,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
      (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
    final static short  SecP192r1_H =  1;

    //======================================================================================
    public static void install(byte[] bArray, short bOffset, byte bLength){
        new MyECDSA(bArray, bOffset, bLength);
    }

    private MyECDSA(byte bArray[], short bOffset, byte bLength){    

        PLAINTEXT       = new byte[0x100] ;         // Data file

        Util.arrayFillNonAtomic(PLAINTEXT,  BAS, (short)0x100, (byte)0);

        register();
    }

    //======================================================================================
    public void process(APDU apdu){
        byte buf[] = apdu.getBuffer();

        switch(buf[1])
        {
            //--------------------------------------------------------
            case (byte)0xA4:                    break;  

            case (byte)0x46:

                // Create ECDSA Keys and Pair
             /*   try {
            // <<<<<<<<<<<<<<<< Here is the problem >>>>>>>>>>>>>>>>>
                    objECDSAPriKey = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE,      KeyBuilder.LENGTH_EC_FP_192, true);
                }
            catch(CryptoException c)
            {    
              short reason = c.getReason();   
              ISOException.throwIt(reason);       // for check
            }     // for check*/
                   // objECDSAPubKey = (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC,      KeyBuilder.LENGTH_EC_FP_192, true);

                    // set EC Domain Parameters
                    objECDSAPubKey.setFieldFP(SecP192r1_P, BAS, (short)24);
                    objECDSAPubKey.setA(SecP192r1_A, BAS, (short)24);
                    objECDSAPubKey.setB(SecP192r1_B, BAS, (short)24);
                    objECDSAPubKey.setG(SecP192r1_G, BAS, (short)25);
                    objECDSAPubKey.setK(SecP192r1_H);
                    objECDSAPubKey.setR(SecP192r1_N, BAS, (short)24);

                    objECDSAKeyPair = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_192);


                // On-Card Key Generation Process
                objECDSAKeyPair.genKeyPair();

                // Obtain Key References
                objECDSAPriKey = (ECPrivateKey)objECDSAKeyPair.getPrivate();
                objECDSAPubKey = (ECPublicKey)objECDSAKeyPair.getPublic();  

                // Create Signature Object
                objECDSASign = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);

            break;

            case (byte)0x2E:                        
                short       Le              = apdu.setOutgoing();   
                short   sSignLen=0 ;

                // Init with Private Key
                objECDSASign.init(objECDSAPriKey, Signature.MODE_SIGN);

                // Sign Data
                sSignLen = objECDSASign.sign(PLAINTEXT, BAS, Le, buf, BAS);

                apdu.setOutgoingLength(sSignLen);
                apdu.sendBytes(BAS, sSignLen);

            break;      
            //--------------------------------------------------------
            default:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }

        return; 
    }
}

このスクリプト スクリプト コードを使用して、このソース コードを実行しています。

#/term SCComm:2
/mode trace=on
/atr
/card
/select |ecdsa
/send 00A4040007D4106509900090
/send 0046000000
/send 002E00000A30313233343031323334

/send 0046000000プレーン テキスト メッセージに署名するように要求すると、応答コードが返されます6F00

これの何が問題なのかを調べるのを手伝ってくれませんか?

このアルゴリズムを JCOP カードに適切に実装するにはどうすればよいですか?

4

3 に答える 3

1

への呼び出しが失敗したことを示しているので、この呼び出しは理由コードをKeyBuilder.buildKey(...)スローすると想定します。コードでその例外を処理しないため、カードによってステータス ワードが返されます (通常、未処理の例外の場合に返されます)。CryptoExceptionNO_SUCH_ALGORITHM0x6F000x6F00

は、要求CryptoExceptionされたキー アルゴリズムがサポートされていないことを示します。次のパラメータを使用するため

KeyBuilder.buildKey(
    KeyBuilder.TYPE_EC_FP_PRIVATE,  // key type
    KeyBuilder.LENGTH_EC_FP_192,    // key length
    true);                          // key encryption

これは次のことを意味する可能性があります

  • カードが EC_FP (大きな素体上の楕円曲線) のキー タイプ/アルゴリズムをサポートしていない。
  • カードが 192 のキーの長さをサポートしていない、または
  • カードはキーの暗号化をサポートしていません。

JCOP 2.4.2 R2JCOP 2.4.2 R3の両方の FIPS 140-2 暗号化モジュール セキュリティ ポリシーは、ECDSA 鍵ペアの生成が P-192 (P-224 と P-256 に加えて) でサポートされていることを示しているので、私はそれを想定します。お使いのカードはキーの暗号化をサポートしていません。したがって、代わりに試すことができます

KeyBuilder.buildKey(
    KeyBuilder.TYPE_EC_FP_PRIVATE,  // key type
    KeyBuilder.LENGTH_EC_FP_192,    // key length
    false);                         // key encryption
于 2016-01-28T18:53:51.323 に答える