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);