This discussion is archived
1 2 3 4 Previous Next 57 Replies Latest reply: Feb 13, 2011 3:55 AM by Sebastien_Lorquet Go to original post RSS
  • 15. Re: RSA implementation basics ...
    safarmer Expert
    Currently Being Moderated
    The ISO 9797 algorithms should pad according to ISO/IEC 9797 padding method 1 and 2 (M1 and M2 respectively). It even says that in the Java Doc for the Cipher class.

    Cheers,
    Shane
  • 16. Re: RSA implementation basics ...
    843851 Newbie
    Currently Being Moderated
    Thanks for the inputs Shane.

    I wanted to know, the way i have coded the program is right? Again reiterating, The program gets input from the screen, sends the string to the applet, to encrypt the information, gets the encrypted information (not sure if what i have coded is right), stores the same in the card. To decrypt the same, gets the string from the card and sends for decryption. Would be good if you could confirm on what iam doing is right.

    Secondly, the error Iam getting while Decrypting is "Error <Code 38> Unidentified technical problem."
  • 17. Re: RSA implementation basics ...
    843851 Newbie
    Currently Being Moderated
    Shane, after implementation of the decrypt code provided by you, Iam getting the following error,

    <Code 37>An unknown error status was returned from the card ...

    Your help is appreciated
  • 18. Re: RSA implementation basics ...
    843851 Newbie
    Currently Being Moderated
    Shane,


    Would have some sample code on AES or 3TDEA. Also, where could i find information on the same.
  • 19. Re: RSA implementation basics ...
    safarmer Expert
    Currently Being Moderated
    Hi,

    Do you have APDU traces? These error codes look like they are from the PCSC library (Delphi?) you are using. AES and DES work the same way. You only have a single key (that can be random generated bytes on the card).

    Here is some untested code that should get you going. I have not even loaded it onto a card so use at your own risk :)

    Cheers,
    Shane
    import javacard.framework.APDU;
    import javacard.framework.Applet;
    import javacard.framework.ISO7816;
    import javacard.framework.ISOException;
    import javacard.framework.JCSystem;
    import javacard.security.AESKey;
    import javacard.security.KeyBuilder;
    import javacard.security.RandomData;
    import javacardx.crypto.Cipher;
    
    /**
     * @author shane
     * 
     */
    public class AESApplet extends Applet {
        private AESKey key;
        private byte[] workBuffer;
        private final static short WORK_BUFFER_SIZE = 1024;
        private static RandomData rand = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
        private static Cipher cipher = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, true);
    
        /**
         * 
         */
        public AESApplet() {
            workBuffer = JCSystem.makeTransientByteArray(WORK_BUFFER_SIZE, JCSystem.CLEAR_ON_RESET);
            rand.generateData(workBuffer, (short) 0, (short) 16);
            key = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
            key.setKey(workBuffer, (short) 0);
        }
    
        public static void install(byte[] bArray, short bOffset, byte bLength) {
            new AESApplet().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
        }
    
        public void process(APDU apdu) {
            // Good practice: Return 9000 on SELECT
            if (selectingApplet()) {
                return;
            }
    
            byte[] buf = apdu.getBuffer();
            switch (buf[ISO7816.OFFSET_INS]) {
                case (byte) 0x00:
                    // do something with the cipher here
                    break;
                default:
                    // good practice: If you don't know the INStruction, say so:
                    ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            }
        }
    
    }
  • 20. Re: RSA implementation basics ...
    843851 Newbie
    Currently Being Moderated
    Simulation does not support AES before JCOP Tools v3.2.8, Targetpack v1.2.8. With the latest JCOP Tools AES is supported in the simulation if the real product supports it:
    JCOP v2.2, (2.2.1), and v2.3.1: 21/72 and 41/72
    JCOP v2.4.1: all configurations
  • 21. Re: RSA implementation basics ...
    843851 Newbie
    Currently Being Moderated
    Shane,

    Thanks for the response. But iam not sure what you mean by APDU trace. The program is giving an error at the DoFinal line.

    len = cipherRSA.doFinal(a, ISO7816.OFFSET_CDATA, byteRead, a, (short) 0);
  • 22. Re: RSA implementation basics ...
    843851 Newbie
    Currently Being Moderated
    Shane,

    Immediately after the DoFinal command, the card returns me the error code 36864 ... Would you be able to help me...
  • 23. Re: RSA implementation basics ...
    843851 Newbie
    Currently Being Moderated
    Shane,

    Would you be able to help me out on the problem (see thread). Also, let me know how i can get an APDU Trace.

    Appreciate your help
  • 24. Re: RSA implementation basics ...
    843851 Newbie
    Currently Being Moderated
    Shane,

    I also tried using your AES code, but it errors out stating that AESKey package is unavailable. Does it mean that AES cannot be done on the Smart Card I use? Iam using Schlumberger Access 32k smart card ....
  • 25. Re: RSA implementation basics ...
    safarmer Expert
    Currently Being Moderated
    Narsee wrote:
    Immediately after the DoFinal command, the card returns me the error code 36864 ... Would you be able to help me...
    Hi,

    That status word is 0x9000 in HEX which means everything worked fine. If you did not get any data back, you need to specify an Le of 0x00 (if you didn't specify an Le).

    Cheers,
    Shane
  • 26. Re: RSA implementation basics ...
    safarmer Expert
    Currently Being Moderated
    Narsee wrote:
    I also tried using your AES code, but it errors out stating that AESKey package is unavailable. Does it mean that AES cannot be done on the Smart Card I use? Iam using Schlumberger Access 32k smart card ....
    Hi,

    I don't think that card supports AES. Here is the security policy for the cards FIPS compliance: [http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140sp/140sp327.pdf]. You might want to try TDEA.

    Cheers,
    Shane
  • 27. Re: RSA implementation basics ...
    843851 Newbie
    Currently Being Moderated
    Shane,

    You have been really helpful. I was finally able to get a trace. Iam posting the code for RSA encryption/decryption. The encryption happens properly, but the decryption seems to be hanging when i send the encrypted text. Iam also attaching the trace herewith. The card returns a 91 05 status. Not sure what this means ... Please help

    Following is the applet that does the encryption and decryption.
    package hands_on_rsa_encrypt_decrypt;
     
    import javacard.framework.*;
    import javacard.security.*;
    import javacardx.crypto.Cipher;
     
    public class HandsonRSAEncryptDecrypt extends javacard.framework.Applet
    {
    
         final static byte SimpleString_CLA = (byte) 0x85;
    
         //  Instruction set for SimpleString
    
         final static byte SET = (byte)0x10;
         final static byte GET = (byte)0x20;
         final static byte SELECT = (byte) 0xA4;
    
            //  This buffer contains the string data on the card
         byte TheBuffer[];     
         //  The constructor. 
    
    
         //globals
         RSAPrivateCrtKey rsa_PrivateCrtKey;
         RSAPublicKey rsa_PublicKey;
         KeyPair rsa_KeyPair;
         Cipher cipherRSA;
         final short dataOffset = (short) ISO7816.OFFSET_CDATA;
         
         //constructor
         private HandsonRSAEncryptDecrypt(byte bArray[], short bOffset, byte bLength)
         {
    
         TheBuffer = new byte[100];
    
         //generate own rsa_keypair
            rsa_KeyPair = new KeyPair( KeyPair.ALG_RSA_CRT, KeyBuilder.LENGTH_RSA_1024 );
            rsa_KeyPair.genKeyPair();
              rsa_PublicKey = (RSAPublicKey) rsa_KeyPair.getPublic();
              rsa_PrivateCrtKey = (RSAPrivateCrtKey) rsa_KeyPair.getPrivate();
              cipherRSA = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);
              register(bArray, (short) (bOffset + 1), bArray[bOffset]);
         }
     
         //install
         public static void install(byte bArray[], short bOffset, byte bLength)
         {
              new HandsonRSAEncryptDecrypt(bArray, bOffset, bLength);
         }
    
    
         public void process(APDU apdu)
         {
     
     
              if (selectingApplet())
              {
                   return;
              }
    
              byte[] buf = apdu.getBuffer();
    
              if (buf[ISO7816.OFFSET_CLA] != 0) ISOException.throwIt (ISO7816.SW_CLA_NOT_SUPPORTED);
    
              if (buf[ISO7816.OFFSET_INS] != (byte) (0xAA)) ISOException.throwIt (ISO7816.SW_INS_NOT_SUPPORTED);
     
              switch (buf[ISO7816.OFFSET_P1])
              {
              case (byte) 0x01:
                   encryptRSA(apdu);
                   //SetString(apdu);
                   return;
              case (byte) 0x02:
                   decryptRSA(apdu);
                   return;
              default:
                   ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
              }
         }
         
         private void encryptRSA(APDU apdu)
         {
              byte a[] = apdu.getBuffer();
    
              short byteRead = (short) (apdu.setIncomingAndReceive());
              cipherRSA.init(rsa_PrivateCrtKey, Cipher.MODE_ENCRYPT);
              short cyphertext = cipherRSA.doFinal(a, (short) dataOffset, byteRead, a, (short) dataOffset);
    
              // Send results
              apdu.setOutgoing();
              apdu.setOutgoingLength((short) cyphertext);
              apdu.sendBytesLong(a, (short) dataOffset, (short) cyphertext);
              //SetString(apdu);
     
         }
         
    
         private void decryptRSA(APDU apdu) {
                 byte a[] = apdu.getBuffer();
     
                 short byteRead = (short) (apdu.setIncomingAndReceive());
                short len = 0;
                try {
                     cipherRSA.init(rsa_PublicKey, Cipher.MODE_DECRYPT);
                     len = cipherRSA.doFinal(a, ISO7816.OFFSET_CDATA, byteRead, a, (short) 0);
                } catch (CryptoException e) {
                   short sw = (short) 0x9100;
                   sw |= e.getReason();
                   ISOException.throwIt(sw);
                }
     
                 // Send results
                 apdu.setOutgoing();
                 apdu.setOutgoingLength(len);
                 apdu.sendBytesLong(a, (short) 0, len);
     
          }
         
    }
    The trace is as follows,
    SCardTransmit (handle 0xEA010000):
     transmitted:
      00 A4 04 00 07 A0 00 00 00 03 00 00
     received:
      61 1A
    
    SCardTransmit (handle 0xEA010000):
     transmitted:
      80 CA 9F 7F 2D
     received:
      9F 7F 2A 40 90 00 62 00 11 02 02 01 00 92 72 00 02 2D 3A 00 00 19 42 92 72 19
      43 92 72 19 44 92 72 00 00 C1 02 FF FF FF FF FF FF FF FF 90 00
    
    SCardTransmit (handle 0xEA010000):
     transmitted:
      00 A4 04 00 05 01 02 C1 C2 C3
     received:
      90 00
    
    SCardTransmit (handle 0xEA010000):
     transmitted:
      00 AA 01 00 06 41 42 43 44 45 46
     received:
      61 80
    
    SCardTransmit (handle 0xEA010000):
     transmitted:
      00 C0 00 00 80
     received:
      12 3D 49 AD E6 4B 4E 60 F3 6A DD CD D4 36 D0 3B 05 7D 03 4B 95 CB 09 A5 94 52
      E0 00 61 98 9F E3 40 23 C3 1B 45 50 61 14 30 7D 65 FD 9F DD 22 49 95 F8 ED EE
      12 68 22 F1 3E A4 70 B6 62 11 7F 1C AB C8 76 D6 35 28 DE 8A 41 56 64 95 D1 F2
      5B D2 7E A7 0A 41 D8 34 0F 4A 2B 05 AB 3C 25 AB 89 F0 8C 91 2E B0 B2 BE 1D B4
      77 A0 14 DC 07 6D 49 1C 0F 9C F6 23 1E 45 B5 C6 38 FE 68 AF 51 EF 30 8D 90 00
    
    SCardTransmit (handle 0xEA010000):
     transmitted:
      00 AA 02 00 06 12 3D 49 AD E6 4B
     received:
      91 05
  • 28. Re: RSA implementation basics ...
    safarmer Expert
    Currently Being Moderated
    Hi,

    From the Java Doc for javacard.security.CryptoException:
    This reason code is used to indicate that the signature or cipher algorithm does not pad the incoming message and input message is not block aligned.
    public static final short ILLEGAL_USE = (short) 0x0005;
    Since you encrypted with the PKCS1 cipher object you are decrypting with, there is most likely data missing. You may want to check that you have actually read all of the bytes in the incoming APDU buffer. Try something like this (coded directly into this window so may not actual compile or run).
    short lc = (short) (a[ISO7816.OFFSET_LC] & 0xff);
    short read = apdu.setIncomingAndReceive();
    while(read < lc) {
        read += apdu.receiveBytes(read);
    }
    Cheers,
    Shane
  • 29. Re: RSA implementation basics ...
    843851 Newbie
    Currently Being Moderated
    Shane,

    Thanks for the inputs. I did not understand your comments. I believe you wanted me to paste the same in the Decrypt code, to ensure all the bytes are being captured. I did do the same, but get the same result.