I built examples of SM4 and SM2 using templates. SM4 can be used and downloaded to Simulator:
eJava Token OR E5 , but SM2 compiler is not a problem and can not be used in Simulator:
eJava Token OR E5 . Here is the code:
/*
* @file sm44.java
* @version v1.0
* Package AID: 4A617661436172644F53
* Applet AID: 4A617661436172644F5302
* @brief The ALgorithm of DES 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 sm ;
import javacard.framework.*;
import javacard.security.Signature;
import javacard.security.KeyBuilder;
import javacardx.crypto.Cipher;
import javacardx.shangmi.SMConstant;
import javacardx.shangmi.SM4Key;
import javacard.security.KeyPair;
import javacardx.shangmi.SM2PrivateKey;
import javacardx.shangmi.SM2PublicKey;
public class sm44 extends Applet
{
private static final byte INS_ECB_e = (byte)0x20;
private static final byte INS_ECB_d = (byte)0x21;
private static final byte INS_sm2_S = (byte)0x22;
private static final byte INS_sm2_V = (byte)0x23;
private static final byte INS_sm2_e = (byte)0x32;
private static final byte INS_sm2_d = (byte)0x33;
// 对称算法SM4
private SM4Key SK_SM4_KEY; // SM4 key
private Cipher CP_SM4_ECB; // SM4 ECB加解密
private Cipher CP_SM4_CBC; // SM4 CBC加解密
private Signature SM4_MAC; // SM4 MAC
// 非对称算法SM2
private KeyPair SM2KeyPair;
private SM2PublicKey SM2_PUB_KEY;
private SM2PrivateKey SM2_PRI_KEY;
private Cipher CP_SM2_X509;
private Signature sm2_sig;
private byte[] tempbuf;
short len1;
public final byte[] sm4Key =
{ 0x01,(byte)0x23,(byte)0x45,(byte)0x67,(byte)0x89,(byte)0xAB,(byte)0xCD,(byte)0xEF,(byte)0xFE,(byte)0xDC,(byte)0xBA,(byte)0x98,(byte)0x76,(byte)0x54,(byte)0x32,(byte)0x10};
public final byte[] sm2priKey =
{ 0x13,(byte)0x00,(byte)0x02,(byte)0x3B,(byte)0x56,(byte)0x48,(byte)0x08,(byte)0xC3,(byte)0xE0,(byte)0x88,(byte)0x2F,(byte)0xD5,(byte)0xC8,(byte)0xDC,(byte)0x97,(byte)0xF4,
(byte)0xFB,(byte)0xEA,(byte)0x80,(byte)0xFF,(byte)0x28,(byte)0x55,(byte)0x83,(byte)0x9C,(byte)0x3E,(byte)0x14,(byte)0xB8,(byte)0x1B,(byte)0x68,(byte)0x5C,(byte)0x61,(byte)0xED
};
public final byte[] sm2PubKey =
{
(byte)0xAF,(byte)0x39,(byte)0x66,(byte)0x7F,(byte)0x4C,(byte)0x91,(byte)0x90,(byte)0x7F,(byte)0x85,(byte)0x5C,(byte)0x1A,(byte)0xD1,(byte)0x8B,(byte)0xAB,(byte)0xEC,(byte)0x12,
(byte)0x99,(byte)0x88,(byte)0x0A,(byte)0x07,(byte)0xE6,(byte)0xB4,(byte)0xB7,(byte)0xB2,(byte)0xEE,(byte)0xF5,(byte)0x50,(byte)0xBE,(byte)0x40,(byte)0xB3,(byte)0x8E,(byte)0x8D,
(byte)0x58,(byte)0x92,(byte)0x90,(byte)0x14,(byte)0x8C,(byte)0xFC,(byte)0xA8,(byte)0xC2,(byte)0x7B,(byte)0x9D,(byte)0xE6,(byte)0x14,(byte)0xE8,(byte)0xE3,(byte)0xC2,(byte)0x4D,
(byte)0xFD,(byte)0xFE,(byte)0x69,(byte)0x1A,(byte)0xB3,(byte)0x87,(byte)0x0E,(byte)0x2C,(byte)0x68,(byte)0xA5,(byte)0xF4,(byte)0x43,(byte)0xB7,(byte)0xC7,(byte)0x2A,(byte)0x52
};
public sm44()
{
// 对称算法SM4
SK_SM4_KEY = (SM4Key)KeyBuilder.buildKey(SMConstant.KEY_TYPE_SM4,(short)128,false);
CP_SM4_ECB = Cipher.getInstance(SMConstant.CIPHER_ALG_SM4_ECB_NOPAD,false);
CP_SM4_CBC = Cipher.getInstance(SMConstant.CIPHER_ALG_SM4_CBC_NOPAD,false);
SM4_MAC = Signature.getInstance( SMConstant.SIGNATURE_ALG_SM4_MAC_ISO9797_M2, false );
// 非对称算法SM2
CP_SM2_X509 = Cipher.getInstance(SMConstant.CIPHER_ALG_SM2, false);
SM2_PUB_KEY = (SM2PublicKey)KeyBuilder.buildKey(SMConstant.KEY_TYPE_SM2_PUBLIC, (short)512, false);
SM2_PRI_KEY = (SM2PrivateKey)KeyBuilder.buildKey(SMConstant.KEY_TYPE_SM2_PRIVATE, SMConstant.KEY_LENGTH_SM2, false);
SM2KeyPair = new KeyPair(SM2_PUB_KEY, SM2_PRI_KEY);
sm2_sig = Signature.getInstance( SMConstant.SIGNATURE_ALG_SM2_E, false );
// tempbuf = new byte[255];
JCSystem.requestObjectDeletion();
}
public static void install(byte[] bArray, short bOffset, byte bLength)
{
new sm44().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_ECB_e:
SM4_ECB(sm4Key, (short)0, sm4Key, (short)0, (short)16, buf, (short)0, true);
apdu.setOutgoingAndSend((short)0,(short)16);
break;
case INS_ECB_d:
SM4_ECB(sm4Key, (short)0, sm4Key, (short)0, (short)16, buf, (short)0, false);
apdu.setOutgoingAndSend((short)0,(short)16);
break;
/* case INS_sm2_S:
// SM2_PRI_KEY.setS(sm2priKey, (short)0,(short)32);
// CP_SM2_X509.init(SM2_PRI_KEY, Cipher.MODE_DECRYPT);
// len1=sm2_sig.sign(sm4Key, (short)0, (short)16, buf, (short)0);
Util.arrayCopy(sm4Key,(short)0,buf,(short)0,(short)16);
apdu.setOutgoingAndSend((short)0,(short)16);
break;
case INS_sm2_e:
SM2_PUB_KEY.setW(sm2PubKey, (short)0,(short)64);
len1 =SM2PublicEncode(SM2_PUB_KEY,sm4Key, (short)0, (short)16, buf, (short)0);
Util.arrayCopy(buf,(short)0,tempbuf,(short)0,len1);
apdu.setOutgoingAndSend((short)0,(short)len1);
break;
case INS_sm2_d:
SM2_PRI_KEY.setS(sm2priKey, (short)0,(short)32);
len1= SM2PrivateDecode(SM2_PRI_KEY, tempbuf, (short)0, len1, buf, (short)0);
apdu.setOutgoingAndSend((short)0,(short)len1);
break;
*/
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
//sm4
public short SM4_ECB(byte key[], short koffset, byte src[], short soffset,
short slength, byte dest[], short doffset, boolean encrpt_mark)
{
SK_SM4_KEY.setKey(key, koffset);
if (encrpt_mark == true)
{
CP_SM4_ECB.init(SK_SM4_KEY, Cipher.MODE_ENCRYPT);
}
else
{
CP_SM4_ECB.init(SK_SM4_KEY, Cipher.MODE_DECRYPT);
}
return CP_SM4_ECB.doFinal(src, soffset, slength, dest, doffset);
}
public short SM4_CBC(byte key[], short koffset, byte buffer[], short boffset, short blength,
byte src[], short soffset, short slength, byte dest[], short doffset, boolean encrpt_mark)
{
SK_SM4_KEY.setKey(key, koffset);
if (encrpt_mark == true)
{
CP_SM4_CBC.init(SK_SM4_KEY, Cipher.MODE_ENCRYPT, buffer, boffset, blength);
}
else
{
CP_SM4_CBC.init(SK_SM4_KEY, Cipher.MODE_DECRYPT, buffer, boffset, blength);
}
return CP_SM4_CBC.doFinal(src, soffset, slength, dest, doffset);
}
//sm2
/*public short SM2PublicEncode(SM2PublicKey sm2_pub_key, byte inbuff[], short offs_inbuff, short len_inbuff, byte output[], short offs_output)
{
CP_SM2_X509.init(sm2_pub_key, Cipher.MODE_ENCRYPT);
return CP_SM2_X509.doFinal(inbuff, offs_inbuff, len_inbuff, output, offs_output);
}
public short SM2PrivateDecode(SM2PrivateKey sm2_pri_key, byte inbuff[], short offs_inbuff, short len_inbuff, byte output[], short offs_output)
{
CP_SM2_X509.init(sm2_pri_key, Cipher.MODE_DECRYPT);
return CP_SM2_X509.doFinal(inbuff, offs_inbuff, len_inbuff, output, offs_output);
}
*/
}