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:
AOneAppSecurity.getInstance(this.context, AOneAppSecurityCbk(this.activity)) .pinEnter(activity, amount, message, min, max, timeout, feedback)
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
feedback: physical and audible feedback flags (ex:
AOneAppSecurity.PIN_ENTRY_FB_HAPTIC or AOneAppSecurity.PIN_ENTRY_FB_SOUND)
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:
E(PIN block) = IDLength||ID(Kpin-pub)||ERSA-OAEP-SHA-1(Kpin-pub, Kpin-session)||Eaes-ecb(Kpin-session, pin-block) |
Which translates into:
Object | Length (bytes) | Comments |
---|---|---|
ID length | 1 | Length of the key ID |
Key ID | var | RSA key ID used for the session key encryption |
Encrypted KEK | 256 | Encrypted KEK block:
|
Encrypted pseudo PIN block | 256 | Encrypted pseudo PIN block:
|
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 |
Example
Below is an example of data received after a successful PIN entry:
07544553544b45592cc79bfa8faf135681df750ad36f2bc347c48ba49f6a3d7d17df442f46edee2783b5f f0b6e82d5f8be7eb47063a992f6e43f1303dc715eb1049b03a4465358485276304d3165e9bb877c864693 7813dbb396b97a3570564e818c5df82b073a950022badb8c39ecf50e1366fb0bcc8e9474bc1bedba5da3d feb298a300c90fd5b5c7cfc0f3ca88b6239fdf120a96083a22e0ce319c628b309519d9f1eaa675dd433d0 e7e5e8dbed56fc293431f7e5f57e76e9bd6930c89e268f07996f2275e76363250b437137942c0e42a5d83 b60a56862ad67d11254f1557eaeecc583f51d88719bcad3b09b262459a5a12ab30b18b02101cb17980749 78f429eb06ad64439914b18234b1c80f9040f1649f1a2894e7
Which can be split into:
The key ID length:
07
The key ID:
544553544b45
The encrypted KEK:
2cc79bfa8faf135681df750ad36f2bc347c48ba49f6a3d7d17df442f46edee2783b5ff0b6e82d5f8be7eb 47063a992f6e43f1303dc715eb1049b03a4465358485276304d3165e9bb877c8646937813dbb396b97a35 70564e818c5df82b073a950022badb8c39ecf50e1366fb0bcc8e9474bc1bedba5da3dfeb298a300c90fd5 b5c7cfc0f3ca88b6239fdf120a96083a22e0ce319c628b309519d9f1eaa675dd433d0e7e5e8dbed56fc29 3431f7e5f57e76e9bd6930c89e268f07996f2275e76363250b437137942c0e42a5d83b60a56862ad67d11 254f1557eaeecc583f51d88719bcad3b09b262459a5a12ab30b18b02101cb1798074978f429eb06ad6443 99
The encrypted pseudo PIN-block:
14b18234b1c80f9040f1649f1a2894e7
Applying an RSA decryption (RSA/ECB/OAEPWithSHA-256AndMGF1Padding
) on the “encrypted KEK” block will lead to:
The KEK:
7df1d2d78e33346c316c5099d4a7857b
The IV:
00000000000000000000000000000000
Applying a AES decryption (AES/CBC/NoPadding
) on the “encrypted pseudo PIN-block” will provide the following pseudo PIN block data:
4ef90b543d09a8151fcefe0058585858
From which we can extract the PIN 8888