Announce two new product: SmartCard Reader Rockey200 and USB2.0 Extension Cable

ROCKEY 200 is a handy and portable USB Smart Card reader that can perform read/write operations on any ISO 7816-1/2/3/4 smart cards which are compatible with protocol T=0 and T=1.

USB2.0 Extension Cable With high speed USB 2.0 devices such as USB token ,USB Card Reader and so on.

Come to try it now!

ECDSA signature

Algorithm School

Moderator: UNKNwYSHSA

mikegigom
Posts: 15
Joined: Fri Nov 27, 2015 1:38 am
Points: 101
Contact:

ECDSA signature

Postby mikegigom » Mon May 30, 2016 4:29 am

I have created an EC key pair and I tried to use the same data and EC private key to generate ECDSA signature. But I found that each signature is different from the previous one. Why the value is different? What can I do to make the signature same?

Code: Select all

Signature sig1 = Signature.getInstance(Signature.ALG_ECDSA_SHA, false);
     
sig1.init(myECPrivateKey);
     
short signatureLength = sig1.sign(inputData, (short) 0, inputDataLength, signatureBuffer, (short) 0);

sendManyBytes(apdu, signatureBuffer, (short) 0, signatureLength);


Usiger
Posts: 14
Joined: Tue Mar 01, 2016 3:56 am
Points: 147
Contact:

Re: ECDSA signature

Postby Usiger » Mon May 30, 2016 5:26 am

There is a step in the process of generating ECDSA signature - generate a random number, which causes different results.

mikegigom
Posts: 15
Joined: Fri Nov 27, 2015 1:38 am
Points: 101
Contact:

Re: ECDSA signature

Postby mikegigom » Tue May 31, 2016 5:42 am

Usiger wrote:There is a step in the process of generating ECDSA signature - generate a random number, which causes different results.


Is there anyway to use the same random number so that I can get the same ECDSA signature?

corleoner
Posts: 15
Joined: Fri Dec 11, 2015 2:22 am
Points: 90
Contact:

Re: ECDSA signature

Postby corleoner » Tue May 31, 2016 11:23 pm

If you use the same random data, there will be security issue. I mean, this method is NOT secure.

ThanhLong
Posts: 1
Joined: Tue Dec 19, 2017 5:05 am
Points: 10
Contact:

Re: ECDSA signature

Postby ThanhLong » Tue Dec 19, 2017 5:21 am

I use ECDSA_SHA256 with sec256p-r1 domain parameter to sign, verify => Verify is OK
and then verify again on https://javacardos.com/tools/ecdsa_sign_verify.html with the same private, public, (r,s)
But the result is invalid.
I don't know why.
I use Java 3.0.5
My applet as follow :

Code: Select all

/**
 *
 */
package com.mksmart.ECDSAproject;

import javacard.framework.*;
import javacard.security.CryptoException;
import javacard.security.ECKey;
import javacard.security.ECPrivateKey;
import javacard.security.ECPublicKey;
import javacard.security.KeyBuilder;
import javacard.security.KeyPair;
import javacard.security.MessageDigest;
import javacard.security.RandomData;
import javacard.security.Signature;
import javacardx.annotations.*;
import javacardx.crypto.Cipher;

/**
 * Applet class
 *
 * @author <user>
 */
@StringPool(value = {
       @StringDef(name = "Package", value = "com.mksmart.ECDSAproject"),
       @StringDef(name = "AppletName", value = "ECDSAapplet")},
       // Insert your strings here
   name = "ECDSAappletStrings")
public class ECDSAapplet extends Applet {
   
   final static byte[] SecP256r1_P = {
      (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,
      (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,
      (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(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[] SecP256r1_A = {
      (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x01,
      (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,
      (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
      (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFC};
   
   final static byte[] SecP256r1_B = {
      (byte)0x5A,(byte)0xC6,(byte)0x35,(byte)0xD8,(byte)0xAA,(byte)0x3A,(byte)0x93,(byte)0xE7,
      (byte)0xB3,(byte)0xEB,(byte)0xBD,(byte)0x55,(byte)0x76,(byte)0x98,(byte)0x86,(byte)0xBC,
      (byte)0x65,(byte)0x1D,(byte)0x06,(byte)0xB0,(byte)0xCC,(byte)0x53,(byte)0xB0,(byte)0xF6,
      (byte)0x3B,(byte)0xCE,(byte)0x3C,(byte)0x3E,(byte)0x27,(byte)0xD2,(byte)0x60,(byte)0x4B};
   
   final static byte[] SecP256r1_S = {
      (byte)0xC4,(byte)0x9D,(byte)0x36,(byte)0x08,(byte)0x86,(byte)0xE7,(byte)0x04,(byte)0x93,
      (byte)0x6A,(byte)0x66,(byte)0x78,(byte)0xE1,(byte)0x13,(byte)0x9D,(byte)0x26,(byte)0xB7,
      (byte)0x81,(byte)0x9F,(byte)0x7E,(byte)0x90};
   
   // Uncompress form
   final static byte[] SecP256r1_G = {
      (byte)0x04,(byte)0x6B,(byte)0x17,(byte)0xD1,(byte)0xF2,(byte)0xE1,(byte)0x2C,(byte)0x42,(byte)0x47,
      (byte)0xF8,(byte)0xBC,(byte)0xE6,(byte)0xE5,(byte)0x63,(byte)0xA4,(byte)0x40,(byte)0xF2,
      (byte)0x77,(byte)0x03,(byte)0x7D,(byte)0x81,(byte)0x2D,(byte)0xEB,(byte)0x33,(byte)0xA0,
      (byte)0xF4,(byte)0xA1,(byte)0x39,(byte)0x45,(byte)0xD8,(byte)0x98,(byte)0xC2,(byte)0x96,
      (byte)0x4F,(byte)0xE3,(byte)0x42,(byte)0xE2,(byte)0xFE,(byte)0x1A,(byte)0x7F,(byte)0x9B,
        (byte)0x8E,(byte)0xE7,(byte)0xEB,(byte)0x4A,(byte)0x7C,(byte)0x0F,(byte)0x9E,(byte)0x16,
        (byte)0x2B,(byte)0xCE,(byte)0x33,(byte)0x57,(byte)0x6B,(byte)0x31,(byte)0x5E,(byte)0xCE,
        (byte)0xCB,(byte)0xB6,(byte)0x40,(byte)0x68,(byte)0x37,(byte)0xBF,(byte)0x51,(byte)0xF5};
   
   final static byte[] SecP256r1_N = {
      (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,
      (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
      (byte)0xBC,(byte)0xE6,(byte)0xFA,(byte)0xAD,(byte)0xA7,(byte)0x17,(byte)0x9E,(byte)0x84,
      (byte)0xF3,(byte)0xB9,(byte)0xCA,(byte)0xC2,(byte)0xFC,(byte)0x63,(byte)0x25,(byte)0x51};
   
   final static short  SecP256r1_H =  1;
   
   private byte[]                PLAINTEXT;
   private ECPrivateKey         objECDSAPriKey         = null;
   private ECPublicKey            objECDSAPubKey         = null;
   private KeyPair               objECDSAKeyPair         = null;
   private Signature            objECDSASign            = null;
   private ECKey               objECKey            = null;
   private short               objECDSAPubKeyLen;
   private short               objECDSAPriKeyLen;
   
   private byte[]               TEMP_ARR;
   private static short         TEMP_ARR_LEN         = (short)256;
   
   private final static byte      ECDSA_GEN_KEY_PAIR      = (byte)0x46;
   private final static byte      ECDSA_GET_PUBLIC_KEY   = (byte)0x47;
   private final static byte      ECDSA_GET_PRIVATE_KEY   = (byte)0x48;
   private final static byte      ECDSA_SIGN            = (byte)0x49;
   private final static byte      ECDSA_VERIFY         = (byte)0x4A;
   private final static byte      ECDSA_SET_PRIVATE_KEY   = (byte)0x4B;
   private final static byte      ECDSA_SET_PUBLIC_KEY   = (byte)0x4C;
   
    /**
     * Installs this applet.
     *
     * @param bArray
     *            the array containing installation parameters
     * @param bOffset
     *            the starting offset in bArray
     * @param bLength
     *            the length in bytes of the parameter data in bArray
     */
    public static void install(byte[] bArray, short bOffset, byte bLength) {
        new ECDSAapplet().register();
    }

    /**
     * Only this class's install method should create the applet object.
     */
    public ECDSAapplet() {
       PLAINTEXT   = JCSystem.makeTransientByteArray((short)0x100, JCSystem.CLEAR_ON_DESELECT);
        TEMP_ARR    = JCSystem.makeTransientByteArray(TEMP_ARR_LEN, JCSystem.CLEAR_ON_DESELECT);
    }

    /**
     * Processes an incoming APDU.
     *
     * @see APDU
     * @param apdu
     *            the incoming APDU
     */
    @Override
    public void process(APDU apdu) {
        //Insert your code here
       
       byte[] buf = apdu.getBuffer();
//       ISOException.throwIt((short)0x9FAA);
       if ((buf[ISO7816.OFFSET_CLA] == 0) &&
                (buf[ISO7816.OFFSET_INS] == (byte) (0xA4))) {
            return;
        }
       switch(buf[ISO7816.OFFSET_INS]){
       case (byte)0xA4:{
          ISOException.throwIt((short)0x9FAA);
          break;
       }
       // Generate Key pair
       case (byte)ECDSA_GEN_KEY_PAIR:{   
          apdu.setIncomingAndReceive();
          ECDSAGenKeyPair(apdu, buf);
          break;
       }
       // Get Public Key
       case (byte)ECDSA_GET_PUBLIC_KEY:{
          ECDSAGetPubKey(apdu, buf);
          break;
       }   
       // Get Private Key
       case (byte)ECDSA_GET_PRIVATE_KEY:{
          ECDSAGetPriKey(apdu, buf);
          break;
       }
       // Signature
       case (byte)ECDSA_SIGN:{
          PLAINTEXT[0] = (byte)0x61;
          apdu.setIncomingAndReceive();
          ECDSASignature(apdu,buf,buf,ISO7816.OFFSET_CDATA,apdu.getIncomingLength());
          break;
       }
       // Verify
       case (byte)ECDSA_VERIFY:{
          PLAINTEXT[0] = (byte)0x61;
          apdu.setIncomingAndReceive();
          short DataLen = buf[ISO7816.OFFSET_LC];
          ECDSAVerify(apdu,buf,buf,(short)(ISO7816.OFFSET_CDATA + apdu.getIncomingLength() - 1),(short)1);
          break;
       }
       
       // Set Private key
       case ECDSA_SET_PRIVATE_KEY:{
          apdu.setIncomingAndReceive();
          ECDSASetPrivKey(buf);
          break;
       }
       
       // Set Public key
       case ECDSA_SET_PUBLIC_KEY:{
          apdu.setIncomingAndReceive();
          ECDSASetPubKey(buf);
          
          break;
       }
       default :{
          ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
          break;
       }
       }
    } 
    private void ECDSAGenKeyPair(APDU apdu,byte[] buf){
       try{
          if (objECDSAPriKey != null){
              objECDSAPriKey.clearKey();
              objECDSAPubKey.clearKey();
          }
         objECDSAPriKey = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE, KeyBuilder.LENGTH_EC_FP_256, false);
         objECDSAPubKey = (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, KeyBuilder.LENGTH_EC_FP_256, false);      
         objECDSASign = Signature.getInstance(Signature.ALG_ECDSA_SHA_256, false);
         
         objECDSASign = Signature.getInstance(MessageDigest.ALG_SHA_256, Signature.SIG_CIPHER_ECDSA, Cipher.PAD_NULL, false);               
         objECDSAPubKey.setFieldFP(SecP256r1_P, (short)0, (short)SecP256r1_P.length);
         objECDSAPubKey.setA(SecP256r1_A, (short)0, (short)ECDSADomainParameter.SecP256r1_A.length);
         objECDSAPubKey.setB(SecP256r1_B, (short)0, (short)SecP256r1_B.length);
         objECDSAPubKey.setG(SecP256r1_G, (short)0, (short)SecP256r1_G.length);
         objECDSAPubKey.setR(SecP256r1_N, (short)0, (short)SecP256r1_N.length);
         objECDSAPubKey.setK(SecP256r1_H);
         
         objECDSAPriKey.setFieldFP(SecP256r1_P, (short)0, (short)ECDSADomainParameter.SecP256r1_P.length);
         objECDSAPriKey.setA(SecP256r1_A, (short)0, (short)SecP256r1_A.length);
         objECDSAPriKey.setB(SecP256r1_B, (short)0, (short)SecP256r1_B.length);
         objECDSAPriKey.setG(SecP256r1_G, (short)0, (short)SecP256r1_G.length);
         objECDSAPriKey.setR(SecP256r1_N, (short)0, (short)SecP256r1_N.length);
         objECDSAPriKey.setK(SecP256r1_H);      
         
         objECDSAKeyPair = new KeyPair(objECDSAPubKey,objECDSAPriKey);
         objECDSAKeyPair.genKeyPair();
      }
      catch(CryptoException ex){
         short reason = ex.getReason();
         ISOException.throwIt(reason);             
      }
      ISOException.throwIt(ISO7816.SW_NO_ERROR);
    }
   
    private void ECDSAGetPubKey(APDU apdu,byte[] buf){
       try{
          objECDSAPubKey = (ECPublicKey)objECDSAKeyPair.getPublic();   
          objECDSAPubKeyLen = objECDSAPubKey.getW(buf, ISO7816.OFFSET_CDATA);
       }
      catch(CryptoException ex){
         ISOException.throwIt(ex.getReason());
      }
      apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA,objECDSAPubKeyLen);
    }
   
    private void ECDSAGetPriKey(APDU apdu,byte[] buf){
       try{
          objECDSAPriKey = (ECPrivateKey)objECDSAKeyPair.getPrivate();
           objECDSAPriKeyLen = objECDSAPriKey.getS(buf, ISO7816.OFFSET_CDATA);
       }
       catch(CryptoException ex){
          ISOException.throwIt(ex.getReason());
       }
       apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA,objECDSAPriKeyLen);
    }
   
    private void ECDSAVerify(APDU apdu,byte[] buf,byte[] PlainText,short PlainTextOffset,short PlainTextLen){
      short Signlen = buf[ISO7816.OFFSET_LC];
      boolean VerifyResult=false;
      objECDSASign.init(objECDSAPubKey, Signature.MODE_VERIFY);
      VerifyResult = objECDSASign.verify(PlainText,PlainTextOffset, PlainTextLen, buf, ISO7816.OFFSET_CDATA ,Signlen);
      if (VerifyResult){
         ISOException.throwIt(ISO7816.SW_NO_ERROR);
      }
      else{
         ISOException.throwIt(ISO7816.SW_DATA_INVALID);
      }
    }
   
    private void ECDSASignature(APDU apdu,byte[] buf,byte[] PlainText,short PlainTextOffset,short PlainTextLen){
      short sSignLen=0;   
      byte result=0;
      try{
         objECDSASign.init(objECDSAPriKey, Signature.MODE_SIGN);
         sSignLen = objECDSASign.sign(PlainText, PlainTextOffset,PlainTextLen, buf, ISO7816.OFFSET_CDATA);
      }
      catch(CryptoException ex){
         ISOException.throwIt(ex.getReason());
      }
      apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, sSignLen);
    }
   
    private void ECDSASetPrivKey(byte[] buf){
       objECDSAPriKey.setS(buf, ISO7816.OFFSET_CDATA, buf[ISO7816.OFFSET_LC]);
    }
   
    private void ECDSASetPubKey(byte[] buf){
       objECDSAPubKey.setW(buf, ISO7816.OFFSET_CDATA, buf[ISO7816.OFFSET_LC]);
    }
       
}


Return to “Algorithm School”

Who is online

Users browsing this forum: No registered users and 1 guest

JavaCard OS : Disclaimer