Card PIN management

Introduction

Physical cards have an additional security feature i.e. PINs (Personal Identification Number). It is a number used to verify the identity of the cardholder and make transactions more secure. The PIN is required to validate the cardholder when the physical card is used on the terminals (like POS or ATM). Initially a random PIN is set for a newly activated card. The initial random PIN can be securely retrieved and presented to the cardholder through a cardholder facing app. The nCore platform also provides the feature to change the card PIN if the cardholder wishes to set his own preferred PIN.

A PIN is treated as a password and it should be kept secret to prevent unauthorized access to cardholder's accounts and related information.

Types of PINs

There are two types of card PINs and both have different validation processes as given below.

  • An online PIN is entered by the cardholder, then it is transmitted along with the card details to the nCore platform via the merchant acquirer system for authentication. The online PIN is not stored on the card. The nCore platform receives the authentication request in real time from the card network, the platform validates the PIN, then confirms to the merchant terminal where the card is inserted.

  • An offline PIN is entered by the cardholder, then transferred in encrypted form to the card’s integrated chip where the PIN is stored. The chip uses its internal procedures to validate and confirm the PIN to the merchant terminal where the card is inserted without transmitting it in real time to the issuer.

Please note that the Card PIN management features (such as get card PIN and change card PIN) are available for PCI DSS compliant customers. nCore platform provides a set of PCI widgets for non-PCI DSS compliant customers. For further information please refer to the PCI Widget section.

Card PIN Management APIs

There are some pre-requisites, which you have to know before dealing with card PIN management. It is preferred to have knowledge of such cryptographic algorithms as 3DES, AES and RSA . Also you should have an understanding of such concepts as encryption/decryption, Base64 encoding, symmetric/asymmetric keys, PIN block formats.

nCore platform provides the following card PIN management features though APIs:

  • Set card PIN

  • Get card PIN

Change card PIN

A cardholder can change his/her card PIN as required. Send a PUT request to /cards/{id}:changePin endpoint as given below to change the card PIN.

PUT /cards/{id}:changePin

{ "enc_pin": "ncrypt:2:bP6dZTzopk6TTYeP4lETrw: kjQRz3M9wzOFPU3cphAomtHoMv3aC2-CkMtAgiLvYfpy1cEwTm3ag7_caXHFThWN_SBxHpj9aviki9rr7okJKN-Bqd O46d7Uu4Bx9dNo0_Tn9ZcKV7X-dAGLgNViYeAaGbA2jlcESYZZLecqPBq BADQ12DdGV4VfRtEb3pDZRO3VRP1hXL4VgN_H1vRwIwT5vTyBLuzQA 3Lh3xqrlVrrRFHah42oH3YkgaY6M8mc3r3e3pBItNMiwW10wjfO50z7dy 2O0yAGyy-QSWqu4LQYMLKMAPx4wsuEcAQg3Xpmnv3GmP_goAvu88 ASH9u4iKWGh0OtrldQZlmUqiYcq9mWMQ: Ok9OebFuRwQ" }

Please note:

  • Remove "enters" from the sample message given above when testing on sandbox.

  • An encrypted PIN is required to get a successful response.

Card PIN enciphering method

Below you can see the encryption flow:

Please refer to the following steps to encrypt the digital envelope:

1. Generate a 16-byte random <IV component> and encode it into Base64 URL encoding (RFC 4648) to get <b64_IVcomponent>

2. Create a PIN Block <clearPINBlock> in ISO 9564-1 format 1 as given below format:

ISO 9564-1 format 1 = <Format Version><PIN Length><PIN><Random HEX digits to make 8 bytes PIN block>

Below you can find an example of code snippet:

// function createPINBlock(plaintext){
	var pinLength = plaintext.length;
	var pinBlock = '1' + pinLength + plaintext + forge.util.bytesToHex(forge.random.getBytesSync(8));
	pinBlock = pinBlock.substring(0, 16);
	console.log(pinBlock);
}

3. Generate a random 3DES key <3DESkey> of 16 bytes.

Below you can find an example of code snippet:

// function generateDESKey(){
	var key = forge.random.getBytesSync(16);
	var secretKey = forge.util.createBuffer(key, 'raw');
	console.log(secretKey.toHex().toUpperCase());
}

4.1. Encrypt the <clearPINBlock> with <3DESkey>, you will get <encryptedData>

4.2. Transform the <encryptedData> into Hex bytes to get the data in Hex <encryptedDataHex>

4.3. Now encode the <encryptedDataHex> into Base64 URL encoding (RFC 4648), you will get <b64_encryptedData>

Below you can find an example of code snippet:

// function encrypt3DES(key, pinBlock) {
	var secretKey = forge.util.createBuffer(forge.util.hexToBytes(key), 'raw');
	secretKey.putBytes(forge.util.hexToBytes(secretKey.toHex().substring(0, 16), 'raw'));
	
	var cipher = forge.cipher.createCipher('3DES-ECB', secretKey);
	var data = forge.util.createBuffer(forge.util.hexToBytes(pinBlock));
	cipher.start({iv: ''});
	cipher.update(data);
	cipher.finish();
	var encryptedPIN = forge.util.bytesToHex(cipher.output);
	encryptedPIN = encryptedPIN.substring(0, 16);
	console.log(encryptedPIN);
}

5. Encrypt the <3DESkey> with NymCard's shared key <publicKey> in PKCS1 to get <encryptedSecretKey>

6. Encode<encryptedSecretKey> into Base64 URL encoding (RFC 4648) to get <b64_encryptedSecretKey>

Below you can find an example of code snippet:

// function encryptRSA(desKey, pubKey) {
	var publicKey = forge.pki.publicKeyFromPem(pubKey);
	var encryptedData = forge.util.encryptRSA2(forge.util.hexToBytes(desKey), publicKey);
	var encoded = forge.util.base64urlencode(forge.util.encode64(encryptedData));
	console.log(encoded);
}

7. Create a digital envelope with the separator “:” in the format <protocol>:2:<b64_IVcomponent>:<b64_encryptedSecretKey>:<b64_encryptedData> and send the created digital envelope in Change Card PIN request.

Below you can find an example of code snippet:

// function createEnvelope(encodedEncryptedSecretKey, pinBlock) {
	var encodedIV = forge.util.base64urlencode( forge.util.encode64(forge.random.getBytesSync(8)) );
	var encBuffer = forge.util.createBuffer();
	encBuffer.putBytes(forge.util.hexToBytes(pinBlock.substring(0, 16), 'raw'));
	var encodedEncryptedData = forge.util.base64urlencode( forge.util.encode64( encBuffer.bytes()) );
	
	var envelope = `ncrypt:2:${encodedIV}:${encodedEncryptedSecretKey}:${encodedEncryptedData}`;
	console.log(envelope);
}

Encryption example

Below you can find an encryption example steps:

1. Create a PIN Block <clearPINBlock> in ISO 9564-1 format 1 as given below format

Where, for example: Version: 1 PIN Length: 4 PIN: 1234 Random HEX digits: 3CB5055865

<clearPINBlock> = 1412343CB5055865

2. Generate a random 3DES key of 16 bytes

<3DESkey> = 1FB3F48A6D51832CE91C1C734554086D

3.1 Now encrypt the <clearPINBlock> with <3DESkey>, you will get <encryptedData>

<encryptedData> = 3A4F4E79B16E4704

3.2. Transform the <encryptedData> into Hex bytes to get the data in Hex <encryptedDataHex>

3.3. Now convert the <encryptedDataHex> into Base64 URL encoding (RFC 4648), you will get <b64_encryptedData>

<b64_encryptedData> = Ok9OebFuRwQ

4. Encrypt the <3DESkey> with NymCard's shared key <publicKey> in PKCS1 and encode it in Base64 URL encoding (RFC 4648), you will get <b64_encryptedSecretKey>

<b64_encryptedSecretKey> = kjQRz3M9wzOFPU3cphAomtHoMv3aC2-CkMtAgiLvYfpy1cEwTm3ag7_caXHFThWN_SBxHpj9aviki9rr7okJKN-Bqd O46d7Uu4Bx9dNo0_Tn9ZcKV7X-dAGLgNViYeAaGbA2jlcESYZZLecqPBq BADQ12DdGV4VfRtEb3pDZRO3VRP1hXL4VgN_H1vRwIwT5vTyBLuzQA 3Lh3xqrlVrrRFHah42oH3YkgaY6M8mc3r3e3pBItNMiwW10wjfO50z7dy 2O0yAGyy-QSWqu4LQYMLKMAPx4wsuEcAQg3Xpmnv3GmP_goAvu88 ASH9u4iKWGh0OtrldQZlmUqiYcq9mWMQ

5. Generate a 16-byte random <IV component> and convert it into Base64 URL encoding (RFC 4648)

<IV component> = c31378867535cc5d1159613388253dab

<b64_IVcomponent> = wxN4hnU1zF0RWWEziCU9qw

6. Create a digital envelope with the separator “:” in the format <protocol>:2:<b64_IVcomponent>:<b64_encryptedSecretKey>:<b64_encryptedData> and send the created digital envelope in Change Card PIN request. Sample message is given in below table:

Test keys which can be used in the sandbox environment are given in the Test Keys section.

For non-PCI compliant customers:

To change the card PIN, please integrate nCore’s PCI widget in your cardholder facing applications to enable your cardholders to securely change their card PIN. Please check the PCI Widget section for further details.

Get card PIN

For PCI compliant customers:

Send GET request to /cards/{id}:getPin endpoint to get an encrypted card PIN, which can be decrypted by your application to show the PIN in clear form to the cardholder.

GET /cards/{id}:getPin

Where {id} is the card ID and it is a mandatory field.

Card PIN deciphering method

Let's send a Get PIN request and receive the encrypted envelope message as given below.

Get PIN request

{ "enc_pin": "ncrypt:2:xKzHT-2NJ8yCZIv7Ra9oFQ: VETEcevv-ZyndOeLF7CqO-4aNJ6Z5Tha0wcMFoJEDAJAoLsst1ccMSeeMdbJUwq1GfKjCpm5mM wkEn51ZAFqLW43EcNkapSiPPVRJtU5V1z9u4ZGEXi4swPVzY2j0NfaM4a4aGM_WdpKSx6r7m86 vhjI5901GXRd2vpyGAztfL9krOMA7KgLGaVlqj1i-xIaxvGbIDhFVepIWcxTxiSHqwZxLMN1HMojtf2pJacwoq5nOBP3DX3DgdapIdJN8AWCSIpZ8M6n wf4-2Wr8GGTJrUChU1eJiALKZ-lliP8RvIERG9zP3Z41kQDoWP9JlEFr547xREvXIf6IS4a_ixuwrg: 1Ya9e6e0Los" }

Remove "enters" from the sample message given above when testing on sandbox.

Now we will apply the steps to decrypt the Card PIN as shown below.

Steps to decrypt a digital envelope:

1. Parse the digital envelope with separator “:”.

2. Now decode the components <b64_IVcomponent>, <b64_encryptedSecretKey> and <64_encryptedData> with BASE64 (RFC 4648), after that you will get <IVcomponent>, <encryptedSecretKey>, <encryptedData>

Below you can find an example of code snippet:

// function parseEnvelope(envelope) {
	var envelopeComponents = envelope.split(":");			
	var encIVh forge.util.bytesToHex(forge.util.decode64(forge.util.base64urldecode(envelopeComponents[2])));
	var encKey = forge.util.bytesToHex(forge.util.decode64(forge.util.base64urldecode(envelopeComponents[3])));
	var encPIN = forge.util.bytesToHex(forge.util.decode64(forge.util.base64urldecode(envelopeComponents[4])));
	console.log(encIVh);
	console.log(encKey);
	console.log(encPIN);
}

3. Decrypt the <encryptedSecretKey> with the receiver's private key in PKCS1 to get the you will get the 3DES key <3DESkey>

Below you can find an example of code snippet:

// function decryptRSA(encKey, privateKey) {			
	var encryptedSecretKey = forge.util.decode64(forge.util.base64urldecode( encKey ));
	var privateKey = forge.pki.privateKeyFromPem(privateKey);
			
	var decryptedSecretKey = forge.util.decryptRSA2(encryptedSecretKey, privateKey);
	console.log(forge.util.bytesToHex(decryptedSecretKey).toUpperCase());
}

4. Now decrypt <encryptedData> with <3DESkey> so that you will get the clear PIN block <clearPINBlock> in ISO 9564-1 format 1

Below you can find an example of code snippet:

// function decrypt3DES(desKey, encPin) {
	var decryptedSecretKey = forge.util.hexToBytes(desKey);
	var buffer = forge.util.createBuffer(decryptedSecretKey);
	if(buffer.length() !== 24) {
		buffer.putBytes(forge.util.hexToBytes(buffer.toHex().substring(0, 16), 'raw'));
	}
	var decipher = forge.cipher.createDecipher('3DES-ECB', buffer.bytes());

	var encryptedData = forge.util.hexToBytes(encPin);
	
	var dataBuffer = forge.util.createBuffer(encryptedData);
	if(dataBuffer.length() !== 16) {
		dataBuffer.putBytes(forge.util.hexToBytes(dataBuffer.toHex().substring(0, 16), 'raw'));
	}

	decipher.start({iv: ''});
	decipher.update(dataBuffer);
	var result = decipher.finish(); 
	var pinBlock = decipher.output.toHex();
	var pinLength = pinBlock.substring(1, 2);
	var pin = pinBlock.substring(2, parseInt(pinLength) + 2);
	console.log(pin);
}

5. Now parse the clear PIN block as per the following ISO 9564-1 format 1, you will get the clear PIN <PIN>

ISO 9564-1 format 1 = <Format Version><PIN Length><PIN><Random HEX digits to make 8 bytes PIN block>

Test keys which can be used in the sandbox environment are given in the Test Keys section.

For non-PCI compliant customers:

To retrieve the card PIN and show it to the cardholder, please integrate nCore’s PCI widget in your cardholder facing applications to enable your cardholders to securely retrieve and see their card PIN. Please check the PCI Widget section for further details.

Decryption example

Below you can find a decryption example steps:

1. Parse the digital envelope with separator “:” as given below.

2. Now decode the components <b64_IVcomponent>, <b64_encryptedSecretKey> and <64_encryptedData> with BASE64 (RFC 4648), after that you will get <IVcomponent>, <encryptedSecretKey>, <encryptedData> as given below.

<IVcomponent> = c4acc74fed8d27cc82648bfb45af6815

<encryptedSecretKey> = VETEcevv+ZyndOeLF7CqO+4aNJ6Z5Tha0wcMFoJEDAJAoLsst1ccMSeeMdbJUwq1 GfKjCpm5mMwkEn51ZAFqLW43EcNkapSiPPVRJtU5V1z9u4ZGEXi4swPVzY2j0NfaM4a4aGM/WdpKSx6r7m 86vhjI5901GXRd2vpyGAztfL9krOMA7KgLGaVlqj1i+xIaxvGbIDhFVepIWcxTxiSHqwZxLMN1HMojtf2pJacwoq 5nOBP3DX3DgdapIdJN8AWCSIpZ8M6nwf4+2Wr8GGTJrUChU1eJiALKZ+lliP8RvIERG9zP3Z41kQDoWP9JlE Fr547xREvXIf6IS4a/ixuwrg==

<encryptedData> = D586BD7BA7B42E8B

3. Decrypt the <encryptedSecretKey> with the receiver's private key in PKCS1 to get the you will get the 3DES key <3DESkey>

<3DESkey> = 9D233E02CD9D26E3519768B50B0BEC31

4. Now decrypt <encryptedData> with <3DESkey> so that you will get the clear PIN block <clearPINBlock> in ISO 9564-1 format 1

<clearPINBlock> = 141234284C1B97D0

5. Now parse the clear PIN block as per the following ISO 9564-1 format 1, you will get the clear PIN <PIN>

ISO 9564-1 format 1 = <Format Version><PIN Length><PIN><Random HEX digits to make 8 bytes PIN block>

<clearPINBlock> = <1><4><1234><284C1B97D0>

<PIN> = <1234>

Test keys which can be used in the sandbox environment are given in the Test Keys section.

Test Keys

You can use the following test keys to perform Get and Change PIN operations.

Remove "enters" from the Test keys given below when testing.

Card PIN Controls

The card PIN settings such as PIN length, PIN type, and PIN retries are defined on the card product. A card inherits all of the PIN setting from the card product. When the cardholder performs a transaction with an incorrect PIN (bad PIN), a counter shall be maintained and updated at the card level to keep track of successive bad PIN attempts.

Before reaching the threshold if the cardholder is able to perform a successful PIN verification, then the counter shall be reset. If the bad PIN retries threshold is achieved, the card status shall be automatically changed to suspended status and the status reason code shall indicate that the card is suspended because PIN retries are exhausted.

When the card is suspended, all POS and ATM authorizations are blocked. The card status can be changed from suspended to active. The cardholder KYC must be performed before resetting the PIN, the PIN counter and the card status. Once KYC is verified then you can perform the following steps to update card PIN and card status.

  • Call change PIN API to reset the card PIN Send PUT request to /cards/{id}:changePin endpoint as given below.

PUT /cards/{id}:changePin

{ "enc_pin": "ncrypt:2:bP6dZTzopk6TTYeP4lETrw: kjQRz3M9wzOFPU3cphAomtHoMv3aC2-CkMtAgiLvYfpy1cEwTm3ag7_caXHFThWN_SBxHpj9aviki9rr7okJKN-Bqd O46d7Uu4Bx9dNo0_Tn9ZcKV7X-dAGLgNViYeAaGbA2jlcESYZZLecqPBq BADQ12DdGV4VfRtEb3pDZRO3VRP1hXL4VgN_H1vRwIwT5vTyBLuzQA 3Lh3xqrlVrrRFHah42oH3YkgaY6M8mc3r3e3pBItNMiwW10wjfO50z7dy 2O0yAGyy-QSWqu4LQYMLKMAPx4wsuEcAQg3Xpmnv3GmP_goAvu88 ASH9u4iKWGh0OtrldQZlmUqiYcq9mWMQ: Ok9OebFuRwQ" }

  • Once you change the card PIN you can reset the card status from Suspended to Active using the change card status API Send PUT request to /cards/{id}:statuschange endpoint to change card status from suspended to active as given below.

PUT /cards/{id}:statuschange

{

“status”: “ACTIVE”, “status_reason_code”: “a1”

}

Last updated