1 Reply Latest reply: Sep 20, 2012 5:42 AM by 956606 RSS

    CryptoException NO_SUCH_ALGORITHM with KeyPair.ALG_RSA on simulator

    956606
      Hi guys,

      I'm getting CryptoException - NO_SUCH_ALGORITHM when run the following code.

      I've used NetBeans 7.0.2.

      I tested it on JavaCard 3.0.2 Connected Edition with KeyPair.ALG_RSA
      and
      with jCardSim emulator after changing to ALG_RSA_CRT .

      In both cases got 0x00 0x03 CryptoException - NO_SUCH_ALGORITHM .

      ===============INS.java========
      /*
      * To change this template, choose Tools | Templates
      * and open the template in the editor.
      */
      package wallet;

      /**
      *
      * @author rbondar
      */
      public class INS {
      // code of CLA byte in the command APDU header
      public final static byte CLA_WALLET = (byte) 0x88;

      //instructions
      public final static byte INS_SRV_SET_EXPONENT_MODULUS_PUBLIC_KEY_DEFAULT = (byte) 0x20;
      public final static byte INS_SRV_SET_PUBLIC_EXPONENT = (byte) 0x21;
      public final static byte INS_SRV_SET_PUBLIC_MODULUS = (byte) 0x22;
      public final static byte INS_SRV_RESTORE_PUBLIC_KEY = (byte) 0x23;

      public final static byte INS_APPLET_GENERATE_KEYS = (byte) 0x30;
      public final static byte INS_APPLET_GET_PUBLIC_EXPONENT = (byte) 0x31;
      public final static byte INS_APPLET_GET_PUBLIC_MODULUS = (byte) 0x32;

      public final static byte INS_TEST_GET_FLAGS = (byte) 0x41;

      }

      =============Wallet.java========
      /*
      * To change this template, choose Tools | Templates
      * and open the template in the editor.
      */

      package wallet;

      import javacard.framework.*;
      import javacard.security.CryptoException;
      import javacard.security.KeyBuilder;
      import javacard.security.KeyPair;
      import javacard.security.RSAPrivateCrtKey;
      import javacard.security.RSAPublicKey;
      import javacardx.crypto.Cipher;
      import wallet.INS;

      /**
      *
      * @author rbondar
      */
      public class Wallet extends Applet {

      /* constants declaration */

      //internal persistent checks
      byte FLAG_APPLET_GENERATED_KEYS = 0;
      byte FLAG_APPLET_EXTRACTED_PRIVATE_KEY = 0;
      byte FLAG_APPLET_EXTRACTED_PUBLIC_KEY = 0;
      byte FLAG_APPLET_EXTRACTED_EXPONENT = 0;
      byte FLAG_APPLET_EXTRACTED_MODULUS = 0;

      byte FLAG_SERVER_SET_PUBLIC_EXPONENT = 0;
      byte FLAG_SERVER_SET_PUBLIC_MODULUS = 0;
      byte FLAG_SERVER_RESTORE_PUBLIC_KEY = 0;

      //responses
      final static short SW_NULL_RESPONSE_DATA = 0x6A66;

      //keys
      RSAPrivateCrtKey rsa_PrivateCrtKey;
      RSAPublicKey rsa_PublicKey;
      KeyPair rsa_KeyPair;
      Cipher cipherRSA;

      byte[] memory = new byte[2048];

      /**
      * 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 Wallet();
      }

      /**
      * Only this class's install method should create the applet object.
      */
      private Wallet() {
      register();
      }

      /**
      * Processes an incoming APDU.
      *
      * @see APDU
      * @param apdu
      * the incoming APDU
      */
      public void process(APDU apdu) {

      byte[] buffer = apdu.getBuffer();
      // check SELECT APDU command
      if ((buffer[ISO7816.OFFSET_CLA] == 0) &&
      (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4))) {
      return;
      }

      byte cla = buffer[ISO7816.OFFSET_CLA];
      byte ins = buffer[ISO7816.OFFSET_INS];
      byte p1 = buffer[ISO7816.OFFSET_P1];
      byte p2 = buffer[ISO7816.OFFSET_P2];
      byte lc = buffer[ISO7816.OFFSET_LC];
      byte le_offset = (byte) (ISO7816.OFFSET_LC+lc+1);
      byte le = buffer[le_offset];

      byte[] responseData = processAPDU(apdu,cla,ins,p1,p2,lc,le_offset,le);

      if (responseData==null){
      ISOException.throwIt(SW_NULL_RESPONSE_DATA);
      }

      responseWith(apdu,responseData);

      }

      private byte[] processAPDU( APDU apdu, byte cla, byte ins,
      byte p1, byte p2,
      byte lc, byte le_offset, byte le) {

      byte[] responseData = null;

      if (cla!=INS.CLA_WALLET){           
      ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
      }

      switch(ins){
      case INS.INS_TEST_GET_FLAGS:
      responseData = JCSystem.makeTransientByteArray((short)8, JCSystem.CLEAR_ON_DESELECT);
      responseData[0] = FLAG_APPLET_GENERATED_KEYS;
      responseData[1] = FLAG_APPLET_EXTRACTED_PUBLIC_KEY;
      responseData[2] = FLAG_APPLET_EXTRACTED_PRIVATE_KEY;
      responseData[3] = FLAG_APPLET_EXTRACTED_EXPONENT;
      responseData[4] = FLAG_APPLET_EXTRACTED_MODULUS;
      responseData[5] = FLAG_SERVER_SET_PUBLIC_EXPONENT;
      responseData[6] = FLAG_SERVER_SET_PUBLIC_EXPONENT;
      responseData[7] = FLAG_SERVER_RESTORE_PUBLIC_KEY;
      break;
      case INS.INS_APPLET_GENERATE_KEYS :
      generateKeys();
      responseData = JCSystem.makeTransientByteArray((short)0, JCSystem.CLEAR_ON_DESELECT);
      break;
      case INS.INS_APPLET_GET_PUBLIC_EXPONENT :

      default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); break;
      }
      return responseData;
      }

      private void responseWith(APDU apdu, byte[] responseData) {
      apdu.setOutgoing(); // set transmission to outgoing data
      apdu.setOutgoingLength((short)responseData.length); // set the number of bytes to send to the IFD
      apdu.sendBytesLong(responseData, (short)0, (short)responseData.length); // send the requested number of bytes to the IFD
      }

      private void generateKeys() {
      try{

      if (rsa_KeyPair==null) {
      rsa_KeyPair = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048);
      }

      rsa_KeyPair.genKeyPair();
      rsa_PublicKey = (RSAPublicKey) rsa_KeyPair.getPublic();
      rsa_PrivateCrtKey = (RSAPrivateCrtKey) rsa_KeyPair.getPrivate();

      FLAG_APPLET_GENERATED_KEYS = 1;
      } catch (CryptoException ex) {
      ISOException.throwIt((short)ex.getReason());
      // ISOException.throwIt((short) ex.ILLEGAL_USE);
      // ISOException.throwIt((short) ex.ILLEGAL_VALUE);
      // ISOException.throwIt((short) ex.INVALID_INIT);
      // ISOException.throwIt((short) ex.NO_SUCH_ALGORITHM);
      // ISOException.throwIt((short) ex.UNINITIALIZED_KEY);
      } catch (Exception e){
      ISOException.throwIt((short)4000);
      }

      }


      }

      ==================



      For jCardSim i used the following code snippet.
      Used imports:
      Wallet project
      api.jar from javacard dev kit 2.2.1 -
      jcardsim-2.2.1-all.jar
      JDK1.7

      =========jcardsimwallettest.java========
      package jcardsimwallettest;

      import com.licel.jcardsim.base.Simulator;
      import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
      import javacard.framework.AID;
      import javax.smartcardio.CommandAPDU;
      import javax.smartcardio.ResponseAPDU;


      /**
      *
      * @author rbondar
      */
      public class JCardSimWalletTest {

      /**
      * @param args the command line arguments
      */
      public static void main(String[] args) {
      Simulator simulator = new Simulator();
      byte[] aidBytes = new byte[]{ (byte)0x60,
      (byte)0x9D,
      (byte)0xF4,
      (byte)0xF7,
      (byte)0x72,
      (byte)0x04 };
      AID aid = new AID(aidBytes, (short)0, (byte)aidBytes.length);
      simulator.installApplet(aid, wallet.Wallet.class);
      simulator.selectApplet(aid);
      ResponseAPDU response;
      //INS_TEST_GET_FLAGS
      //0x88 0x41 0x00 0x00 0x00 0x08
      CommandAPDU cmd_INS_TEST_GET_FLAGS = new CommandAPDU(
      0x88, 0x41, 0x00, 0x00);
      response = simulator.transmitCommand(cmd_INS_TEST_GET_FLAGS);
      System.out.println(Integer.toHexString(response.getSW()));

      //INS_APPLET_GENERATE_KEYS
      //0x88 0x30 0x00 0x00 0x00 0x00;
      CommandAPDU cmd_INS_APPLET_GENERATE_KEYS = new CommandAPDU(
      0x88, 0x30, 0x00, 0x00);
      response = simulator.transmitCommand(cmd_INS_APPLET_GENERATE_KEYS);
      System.out.println(Integer.toHexString(response.getSW()));

      }
      }
      ===========


      After getting error on Oracle simulator i moved to jCardSim . Right now i don't know what should i use.

      Please help.

      Thanks

      Edited by: rbondar on Sep 19, 2012 8:40 AM