Skip to content

Commit

Permalink
added ISO/IEC 9797-1 padding method 3 + test
Browse files Browse the repository at this point in the history
  • Loading branch information
T-eli committed Dec 21, 2023
1 parent 36c19ed commit 2187d42
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
*/
public interface CryptogramDataBuilder {

final PaddingMethod ZERO_PADDING = data -> data;
final PaddingMethod NO_PADDING = data -> data;

/**
* ISO/IEC 9797-1 padding method 1
Expand All @@ -45,10 +45,24 @@ public interface CryptogramDataBuilder {

/**
* ISO/IEC 9797-1 padding method 2
* for Block size 8, n = 64
* for Block size 8, n = 64
*/
final PaddingMethod ISO9797Method2 = data -> ISO9797Method1.apply(data + "80");

/**
* ISO/IEC 9797-1 padding method 3
* for Block size 8, n = 64
*/
final PaddingMethod ISO9797Method3 = data -> {
StringBuilder sb = new StringBuilder();
String D = ISO9797Method1.apply(data);
String Ld = ISOUtil.byte2hex(ISOUtil.int2byte(data.length() / 2));
String Lp = ISO9797Method1.apply(Ld);
Lp = Ld.length() % 16 == 0 ? "" : Lp.substring(Ld.length());
return sb.append(Lp).append(Ld).append(D).toString();
};


/**
* Method that selects the minimum set of data elements recommended for
* the generation of application cryptograms described in EMV Book 2 sec 8.1.1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
import java.util.Arrays;
import java.util.Random;

import static org.jpos.emv.cryptogram.CryptogramDataBuilder.ISO9797Method2;
import static org.jpos.emv.cryptogram.CryptogramDataBuilder.ISO9797Method1;

import static org.jpos.emv.cryptogram.CryptogramDataBuilder.*;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

Expand All @@ -18,7 +16,6 @@
*/
public class CryptogramDataBuilderTest {

Random r;
byte[] r0;
byte[] r1;
byte[] r2;
Expand Down Expand Up @@ -56,7 +53,7 @@ void testPaddingMethod2() {

// if data length is not multiple of n, data is padded with 1 bit followed by 0s
if (b.length % n > 0) {
byte[] padding = Arrays.copyOfRange(b_padded, b.length, b_padded.length);
byte[] padding = Arrays.copyOfRange(b_padded, b.length, b_padded.length);
assertEquals(((byte) 0x80), padding[0]);
if (padding.length > 1) {
assertArrayEquals(ISOUtil.concat(new byte[]{(byte) 0x80}, new byte[n - b.length % n - 1]), padding);
Expand All @@ -68,7 +65,6 @@ void testPaddingMethod2() {
@Test
void testPaddingMethod1() {
int n = 8; // block size

Arrays.asList(r0, r1, r2).forEach(b -> {
byte[] b_padded = ISOUtil.hex2byte(ISO9797Method1.apply(ISOUtil.hexString(b)));

Expand All @@ -84,11 +80,41 @@ void testPaddingMethod1() {
assertArrayEquals(b, b_padded);
}

// if data length is not multiple of n, data is padded with 0s
// if data length is not multiple of n, data is padded with 0s
if (b.length % n > 0) {
assertArrayEquals(ISOUtil.concat(b, new byte[n - b.length % n]), b_padded);
}
});
}

@Test
void testPaddingMethod3() {
int n = 8; // block size
Arrays.asList(r0, r1, r2).forEach(b -> {
byte[] b_padded = ISOUtil.hex2byte(ISO9797Method3.apply(ISOUtil.hexString(b)));

assertEquals(0, b_padded.length % n);

// if data is empty, padded data should be a 2 block of 0s
if (b.length == 0) {
assertArrayEquals(new byte[n * 2], b_padded);
}

// if data length is multiple of n, pad only length Block
if (b.length % n == 0 && b.length > 0) {
String pad = ISOUtil.byte2hex(b_padded).substring(0, 2 * (b_padded.length - b.length));
assertArrayEquals(b, Arrays.copyOfRange(b_padded, b_padded.length - b.length, b_padded.length));
assertArrayEquals(ISOUtil.int2byte(b.length), ISOUtil.hex2byte(ISOUtil.unPadLeft(pad, '0')));
}

// if data length is not multiple of n, data is right padded with 0s, then left padded with length Block
if (b.length % n > 0) {
byte[] rpad = new byte[n - b.length % n];
byte[] lpad = Arrays.copyOfRange(b_padded, 0, b_padded.length - b.length - rpad.length);
assertArrayEquals(ISOUtil.int2byte(b.length), ISOUtil.hex2byte(ISOUtil.unPadLeft(ISOUtil.byte2hex(lpad), '0')));
assertArrayEquals(ISOUtil.concat(ISOUtil.concat(lpad, b), rpad), b_padded);
}
});
}

}

0 comments on commit 2187d42

Please sign in to comment.