Foreword
PIN entry on Tap to Phone solutions, because of its very sensitive nature, is handled by the Secure Client (and the Secure Backend). The flow is relatively simple, the PIN prompt is triggered by one API call. The output of the PIN entry is provided through a callback.
PIN prompt
To launch the PIN entry screen, once must call the pinEnter()
method from the AOneAppSecurity
class as follows:
SecureClient.getInstance(activity, AOneAppSecurityCbk(activity)) .pinEnter(activity, amount, message, min, max, timeout)
With:
amount: the amount string, including currency (ex: $ 51.00)
message: the customer message (ex: Please enter PIN)
min: the minimum number of PIN digits (usually 4)
max: the maximum number of PIN digits
timeout: the PIN entry timeout in seconds
Once the pinEnter()
function is called the screen control is taken over by our security layer until the user presses Enter, Cancel or the timeout is reached.
PIN entry result
After one of the above events happens (e.g. Enter, Cancel or timeout), display control is given back to the application and the PIN entry result is provided by the pinEnterResult()
callback:
override fun pinEnterResult(params: Any?, status: IAOneAppSecurityCbk.PinStatus, pin: ByteArray?, error: Int) { Log.v("${this::class.java.simpleName}", "pinEnterResult - params: ${params}, status: ${status}, error: ${error}") }
With:
params: optional parameters (null for now)
status: PIN entry result (Success, Cancelled, Timeout, etc…)
pin: the encrypted PIN block
error: error code
PIN block format
The PIN block generated by the Secure Client follows EMV PIN block format recommendations but does not contain the PAN as it would be against PCI security requirements. This is why we call it “pseudo” PIN block.
The partial PIN block is encrypted using the AES-ECB algorithm and a 128 bits AES key, Kpin-session. Kpin-session is unique for each PIN block. The 8 bytes partial PIN block is padded with an 8 bytes random byte string. Kpin-session is wrapped using the RSA-2048 Kpin-pub using the PKCS#1 RSA-OAEP algorithm with SHA-1 as digest.
The format of the partial PIN block cryptogram is:
The format of the PIN block cryptogram changed staring secure client v1.0.9
Object | Length (bytes) | Comments |
---|---|---|
RSA Key ID length | 2 | Length of the key ID (MSB) |
RSA Key ID | var | RSA key ID used for the session key encryption |
Encrypted KEK length | 2 | Length of the encrypted KEK (MSB - should be 512) |
Encrypted KEK | 512 | Encrypted KEK block:
|
Encrypted pseudo PIN block length | 2 | Length of the encrypted PIN block (MSB - should be 16) |
Encrypted pseudo PIN block | 16 | Encrypted pseudo PIN block:
|
HMAC Key ID length | 2 | Length of the HMAC key ID (MSB) |
HMAC Key ID | var | HMAC key ID used for the checksum calculation |
HMAC length | 2 | Length of the HMAC checksum (MSB - should be 32) |
HMAC | 32 | AES-CBC-256 checksum |
The pseudo PIN block is encoded in the following way:
If N is the number of PIN digits, with N in the [4, 12] range, the PIN is encoded in a 16 bytes byte array with the following format:
A prefix of (16 - N) random bytes Bi:
B0 … B(16 - N - 2) = 0xmn where m and n denote the most and least significant nibbles
B(16 - N - 1) = 0xm0, end of prefix
The encoded PIN of N bytes, each byte encoding a PIN digit:
B0(16 - N) … B15 = 0xmd where m(random) and d(PIN digit) denote the most and least significant nibbles
The following table gives an example of the encoding of the encoding of the PIN value “1234”:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
0xB9 | 0x6F | 0x4A | 0x31 | 0x06 | 0x9E | 0x73 | 0x48 | 0x9A | 0xA7 | 0xD3 | 0x60 | 0xD1 | 0x62 | 0xE3 | 0xD4 |