1

Need to generate 35 bytes (70 characters) Alphanumerical data using ISO 9797-1 MAC algorithm 3 and padding method 1 in java.

I have tried using below code but its not generating 35 bytes (70 characters) Alphanumerical data and using key as 64 byte key.

public byte[] getRetailMAC(byte[] key, byte[] data) {
    int macSizeBits = 64;

    BlockCipher cipher = new DESEngine();

    Mac mac = new ISO9797Alg3Mac(cipher, macSizeBits);

    KeyParameter keyP = new KeyParameter(key);
    mac.init(keyP);
    mac.update(data, 0, data.length);

    // perform padding manually
    int n = cipher.getBlockSize();
    int zeroPaddingRequired = n - (data.length + n - 1) % n - 1; 
    for (int i = 0; i < zeroPaddingRequired; i++) {
        mac.update((byte) 0x00);
    }

    byte[] out = new byte[macSizeBits / Byte.SIZE];
    mac.doFinal(out, 0);

    return out;
}

and I expect the output is 35 bytes (70 characters) Alphanumerical data but actual output getting above code is :[B@2ee0d183.

Can anyone please help me on this.

Krishna
  • 233
  • 2
  • 6
  • 20

1 Answers1

1
  • The :[B@2ee0d183 is the object id (see Java: Syntax and meaning behind "[B@1ef9157"? Binary/Address?) of your byte-array, it's not the content! The method org.bouncycastle.util.encoders.Hex.toHexString(...) can be used to display the content as a hexadecimal string, i.e. if the byte-array consists of e.g. 3 bytes with the contents 0x42, 0x42 and 0x43, then this method returns the string 414243.
  • The maximum length of the MAC generated by ISO9797Alg3Mac is equal to the block length of the used cipher, i.e. of DES, which is 8 bytes. I.e. the parameter macSizeBits (length in bit) must be (a multiple of 8 and) less than or equal to 64. For larger sizes an exception is thrown in the doFinal-method. For this reason, a MAC with a length of 35 bytes cannot be generated (but of course several MACs can be concatenated until the desired length is reached).
  • Moreover, if no padding is defined in the constructor (as it's currently the case), zero-byte-padding (in this context also called padding method 1) is used by default. This means that the manual implementation of the zero-byte-padding is not necessary (but does not cause an error of course).

The last two points can be tested explicitly, or verified in the source code (https://www.bouncycastle.org/latest_releases.html, section Sources and JavaDoc, bcprov-jdk15on-161.zip).

Topaco
  • 40,594
  • 4
  • 35
  • 62
  • okay..converting now object into String as `org.bouncycastle.util.encoders.Hex.toHexString(out);` is it correct right? and also how we can do this - MACs can be concatenated until the desired length (70 characters) is reached? please help me. thanks @Topaco – Krishna Apr 24 '19 at 12:44
  • Typically, a MAC is used to protect the integrity of a message and prove its authenticity. There is a lot of information on the Internet about this, e.g. https://en.wikipedia.org/wiki/Message_authentication_code. I have no idea what a 35 byte MAC is needed for. This information should rather come from you, e.g. what is the MAC needed for, why is it supposed to be 35 bytes long and why is ISO9797 used with regard to the 8-byte limitation? My suggestion of concatenation should only show a way to reach the desired length (but this approach would be rather unconventional). – Topaco Apr 24 '19 at 13:47
  • Oh, funny, I expected bit padding to be the default. I'm checking what happens if a full block is given though. Confirmed that this is optional zero padding, not zero padding that is *always* applied. – Maarten Bodewes Apr 24 '19 at 14:27
  • Is there any other chipper other than DES to generate 35 bytes (70 characters) Alphanumerical data? Thanks @Topaco – Krishna Apr 25 '19 at 07:38
  • You could search for a MAC that has a length of at least 35 bytes. Probably there is none that is exactly 35 bytes long. A longer MAC must be shortened accordingly. Here is a list of MACs offered by the SunJCE provider: https://docs.oracle.com/en/java/javase/11/security/oracle-providers.html#GUID-A47B1249-593C-4C38-A0D0-68FA7681E0A7, section _MAC_. `HmacSHA512` provides a MAC that is 64 bytes in size which must then be shortened to 35 bytes. Here is an example: https://stackoverflow.com/a/39356436/9014097 (truncation to 35 bytes not included). – Topaco Apr 25 '19 at 09:18