Hash 哈希生成器小程序不使用';我工作不好
下面是一个小程序,它基于Hash 哈希生成器小程序不使用';我工作不好,hash,md5,javacard,Hash,Md5,Javacard,下面是一个小程序,它基于MD5、RIPEMD160、SHA、SHA224、SHA256、SHA384和SHA512,生成输入数据的哈希值: package hashPack; import javacard.framework.*; import javacard.security.CryptoException; import javacard.security.MessageDigest; public class HashMachine extends Applet { //
MD5
、RIPEMD160
、SHA
、SHA224
、SHA256
、SHA384
和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);
}
}
问题是这个小程序返回的值与在线工具返回的值不同
例如,我希望哈希值为012345
(ascii格式)。因此,我将其转换为十六进制值(即303132333435
),并将其发送到我的小程序:
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.
如您所见,小程序返回
406b 29645d 4D 8A 75978984 B5 00 2567 D2
,而返回d6 a9 a9 33 c8 aa fc 51 e5 5a c0 66 2b 6e 4D 4a
。怎么了?您的代码中有一个错误。您的doHash
方法根据两倍长的输入进行散列(它从“XX”而不是“X”计算散列):
update
方法仅适用于长输入-它完成前N个数据块的所有计算,不产生任何输出。doFinal
方法对最后一个数据块执行相同的操作,并将输出复制到输出缓冲区
仅使用第二行:
HashObj.doFinal(buffer, ISO7816.OFFSET_CDATA, buffer[ISO7816.OFFSET_LC], hashedValue, (short) 0);
我知道使用静态变量作为输出会很快破坏EEPROM。我将更改此变量的类型。但为什么输出不正确?
HashObj.doFinal(buffer, ISO7816.OFFSET_CDATA, buffer[ISO7816.OFFSET_LC], hashedValue, (short) 0);