Hash generator applet doesn't work fine

淺唱寂寞╮ 提交于 2019-12-05 06:28:20

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!