PIN operations using PKI
PIN operations using PKI
Endpoint for Card PIN operations using public key cryptography.
Note: If this endpoint is used, the client must make sure that the RSA key pair is generated and used by the card-holder device, giving no access to the private RSA key to any other system. This way, no other system will have any means to access the PIN code.
Endpoints
Previous
View PIN (Deprecated)This operation retrieves card PIN encrypted with temporary PIN encryption key (tzpk) and tzpk encrypted
with the provided RSA public key.
**Note:** The card-holder device must be generating the RSA key, and must not allow any other system to
access the private RSA key. The RSA key should be a temporary one-time use key.
### Example flow
#### Step 1, executed on the CARD-HOLDER DEVICE, generating an RSA key pair
// generate RSA key pair
var kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
var keyPair = kpg.generateKeyPair();
var publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
#### Step 2, executed on the CLIENT BACK-END, requesting the encrypted PIN from the API
// controlId received from pincontrol API
var controlId = "83fa5f55-3dd7-453a-8233-4242a6bad179";
// public RSA key, generated by the card-holder device in Step 1
var publicKey = // fetched from the device
// make request
var pinResponse = pinApiClient.post()
.uri("/pin/v2/view?auditUser={user}", "test")
.bodyValue(Map.of(
"controlId", controlId,
"publicKey", publicKey
))
.retrieve()
.bodyToMono(ViewPinResponse.class)
.block();
#### Step 3, executed on the CARD-HOLDER DEVICE, decrypting the PIN
// response from the API call done in Step 2, given by the backend
var pinResponse = // given by the backend
// decrypt received tzpk with private key
var rsa = Cipher.getInstance("RSA/ECB/NoPadding");
rsa.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
var decryptedTzpk = rsa.doFinal(Base64.getDecoder().decode(pinResponse.getTzpk()));
// convert double-length key to triple-length - used if the library support only triple-length 3DES
var tzpk = new byte[24];
System.arraycopy(decryptedTzpk, 0, tzpk, 0, 16);
System.arraycopy(decryptedTzpk, 0, tzpk, 16, 8);
// decrypt pinBlock with tzpk
var des = Cipher.getInstance("DESede/ECB/NoPadding");
des.init(Cipher.DECRYPT_MODE, new SecretKeySpec(tzpk, "DESede"));
var decryptedPinBlock = Hex.toHexString(des.doFinal(Base64.getDecoder().decode(pinResponse.getPinBlock())));
Next