You can copy and use it directly or you can download the JCIDE project from the attachment and build it.
Code: Select all
/*
* @file HashSample.java
* @version v1.0
* Package AID: 4A617661436172644F53
* Applet AID: 4A617661436172644F5305
* @brief The ALgorithm of Hash 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.*;
import javacardx.crypto.*;
public class HashSample extends Applet
{
private static final byte INS_GEN_HASH = (byte)0x50;
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 InitializedMessageDigest sha1;
private InitializedMessageDigest sha256;
private InitializedMessageDigest sha512;
public HashSample()
{
flags = JCSystem.makeTransientByteArray(FLAGS_SIZE, JCSystem.CLEAR_ON_DESELECT);
//Creates a InitializedMessageDigest object instance of the ALG_SHA algorithm.
sha1 = MessageDigest.getInitializedMessageDigestInstance(MessageDigest.ALG_SHA, false);
//Creates a InitializedMessageDigest object instance of the ALG_SHA_256 algorithm.
sha256 = MessageDigest.getInitializedMessageDigestInstance(MessageDigest.ALG_SHA_256, false);
//Creates a InitializedMessageDigest object instance of the ALG_SHA_512 algorithm.
sha512 = MessageDigest.getInitializedMessageDigestInstance(MessageDigest.ALG_SHA_512, false);
JCSystem.requestObjectDeletion();
}
public static void install(byte[] bArray, short bOffset, byte bLength)
{
new HashSample().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 (byte)INS_GEN_HASH:
generateHash(apdu, len);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
//Generate Hash
private void generateHash(APDU apdu, short len)
{
byte[] buffer = apdu.getBuffer();
boolean hasMoreCmd = (buffer[ISO7816.OFFSET_P1] & 0x80) != 0;
InitializedMessageDigest hash = null;
short resultLen = 0;
short offset = ISO7816.OFFSET_CDATA;
switch (buffer[ISO7816.OFFSET_P1] & 0x7f)
{
case 0:
hash = sha1;
resultLen = MessageDigest.LENGTH_SHA;
break;
case 1:
hash = sha256;
resultLen = MessageDigest.LENGTH_SHA_256;
break;
case 2:
hash = sha512;
resultLen = MessageDigest.LENGTH_SHA_512;
if (hash == null)
{
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
break;
default:
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
break;
}
if (buffer[ISO7816.OFFSET_P2] == 0) //first block
{
//Reset the MessageDigest object to the initial state.
hash.reset();
}
if (hasMoreCmd)
{
//Accumulate a hash of the input data.
hash.update(buffer, offset, len);
}
else
{
//Generate a hash of all the input data.
short ret = hash.doFinal(buffer, offset, len, buffer, (short)0);
Util.arrayFillNonAtomic(flags, (short)0, (short)flags.length, (byte)0);
apdu.setOutgoingAndSend((short)0, ret);
}
}
}
Note:
The purpose of this example is only used to show the usage of Hash algorithm .