问题
Below, you see an applet that generate hash value of input data based on MD5
, RIPEMD160
, SHA
, SHA224
, SHA256
, SHA384
and SHA512
:
package hashPack;
import javacard.framework.*;
import javacard.security.CryptoException;
import javacard.security.MessageDigest;
public class HashMachine extends Applet {
//outputArray
byte[] hashedValue = new byte[64];
//output Length
short OLength = 0x0000;
//Defining switch case variables for Hash algorithm commands
final byte MD5 = (byte) 0x00;
final byte RIPEMD160 = (byte) 0X01;
final byte SHA = (byte) 0X02;
final byte SHA224 = (byte) 0X03;
final byte SHA256 = (byte) 0X04;
final byte SHA384 = (byte) 0X05;
final byte SHA512 = (byte) 0X06;
public static void install(byte[] bArray, short bOffset, byte bLength) {
new HashMachine();
}
protected HashMachine() {
register();
}
public void process(APDU apdu) {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
try {
switch (buffer[ISO7816.OFFSET_INS]) {
case MD5: {
MessageDigest HashObj = MessageDigest.getInstance(MessageDigest.ALG_MD5, false);
HashObj.reset();
OLength = 16;
if (buffer[ISO7816.OFFSET_LC] > 0) {
doHash(apdu, HashObj, OLength);
} else {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
}
break;
case RIPEMD160: {
MessageDigest HashObj = MessageDigest.getInstance(MessageDigest.ALG_RIPEMD160, false);
HashObj.reset();
OLength = 20;
if (buffer[ISO7816.OFFSET_LC] > 0) {
doHash(apdu, HashObj, OLength);
} else {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
}
break;
case SHA: {
MessageDigest HashObj = MessageDigest.getInstance(MessageDigest.ALG_SHA, false);
HashObj.reset();
OLength = 20;
if (buffer[ISO7816.OFFSET_LC] > 0) {
doHash(apdu, HashObj, OLength);
} else {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
}
break;
case SHA224: {
MessageDigest HashObj = MessageDigest.getInstance(MessageDigest.ALG_SHA_224, false);
HashObj.reset();
OLength = 32;
if (buffer[ISO7816.OFFSET_LC] > 0) {
doHash(apdu, HashObj, OLength);
} else {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
}
break;
case SHA256: {
MessageDigest HashObj = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false);
HashObj.reset();
OLength = 32;
if (buffer[ISO7816.OFFSET_LC] > 0) {
doHash(apdu, HashObj, OLength);
} else {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
}
break;
case SHA384: {
MessageDigest HashObj = MessageDigest.getInstance(MessageDigest.ALG_SHA_384, false);
HashObj.reset();
OLength = 64;
if (buffer[ISO7816.OFFSET_LC] > 0) {
doHash(apdu, HashObj, OLength);
} else {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
}
break;
case SHA512: {
MessageDigest HashObj = MessageDigest.getInstance(MessageDigest.ALG_SHA_512, false);
HashObj.reset();
OLength = 64;
if (buffer[ISO7816.OFFSET_LC] > 0) {
doHash(apdu, HashObj, OLength);
} else {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
}
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
} catch (CryptoException e) {
ISOException.throwIt(((CryptoException) e).getReason());
}
}
public void doHash(APDU apdu, MessageDigest HashObj, short OLength) {
byte[] buffer = apdu.getBuffer();
HashObj.update(buffer, ISO7816.OFFSET_CDATA, buffer[ISO7816.OFFSET_LC]);
HashObj.doFinal(buffer, ISO7816.OFFSET_CDATA, buffer[ISO7816.OFFSET_LC], hashedValue, (short) 0);
Util.arrayCopyNonAtomic(hashedValue, (short) 0, buffer, (short) 0, OLength);
apdu.setOutgoingAndSend((short) 0, OLength);
}
}
The problem is that the values that this applet returns me, are different from the values that online tools return.
For example I want to have hash value of 012345
(in ascii). So I convert it to its hex value (i.e 303132333435
) and I sent it to my applet:
OSC: opensc-tool.exe -s 00a4040006C761819104D7 -s 0000000005303132333435
Using reader with a card: ACS CCID USB Reader 0
Sending: 00 A4 04 00 06 C7 61 81 91 04 D7
Received (SW1=0x90, SW2=0x00)
Sending: 00 00 00 00 05 30 31 32 33 34 35
Received (SW1=0x90, SW2=0x00):
40 6B 29 64 5D 4D 8A 75 97 89 84 B5 00 25 67 D2 @k)d]M.u.....%g.
As you see the applet returns 40 6B 29 64 5D 4D 8A 75 97 89 84 B5 00 25 67 D2
, while online toolsreturn d6 a9 a9 33 c8 aa fc 51 e5 5a c0 66 2b 6e 4d 4a
. What's wrong?
回答1:
There is a bug in your code. Your doHash
method does the hashing as from a twice as long input (it computes the hash from "XX" instead of "X"):
HashObj.update(buffer, ISO7816.OFFSET_CDATA, buffer[ISO7816.OFFSET_LC]);
HashObj.doFinal(buffer, ISO7816.OFFSET_CDATA, buffer[ISO7816.OFFSET_LC], hashedValue, (short) 0);
The update
method is for long inputs only - it does all the computation of the first N data blocks and produces no output. The doFinal
method does the same for the last block of data and it copies the output to the output buffer.
Use the second line only:
HashObj.doFinal(buffer, ISO7816.OFFSET_CDATA, buffer[ISO7816.OFFSET_LC], hashedValue, (short) 0);
来源:https://stackoverflow.com/questions/30074990/hash-generator-applet-doesnt-work-fine