Site Tools


javacard-api-samples:rsa

RSA Sample Code

Download Sample Code Discussion

   /*
 * @file  RSASample.java
 * @version v1.0
 * Package AID: 4A617661436172644F53
 * Applet AID:  4A617661436172644F5303
 * @brief The ALgorithm of RSA Sample Code in JavaCard API Specification
 * @comment The purpose of this example is only used to show the usage of API functions and there is no practical significance.
 * @copyright Copyright(C) 2016 JavaCardOS Technologies Co., Ltd. All rights reserved.
 */
 
package JavaCardOS.Sample.Algorithm;
 
import javacard.framework.*;
import javacard.security.KeyBuilder;
import javacard.security.*;
import javacardx.crypto.*;
 
public class RSASample extends Applet
{
    private static final byte INS_GEN_RSA_KEYPAIR          = (byte)0x30;
    private static final byte INS_GET_RSA_PUBKEY           = (byte)0x31;
    private static final byte INS_GET_RSA_PRIKEY           = (byte)0x32;
    private static final byte INS_SET_RSA_PUBKEY           = (byte)0x33;
    private static final byte INS_SET_RSA_PRIKEY           = (byte)0x34;
    private static final byte INS_RSA_SIGN                 = (byte)0x35;
    private static final byte INS_RSA_VERIFY               = (byte)0x36;
    private static final byte INS_DO_RSA_CIPHER            = (byte)0x37;
 
    private byte[] tempBuffer;
 
    private byte[] flags;
    private static final short OFF_INS    = (short)0;
    private static final short OFF_P1     = (short)1;
    private static final short OFF_P2     = (short)2;
    private static final short OFF_LEN    = (short)3;
    private static final short FLAGS_SIZE = (short)5;
 
    private static final byte ID_N   = 0;
    private static final byte ID_D   = 1;
    private static final byte ID_P   = 2;
    private static final byte ID_Q   = 3;
    private static final byte ID_PQ  = 4;
    private static final byte ID_DP1 = 5;
    private static final byte ID_DQ1 = 6;
 
    private byte[] rsaPubKey;
    private short rsaPubKeyLen;
    private byte[] rsaPriKey;
    private short rsaPriKeyLen;
    private boolean isRSAPriKeyCRT;
    private Cipher rsaCipher;   
    private Signature rsaSignature;
 
    private static final short SW_REFERENCE_DATA_NOT_FOUND = (short)0x6A88;
 
    public RSASample()
    {
        //Create a transient byte array to store the temporary data
        tempBuffer = JCSystem.makeTransientByteArray((short)256, JCSystem.CLEAR_ON_DESELECT);
        flags = JCSystem.makeTransientByteArray(FLAGS_SIZE, JCSystem.CLEAR_ON_DESELECT);
 
        rsaPubKey = new byte[(short)    (256 + 32)];
        rsaPriKey = new byte[(short)(128 * 5)];
        rsaPubKeyLen = 0;
        rsaPriKeyLen = 0;
        isRSAPriKeyCRT = false;
        rsaSignature = null;
        //Create a RSA(not pad) object instance
        rsaCipher = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false);
 
        JCSystem.requestObjectDeletion();
    }
 
    public static void install(byte[] bArray, short bOffset, byte bLength)
    {
        new RSASample().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
    }
 
    public void process(APDU apdu)
    {
        if (selectingApplet())
        {
            return;
        }
 
        byte[] buf = apdu.getBuffer();
        short len = apdu.setIncomingAndReceive();
        switch (buf[ISO7816.OFFSET_INS])
        {
        case INS_GEN_RSA_KEYPAIR:
            //GEN_RSA_KEYPAIR
            genRsaKeyPair(apdu, len);
            break;
        case INS_GET_RSA_PUBKEY:
            //GET_RSA_PUBKEY
            getRsaPubKey(apdu, len);
            break;
        case INS_GET_RSA_PRIKEY:
            //GET_RSA_PRIKEY
            getRsaPriKey(apdu, len);
            break;
        case INS_SET_RSA_PUBKEY:
            // SET_RSA_PUBKEY
            setRsaPubKey(apdu, len);
            break;
        case INS_SET_RSA_PRIKEY:
            //SET_RSA_PRIKEY
            setRsaPriKey(apdu, len);
            break;
        case INS_RSA_SIGN:
            //RSA_SIGN
            rsaSign(apdu, len);
            break;
        case INS_RSA_VERIFY:
            //RSA_VERIFY
            rsaVerify(apdu, len);
            break;
        case INS_DO_RSA_CIPHER:   
            //RSA_CIPHER
            doRSACipher(apdu, len);
            break;
        default:
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }
 
    //RSA algorithm encrypt and decrypt
    private void doRSACipher(APDU apdu, short len)
    {
        byte[] buffer = apdu.getBuffer();
        byte p1Tmp = buffer[ISO7816.OFFSET_P1];
        boolean hasMoreCmd = (p1Tmp & 0x80) != 0;
        boolean isEncrypt = (p1Tmp & 0x01) != 1;
        short keyLen = (p1Tmp & 0x08) == (byte)0x00 ? KeyBuilder.LENGTH_RSA_1024 : KeyBuilder.LENGTH_RSA_2048;
        short offset = (p1Tmp & 0x08) == (byte)0x00 ? (short)128 : (short)256;
 
        if (len  rsaPubKey.length)
        {
            Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
            ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        }
        //Copy the value of RSA public key  to the global variable 'rsaPubKey'.
        Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, rsaPubKey, loadedLen, len);
        loadedLen += len;
 
        if ((buffer[ISO7816.OFFSET_P1] & 0x80) == 0) //last block
        {
            Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
            short modLen = (buffer[ISO7816.OFFSET_P1] & 0x01) == 0 ? (short)128 : (short)256;
            if (loadedLen < modLen + 3 || loadedLen > modLen + 32)
            {
                ISOException.throwIt(ISO7816.SW_WRONG_DATA);
            }
 
            rsaPubKeyLen = loadedLen;
        }
        else
        {
            Util.setShort(flags, OFF_LEN, loadedLen);
        }
 
    }
 
    //Set the value of RSA private key
    private void setRsaPriKey(APDU apdu, short len)
    {
        byte[] buffer = apdu.getBuffer();
        if (buffer[ISO7816.OFFSET_P2] == 0) // first block
        {
            rsaPriKeyLen = (short)0;
            Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_INS, flags, OFF_INS, (short)3);
            Util.setShort(flags, OFF_LEN, (short)0);
        }
        else
        {
            if (flags[OFF_INS] != buffer[ISO7816.OFFSET_INS]
                    || (flags[OFF_P1] & 0x7f) != (buffer[ISO7816.OFFSET_P1] & 0x7f)
                    || (short)(flags[OFF_P2] & 0xff) != (short)((buffer[ISO7816.OFFSET_P2] & 0xff) - 1))
            {
                Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            }
 
            flags[OFF_P2] ++;
        }
        short loadedLen = Util.getShort(flags, OFF_LEN);
        if (loadedLen + len > rsaPriKey.length)
        {
            Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
            ISOException.throwIt(ISO7816.SW_WRONG_DATA);
        }
        //Copy the value of RSA private key  to the global variable 'rsaPriKey'.
        Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, rsaPriKey, loadedLen, len);
        loadedLen += len;
 
        if ((buffer[ISO7816.OFFSET_P1] & 0x80) == 0) //last block
        {
            Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
            short modLen = (buffer[ISO7816.OFFSET_P1] & 0x01) == 0 ? (short)128 : (short)256;
            boolean isCRT = (buffer[ISO7816.OFFSET_P1] & 0x40) != 0;
            if ((isCRT && (loadedLen != modLen / 2 * 5)) || (!isCRT && (loadedLen != modLen * 2)))
            {
                ISOException.throwIt(ISO7816.SW_WRONG_DATA);
            }
 
            isRSAPriKeyCRT = isCRT;
            rsaPriKeyLen = loadedLen;
        }
        else
        {
            Util.setShort(flags, OFF_LEN, loadedLen);
        }
    }
    //
    private void genRsaKeyPair(APDU apdu, short len)
    {
        byte[] buffer = apdu.getBuffer();
        short keyLen = buffer[ISO7816.OFFSET_P1] == 0 ? (short)1024 : (short)2048;
        byte alg = buffer[ISO7816.OFFSET_P2] == 0 ? KeyPair.ALG_RSA : KeyPair.ALG_RSA_CRT;
        KeyPair keyPair = new KeyPair(alg, keyLen);
        if (len > 32)
        {
            ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
        }
        if (len > 0)
        {
            ((RSAPublicKey)keyPair.getPublic()).setExponent(buffer, ISO7816.OFFSET_CDATA, len);
        }
        //(Re)Initializes the key objects encapsulated in this KeyPair instance with new key values.
        keyPair.genKeyPair();
        JCSystem.beginTransaction();
        rsaPubKeyLen = 0;
        rsaPriKeyLen = 0;
        JCSystem.commitTransaction();
        //Get a reference to the public key component of this 'keyPair' object.
        RSAPublicKey pubKey = (RSAPublicKey)keyPair.getPublic();
        short pubKeyLen = 0;
        //Store the RSA public key value in the global variable 'rsaPubKey', the public key contains modulo N and Exponent E
        pubKeyLen += pubKey.getModulus(rsaPubKey, pubKeyLen);
        pubKeyLen += pubKey.getExponent(rsaPubKey, pubKeyLen);
 
        short priKeyLen = 0;
        if (alg == KeyPair.ALG_RSA)
        {
            isRSAPriKeyCRT = false;
            //Returns a reference to the private key component of this KeyPair object.
            RSAPrivateKey priKey = (RSAPrivateKey)keyPair.getPrivate();
            //RSA Algorithm,  the Private Key contains N and D, and store these parameters value in global variable 'rsaPriKey'.
            priKeyLen += priKey.getModulus(rsaPriKey, priKeyLen);
            priKeyLen += priKey.getExponent(rsaPriKey, priKeyLen);
        }
        else //RSA CRT
        {
            isRSAPriKeyCRT =  true;
            //The RSAPrivateCrtKey interface is used to sign data using the RSA algorithm in its Chinese Remainder Theorem form.
            RSAPrivateCrtKey priKey = (RSAPrivateCrtKey)keyPair.getPrivate();
            //RSA CRT Algorithm,  the Private Key contains P Q PQ DP and DQ, and store these parameters value in global variable 'rsaPriKey'.
            priKeyLen += priKey.getP(rsaPriKey, priKeyLen);
            priKeyLen += priKey.getQ(rsaPriKey, priKeyLen);
            priKeyLen += priKey.getPQ(rsaPriKey, priKeyLen);
            priKeyLen += priKey.getDP1(rsaPriKey, priKeyLen);
            priKeyLen += priKey.getDQ1(rsaPriKey, priKeyLen);
        }
 
        JCSystem.beginTransaction();
        rsaPubKeyLen = pubKeyLen;
        rsaPriKeyLen = priKeyLen;
        JCSystem.commitTransaction();
 
        JCSystem.requestObjectDeletion();
    }
   //RSA Signature
    private void rsaSign(APDU apdu, short len)
    {
        byte[] buffer = apdu.getBuffer();
        if (rsaPriKeyLen == 0)
        {
            ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
        }
        boolean hasMoreCmd = (buffer[ISO7816.OFFSET_P1] & 0x80) != 0;
        short resultLen = 0;
        if (buffer[ISO7816.OFFSET_P2] == 0) //first block
        {
            Key key;
            if (!isRSAPriKeyCRT)
            {
                short ret;
                //Creates uninitialized private keys for signature algorithms.
                key = KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, (short)(rsaPriKeyLen / 2 * 8), false);
                ret = getRsaPriKeyComponent(ID_N, tempBuffer, (short)0);
                ((RSAPrivateKey)key).setModulus(tempBuffer, (short)0, ret);
                ret = getRsaPriKeyComponent(ID_D, tempBuffer, (short)0);
                ((RSAPrivateKey)key).setExponent(tempBuffer, (short)0, ret);
            }
            else
            {
                short ret;
                //Creates uninitialized private keys for signature algorithms.
                key = KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_CRT_PRIVATE, (short)(rsaPriKeyLen / 5 * 16), false);
                ret = getRsaPriKeyComponent(ID_P, tempBuffer, (short)0);
                ((RSAPrivateCrtKey)key).setP(tempBuffer, (short)0, ret);
                ret = getRsaPriKeyComponent(ID_Q, tempBuffer, (short)0);
                ((RSAPrivateCrtKey)key).setQ(tempBuffer, (short)0, ret);
                ret = getRsaPriKeyComponent(ID_DP1, tempBuffer, (short)0);
                ((RSAPrivateCrtKey)key).setDP1(tempBuffer, (short)0, ret);
                ret = getRsaPriKeyComponent(ID_DQ1, tempBuffer, (short)0);
                ((RSAPrivateCrtKey)key).setDQ1(tempBuffer, (short)0, ret);
                ret = getRsaPriKeyComponent(ID_PQ, tempBuffer, (short)0);
                ((RSAPrivateCrtKey)key).setPQ(tempBuffer, (short)0, ret);
            }
            // Creates a Signature object instance of the ALG_RSA_SHA_PKCS1 algorithm.
            rsaSignature = Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1, false);
            JCSystem.requestObjectDeletion();
            //Initializ the Signature object.
            rsaSignature.init(key, Signature.MODE_SIGN);
 
            Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_INS, flags, OFF_INS, (short)3);
            JCSystem.requestObjectDeletion();
        }
        else
        {
            if (flags[OFF_INS] != buffer[ISO7816.OFFSET_INS]
                    || (flags[OFF_P1] & 0x7f) != (buffer[ISO7816.OFFSET_P1] & 0x7f)
                    || (short)(flags[OFF_P2] & 0xff) != (short)((buffer[ISO7816.OFFSET_P2] & 0xff) - 1))
            {
                Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            }
 
            flags[OFF_P2] ++;
        }
 
        if (hasMoreCmd)
        {
            // Accumulates a signature of the input data.
            rsaSignature.update(buffer, ISO7816.OFFSET_CDATA, len);
        }
        else
        {
            //Generates the signature of all input data.
            short ret = rsaSignature.sign(buffer, ISO7816.OFFSET_CDATA, len, buffer, (short)0);
            Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
            apdu.setOutgoingAndSend((short)0, ret);
        }
    }
    //RSA Signature and Verify
    private void rsaVerify(APDU apdu, short len)
    {
        byte[] buffer = apdu.getBuffer();
        if (rsaPubKeyLen == 0)
        {
            ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
        }
        boolean hasMoreCmd = (buffer[ISO7816.OFFSET_P1] & 0x80) != 0;
        short resultLen = 0;
        short offset = ISO7816.OFFSET_CDATA;
        short modLen = rsaPubKeyLen > 256 ? (short)256 : (short)128;
        if (buffer[ISO7816.OFFSET_P2] == 0) //first block
        {
            Key key;
            // Create uninitialized public keys for signature  algorithms.
            key = KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, (short)(modLen * 8), false);
            //Sets the modulus value of the key.
            ((RSAPublicKey)key).setModulus(rsaPubKey, (short)0, modLen);
            //Sets the public exponent value of the key.
            ((RSAPublicKey)key).setExponent(rsaPubKey, modLen, (short)(rsaPubKeyLen - modLen));
 
            //Create a ALG_RSA_SHA_PKCS1 object instance.
            rsaSignature = Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1, false);
            JCSystem.requestObjectDeletion();
            //Initializes the Signature object with the appropriate Key.
            rsaSignature.init(key, Signature.MODE_VERIFY);
            Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_INS, flags, OFF_INS, (short)3);
            Util.setShort(flags, OFF_LEN, (short)0);
            JCSystem.requestObjectDeletion();
        }
        else
        {
            if (flags[OFF_INS] != buffer[ISO7816.OFFSET_INS]
                    || (flags[OFF_P1] & 0x7f) != (buffer[ISO7816.OFFSET_P1] & 0x7f)
                    || (short)(flags[OFF_P2] & 0xff) != (short)((buffer[ISO7816.OFFSET_P2] & 0xff) - 1))
            {
                Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            }
 
            flags[OFF_P2] ++;
        }
 
        short sigLen = Util.getShort(flags, OFF_LEN);
        if (sigLen < modLen)
        {
            short readLen = (short)(modLen - sigLen);
            if (readLen > len)
            {
                readLen = len;
            }
            Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, tempBuffer, sigLen, readLen);
            sigLen += readLen;
            len -= readLen;
            Util.setShort(flags, OFF_LEN, sigLen);
            offset += readLen;
        }
        if (hasMoreCmd)
        {
            if (len > 0)
            {
                //Accumulates a signature of the input data.
                rsaSignature.update(buffer, offset, len);
            }
        }
        else
        {
            if (sigLen != modLen)
            {
                Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
                ISOException.throwIt(ISO7816.SW_WRONG_DATA);
            }
            //Verify the signature of all/last input data against the passed in signature.
            boolean ret = rsaSignature.verify(buffer, offset, len, tempBuffer, (short)0, sigLen);
            Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
            buffer[(short)0] = ret ? (byte)1 : (byte)0;
            apdu.setOutgoingAndSend((short)0, (short)1);
        }
    }
 
}

The test script of RSA is as follows: Download Test Script

//The test script of RSA
//Copyright(C) JavaCardOS Technologies Co., Ltd. All rights reserved.
 
//RSA Select Applet
00A404000B4A617661436172644F530300;
//RSA
//generate-keypair-1024 in card
80300000;
//get Publck Key -  N
80310000;
 
//get Publck Key - E  The data of response APDU command is 4 bytes, such as 01 00 01 90 00
80310100;
//get RSA Private Key - N
80320000;
//get RSA Private Key - D
80320100;
 
//RSA encrypt - 2048
//set RSA Public key 2048bit
 
80338100C8C24A7A902FA8983CBBAB3F690528F86D5591496374E6B3B4EC47CA644CB55F204C4D5EEBBD9D236B6F74AC209738CB294A7C26F1251D838EDF8ADAF3E287743A5D7C65BBBCFE4A22BEB06D0D65DAFE1D1217E8AB9E5B7AA0D3883A4D6D2F5BE5B295AE6CD495D45D4452876F573C3EDD402E3BA998EC1078F662027A5F7BCE949C3B3F0309B1BE5EE9AAE720C97C2C2F0CBCD298E3FC049A457513DCCC70BDA06949011BC1F0DB6F499685377DF87B3E66890FB4C0CC09CF12DB338394C44E324D0F1931D623C035;
803301013BD00F518C353243CD22A3239811928163DCDA1352044AE4E15F10FEF648E98AE88B7BBA89F29C7EFAE5EE04E299F90F52FEE263AF2DA885FB010001;
//set RSA Private Key 2048bit
80348100C8C24A7A902FA8983CBBAB3F690528F86D5591496374E6B3B4EC47CA644CB55F204C4D5EEBBD9D236B6F74AC209738CB294A7C26F1251D838EDF8ADAF3E287743A5D7C65BBBCFE4A22BEB06D0D65DAFE1D1217E8AB9E5B7AA0D3883A4D6D2F5BE5B295AE6CD495D45D4452876F573C3EDD402E3BA998EC1078F662027A5F7BCE949C3B3F0309B1BE5EE9AAE720C97C2C2F0CBCD298E3FC049A457513DCCC70BDA06949011BC1F0DB6F499685377DF87B3E66890FB4C0CC09CF12DB338394C44E324D0F1931D623C035;
80348101C8D00F518C353243CD22A3239811928163DCDA1352044AE4E15F10FEF648E98AE88B7BBA89F29C7EFAE5EE04E299F90F52FEE263AF2DA885FB8FFFDD79122995B3A5B0558E03CA0ADE1606596B42505EAEE0549117E796A18B71A202911C76E3B293E7D84F4B65478631F3747553F9DCF0BE93CE95E5B659198D024EF06731DD468528839AE37BFCCD1504ED688D34E5DD5F0A5F93D531BD9DAFCFAA7874D31B9388B8D6325A68877B3A3F49EEF82D364440F001402B96BA533404EB121B0E6604B0678A5AAA100C56;
8034010270B3ECD17EDDCB4F5BC71BBE1E7A405679380E6D9A777AA8452A2DE5F1FECAA09ACEA4A02940A14F28C7CBF7EE0A1A1519B58ED3161A590BC66B82C13CD43C484AD2D77E8301629F9B1EB4C7505C5A7B46C0171668990775FDF2E62BB695DF424130727CD0ACC61943FE8EF513A0AC9BD1;
// RSA Signature  SHA1 &2048bit
//expect:75A78094B3A63715B85327C2839CE1E1831C39B740DDB9F67F27AEBC540DB94BF95C7DEE200AC60A2BF0F64B9F4772A163E036D8DC8E865EFD5B3E7A9442BDF43BA86660D305C15DB2A3A8F5F6E3D1F50E234B193DD787B89E3EDF045E280285474A027E8985F45D883E14593D91CF79017E3AEBCF8A155DD0B5C85BE0A4301D0F80C99A15D154DF54FFE8EB603DA85184386452ABB47C985EF1D5390FF74516A7F0B8A05380DD186AA6FA584287F8AAE6421D98AD84601D734EA008CE0B37FF574BD1C9FE948DABF0A78F4E691FC0A9CAE6DC1288BD2E295CFB31443F09AF16B5D66886BA7AEF2FF272E443ADBA47798F76EF6B4594CEC399526F21236AD3A29000
8035000080C05DECFACFC439CA7AB1EC89F554FF982FB7E8E95FFFC863DFEFE5883EAD5A5591C90D69097BE26ACB2C2EA5FB386FF41AF33AE593EA7418906BC5E912474A4F41D68A04013CACE7C5EBE79EA869397FBA545CB197A3F68E3F2E104C2171C9DD798C4B13DC8FFF0811F5FDBD236EC701B4E2369594B2B48D9341ACF993B33FC5;
//RSA Verify 2048bit
80368000C875A78094B3A63715B85327C2839CE1E1831C39B740DDB9F67F27AEBC540DB94BF95C7DEE200AC60A2BF0F64B9F4772A163E036D8DC8E865EFD5B3E7A9442BDF43BA86660D305C15DB2A3A8F5F6E3D1F50E234B193DD787B89E3EDF045E280285474A027E8985F45D883E14593D91CF79017E3AEBCF8A155DD0B5C85BE0A4301D0F80C99A15D154DF54FFE8EB603DA85184386452ABB47C985EF1D5390FF74516A7F0B8A05380DD186AA6FA584287F8AAE6421D98AD84601D734EA008CE0B37FF574BD1C9FE948DAB;
//expect:019000
80360001B8F0A78F4E691FC0A9CAE6DC1288BD2E295CFB31443F09AF16B5D66886BA7AEF2FF272E443ADBA47798F76EF6B4594CEC399526F21236AD3A2C05DECFACFC439CA7AB1EC89F554FF982FB7E8E95FFFC863DFEFE5883EAD5A5591C90D69097BE26ACB2C2EA5FB386FF41AF33AE593EA7418906BC5E912474A4F41D68A04013CACE7C5EBE79EA869397FBA545CB197A3F68E3F2E104C2171C9DD798C4B13DC8FFF0811F5FDBD236EC701B4E2369594B2B48D9341ACF993B33FC5;
//RSA -2048 encrypt
80378800643E78AA266AA64FED361D907305CD70438AA5F0E674AAD69E5146AD57ACE20DDA79B71C44B4E055B644B4884F25542257C680AFBDB0AF9DC4695E43F998A8226869176A0F33BAC09359773E326EA3BBF99CD04D3746E60D31EC761A174F4AE137D6419B71;
8037880164315A16EB3C0EB90626E3C390D23ED33B7D78AD4D3E78AA266AA64FED361D907305CD70438AA5F0E674AAD69E5146AD57ACE20DDA79B71C44B4E055B644B4884F25542257C680AFBDB0AF9DC4695E43F998A8226869176A0F33BAC09359773E326EA3BBF9; 
//expect:50237853BC0EBF1537BACA8022795F75FBCF4DDAF18FB99464F68E2E29D7023159BE25219D4493EADB048811304301507EEECEEC0056665E77960D338B4AB52B00B2235E2CF390B1BFDB77716C82493D719228385B707D56DAB30C06661218F162181E90094E32C5D1879F1401B3B17CE961297977CA7C97B2C10FC0FF104780A360150C797EDFA60677C200AA78F3EDCC99FDA1BCE14961A65C4F41552EE575EFB07F4074C8071F80AE083F1AA2BFDB0007A824A7828BBFB583D96B6D6EAD84F9124CA9B7A41EC522630C605886E8EAD146A6C837ED88BC39D779541B5586B518F20554FF8D1496B9EB17A3954FBCB9F3E7C5B6F01DA8C973E4B41A96B32F5C9000
80370802389CD04D3746E60D31EC761A174F4AE137D6419B71315A16EB3C0EB90626E3C390D23ED33B7D78AD4DA2353B9A1AF1D2AFA2353B9A1AF1D2AF;
//RSA -2048 decrypt
80378900C850237853BC0EBF1537BACA8022795F75FBCF4DDAF18FB99464F68E2E29D7023159BE25219D4493EADB048811304301507EEECEEC0056665E77960D338B4AB52B00B2235E2CF390B1BFDB77716C82493D719228385B707D56DAB30C06661218F162181E90094E32C5D1879F1401B3B17CE961297977CA7C97B2C10FC0FF104780A360150C797EDFA60677C200AA78F3EDCC99FDA1BCE14961A65C4F41552EE575EFB07F4074C8071F80AE083F1AA2BFDB0007A824A7828BBFB583D96B6D6EAD84F9124CA9B7A41EC5;
803709013822630C605886E8EAD146A6C837ED88BC39D779541B5586B518F20554FF8D1496B9EB17A3954FBCB9F3E7C5B6F01DA8C973E4B41A96B32F5C;
//2048-CRT 
//set public Key RSA CRT-2048
80338100C8AF536A413B40AD9D363E2A8192986A4F054C1C4BE30D47EDD76A32D1AA7EE9A9F91E5BA81D20819B5A5293D8C39F8549E3695E13BE12B19405110D2FBED0E393016D231B4201408CDE963377F802579313ECBBB49320B09D8216374EC50A70D70AE1DE5E0E05AD1B7A1F57638674309FB544EB35CBB5535D3C4C727FF633C6CFFF44F0E141B38074B5C92EF26A57B173F3DDE85C5D4F0B2A3F06E4F1961BB07712D9D0B901EDC8CEA67AEDDBBA0C7EA08857B6934168AF893E7F419DE51E45EEF8272274D85F89D8;
803301013B95E867318D75FADC8AA35FC053B3E02EABA50B2D7B61F0F3EB7A4BCE1DDB43B6887C93580F8BAED5B5236EC69A7D1C42CCE978A98160AC51010001;
//set private Key RSA CRT-2048
8034C100C8E7F037F8E89DF110BA672C16BDE2930EA223E2CF63FC030650DCA03289DD4FBE1056975FCB4566822E18C9A22437FA8685C7978187E1A72860E4BE19BEAA4A88A9C1A64F3186E39E6618039418528006281ADD687842CF8D27198C6D1E16166A4CE5A983263A776A5DCA829FC2F76B1A9369F5B5B2A62382593E8E00B3D36795C183B0BEB5D5171EC3DC28BD4BFE637F76AB6874EB6E7BCDAC5F782C7FD38C3A71394FA503DA1519413D60577AD831257E8C77356952B9F1BDF909FADC609F05002A532D6FFBEBAD;
8034C101C84E68A2FF5914E2A331CFC001586F74ACE4FFD23C2FB584B175070E2C3AC414259DC831536116BA669DB636FA82E65CE1C2D873E2B40552CDCAEDFEE1BCFBF77E31D1F82908A8B54CE471F58FF3B0B79EB00DE1D195033D52EA0DA48401961227A4D48E488081701DF08997D4C29BEAD4BF2F3BD1AB9431AA9775ED5A63958984BA30868AAE23BD2BBB1815764F5896BFD5AEC2FF2B08D23A7EC18D358C3D2E99798E0C9DABDD145A3F7E7FC741097762853E882DFCFEF0165153C60C9D646456FD45980C11611537;
8034C102C8985B04F8BB926E6D14858816B088CDA15391495AE9A7D81DE594037FBB3B75B91DC7B2B454B5272BDD6DD7CAA73487160C903E849E55321324B15EEFDAE772C4B5E355A78023CD2B2D7EA3E2CF1DE7963688813BDF77B8CFAF3B873A05DF43CAF9CDB9BE9079F91187C18B816B8CC151720904B29DBC80EF6443ECCE00665C83D48E95F3B0795F0388BC89B8CF6AFE8BC2051FE6022B159BD8522EDFDE48604DD4113A7E831E78ECF82235BB5AFAA53AF129FFF21AB7BDDE57025A6B57377386EFE7992231D71C4E;
803441032876743A93B519A6A45C6E57EFC081A3CDB6F92DF81092B02DA06AAC635B981CCBFD62488823C5AF51;
//sign  RSA CRT-2048
80358000C8111111413B40AD9D363E2A8192986A4F054C1C4BE30D47EDD76A32D1AA7EE9A9F91E5BA81D20819B5A5293D8C39F8549E3695E13BE12B19405110D2FBED0E393016D231B4201408CDE963377F802579313ECBBB49320B09D8216374EC50A70D70AE1DE5E0E05AD1B7A1F57638674309FB544EB35CBB5535D3C4C727FF633C6CFFF44F0E141B38074B5C92EF26A57B173F3DDE85C5D4F0B2A3F06E4F1961BB07712D9D0B901EDC8CEA67AEDDBBA0C7EA08857B6934168AF893E7F419DE51E45EEF8272274D85F89D8;
//expect: 7008B8ACE976C4024F5148DCCF30DE9CEF6D330FE803B8516A8099CF795C9C57EF9092F1BA7CB75018BF0A7378062FC6D23208CE916F55E0BA471A977CE86FB3E6AAD1282E33E8E5B8FCCF31B2FF689127C292F9B8CC0F07DDDA17A4B870510F6E19187184C3749D1CA957AB2CDE752D459C3D9427A16168BDF1705536E87A97FAAEC1485F90857A0EB2A8DAF5EEDD59F8285D2E65B8D4DEB24EE59A72645B263D02D604EEE03F93EC04EDC8CBC08619E863B2C4A521244A101C6D2EA3E789F1616CE2DFA11190A6C928C0BE4117DF4555DEA280645454CFD755C3B547813FC46667C96223EC5458A9FCB51BBF9524183F0CF3A00A89B812F597CC7285573E7D9000
803500013895E867318D75FADC8AA35FC053B3E02EABA50B2D7B61F0F3EB7A4BCE1DDB43B6887C93580F8BAED5B5236EC69A7D1C42CCE978A98160AC51;
//verify RSA CRT-2048
80368000C87008B8ACE976C4024F5148DCCF30DE9CEF6D330FE803B8516A8099CF795C9C57EF9092F1BA7CB75018BF0A7378062FC6D23208CE916F55E0BA471A977CE86FB3E6AAD1282E33E8E5B8FCCF31B2FF689127C292F9B8CC0F07DDDA17A4B870510F6E19187184C3749D1CA957AB2CDE752D459C3D9427A16168BDF1705536E87A97FAAEC1485F90857A0EB2A8DAF5EEDD59F8285D2E65B8D4DEB24EE59A72645B263D02D604EEE03F93EC04EDC8CBC08619E863B2C4A521244A101C6D2EA3E789F1616CE2DFA11190A6;
80368001C8C928C0BE4117DF4555DEA280645454CFD755C3B547813FC46667C96223EC5458A9FCB51BBF9524183F0CF3A00A89B812F597CC7285573E7D111111413B40AD9D363E2A8192986A4F054C1C4BE30D47EDD76A32D1AA7EE9A9F91E5BA81D20819B5A5293D8C39F8549E3695E13BE12B19405110D2FBED0E393016D231B4201408CDE963377F802579313ECBBB49320B09D8216374EC50A70D70AE1DE5E0E05AD1B7A1F57638674309FB544EB35CBB5535D3C4C727FF633C6CFFF44F0E141B38074B5C92EF26A57B173;
//expect:01 90 00
8036000270F3DDE85C5D4F0B2A3F06E4F1961BB07712D9D0B901EDC8CEA67AEDDBBA0C7EA08857B6934168AF893E7F419DE51E45EEF8272274D85F89D895E867318D75FADC8AA35FC053B3E02EABA50B2D7B61F0F3EB7A4BCE1DDB43B6887C93580F8BAED5B5236EC69A7D1C42CCE978A98160AC51;
//encrypt RSA CRT-2048
8037C800C8111111413B40AD9D363E2A8192986A4F054C1C4BE30D47EDD76A32D1AA7EE9A9F91E5BA81D20819B5A5293D8C39F8549E3695E13BE12B19405110D2FBED0E393016D231B4201408CDE963377F802579313ECBBB49320B09D8216374EC50A70D70AE1DE5E0E05AD1B7A1F57638674309FB544EB35CBB5535D3C4C727FF633C6CFFF44F0E141B38074B5C92EF26A57B173F3DDE85C5D4F0B2A3F06E4F1961BB07712D9D0B901EDC8CEA67AEDDBBA0C7EA08857B6934168AF893E7F419DE51E45EEF8272274D85F89D8;
//expect:45ACD17EE02228DE45096F1153EF89DBF72933925A17803142A093FD2300CE27CF26A1B38F402E167647035227E0CBB238208A7E166E9DD4F563E04D48C9916C6812AA40AF4715C2D70D32190BC4F9EC2DA0FAD7EFE703AE2808401AA389698BC7428E9172B868E328DA5698CACDBE489EA871225DBEBB238B015828E4B68B274175910D1F72D8D684D24A40077F3A5C75F086A57B733C74CC94C7377A8F555DCB638A4A336344D9B2D53594E7C24BF3FA85705C2E6818B9703EDBBEFDCFA2FC42D3791816025BE4D3045ABF37AEEDF290B90D93E151AFA128E50A271A19AAA7988EBBACF17D26AAF8AAEA0C027186E2715E3A850971F5F16E44DB4FFACE07D09000
803748013895E867318D75FADC8AA35FC053B3E02EABA50B2D7B61F0F3EB7A4BCE1DDB43B6887C93580F8BAED5B5236EC69A7D1C42CCE978A98160AC51;
//decrypt  RSA CRT-2048
8037C900C845ACD17EE02228DE45096F1153EF89DBF72933925A17803142A093FD2300CE27CF26A1B38F402E167647035227E0CBB238208A7E166E9DD4F563E04D48C9916C6812AA40AF4715C2D70D32190BC4F9EC2DA0FAD7EFE703AE2808401AA389698BC7428E9172B868E328DA5698CACDBE489EA871225DBEBB238B015828E4B68B274175910D1F72D8D684D24A40077F3A5C75F086A57B733C74CC94C7377A8F555DCB638A4A336344D9B2D53594E7C24BF3FA85705C2E6818B9703EDBBEFDCFA2FC42D3791816025BE4;
//expect:111111413B40AD9D363E2A8192986A4F054C1C4BE30D47EDD76A32D1AA7EE9A9F91E5BA81D20819B5A5293D8C39F8549E3695E13BE12B19405110D2FBED0E393016D231B4201408CDE963377F802579313ECBBB49320B09D8216374EC50A70D70AE1DE5E0E05AD1B7A1F57638674309FB544EB35CBB5535D3C4C727FF633C6CFFF44F0E141B38074B5C92EF26A57B173F3DDE85C5D4F0B2A3F06E4F1961BB07712D9D0B901EDC8CEA67AEDDBBA0C7EA08857B6934168AF893E7F419DE51E45EEF8272274D85F89D895E867318D75FADC8AA35FC053B3E02EABA50B2D7B61F0F3EB7A4BCE1DDB43B6887C93580F8BAED5B5236EC69A7D1C42CCE978A98160AC519000
8037490138D3045ABF37AEEDF290B90D93E151AFA128E50A271A19AAA7988EBBACF17D26AAF8AAEA0C027186E2715E3A850971F5F16E44DB4FFACE07D0;
javacard-api-samples/rsa.txt · Last modified: 2017/05/13 02:43 (external edit)