Encrypted PIN Transfer

This guide describes how to implement secure PIN transfer for your end-users.

📘

Applicable only for the request that accepts the Signing-Method header.

Encrypted PIN Transfer

This feature allows you to transfer your end-users signing methods (PIN, Emergency Code, Biometrics) in a secure and encrypted way so that it is not visible on your system in any way. Your system won't be able to view or read the end-user signing method's value.

This feature also ensures that the original end-user request body is not tampered with and helps avoid duplicate transactions.

Flowchart

Encrypted PIN Transfer Flowchart

Encrypted PIN Transfer Flowchart

📘

View the TypeScript code example for Encrypted PIN Transfer.

1. Generate random AES 256-bit key

First, generate a random AES 256-bit key.

2. Generate a random iv vector (12 bytes)

Next, generate a random iv vector which should be 12 bytes.

3. Encrypt the AES 256-bit key

Next, encrypt the randomly generated AES 256-bit key with the AWS RSA-2048 public key that we expose in our publicly available endpoint:

Endpoint:

GET https://api-wallet.venly.io/api/security

Response Body:

{
    "success": true,
    "result": {
            "encryptionKeys": [
                {
                    "id": "837943da-82aa-49c5-bab7-503010985ae9",
                    "keyspec": "RSA_2048",
                    "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnDcmfHx3yZxwgZW7r+iUlUdI4a6Ot5WP8P4gzc/emfafLgOGQCoZue6n99BD6iRynnwqHUKd3fS50UX5vmZmXOJGHXlXCRsv5Z1/P32s/q5bLnTGpmzZOQXeiaOMbXgcOWcS0XhVGfioB3VsfURFBOU7okmMY0iAPPA7cdBK5fLTb0CYulMdIKfgWzeBBbqT0J6mRdUfbvXqA2gOLmaZRXKerdJUBbnNc3oOxgsk2noMlyOUId6SZsJYxQZRyjErBSjM+qNitEYLKO8tlxiPtLFWOGAa782nSMNJaLcdGWdz5TeADyvlJbbsvItA1lDWTbnJQyeN0bMDzL5XYcPTkQIDAQAB",
                    "encryptionAlgorithm": "RSAES_OAEP_SHA_256",
                }
            ]
        
    }
}

4. Prepare the Request Body

Generate a SHA256 hash based on the request body.

Example Request Body:

{
  "transactionRequest": {
    "type" : "TRANSFER",
    "secretType" : "MATIC",
    "walletId": "56137f2d-b4e9-42de-943b-cee828eb222a",
    "to" : "0x8D6331D6C5ba3306961F0b4Ea13ff13aa43560b9",
    "value": 1
  }
}

Example SHA256 Hash:

9ad9900886a75c33c327168ed6b0f8892eeffab26369e74082bc120887653762

5. Encrypt Signing-Method body with the Raw AES key

Next, encrypt the Signing-Method body with your raw AES key. The structure of the Signing-Method body is as follows:

ParamDescriptionRequired?
idThe unique ID of the signing method.
valueThe value of the signing method.
physicalDeviceIdThe physicalDeviceId which is the unique ID of the user's device. (Applicable for BIOMETRIC only)
idempotencyKeyA unique UUID for every request.
signature.typeThis will be sha256
signature.valueSHA256 encoded hash of the JSON request body. - from Step#4
{
  id: string,
  value: string,
  idempotencyKey: string,
  signature: {
    type: 'sha256',
    value: string
  }
}

Example Signing-Method body with PIN:

{
   "id":"2bed9491-cdf2-454f-bdfa-716c94cbd922",
   "value":"123456",
   "idempotencyKey": "9ee45da6-193b-4b07-bdd5-92f5602bcf62",
   "signature":{
      "type":"sha256",
      "value":"9ad9900886a75c33c327168ed6b0f8892eeffab26369e74082bc120887653762"
   }
}

Example Signing-Method body with Emergency Code:

{
   "id":"a2ffea97-c199-4685-928d-b34b6f6b2133",
   "value":"UvHSS5SCYek3U2W9h4gEUa9VZ",
   "idempotencyKey": "d06e7754-4c27-4418-8f85-0eb4337a717b",
   "signature":{
      "type":"sha256",
      "value":"54f6e79117c0dc43e1bba7e57303c81da3588703e068f723bb1a7a410c6e0230"
   }
}

Example Signing-Method body with Biometric:

{
   "id":"64c10e41-114a-4ce7-9d02-7df48ba360e6",
   "value":"2f08ae38-b3b9-4857-b46e-3b20e1a936f8",
   "physicalDeviceId": "312b26a0-e6de-4d33-a011-c17cd5fb5e7f",
   "idempotencyKey": "659386e2-4c5a-4c1f-80c7-9e30ff65265e",
   "signature":{
      "type":"sha256",
      "value":"cd0d7f18ca78e1466dd593d88a21deabb80ee42069159e28ddfaa2ac0eb9de5c"
   }
}

6. Prepare Encrypted-Signing-Method Header

6.1 Preparing JSON Body for Encrypted-Signing-Method

Next, prepare the following JSON body.

ParamDescription
encryption.typeThis will be AES/GCM/NoPadding.
encryption.key.encryptedValueThe AES key that is encrypted with RSA-2048 public key (GET /api/security) - from Step#3
encryption.key.encryptionKeyIdThe value corresponds to the result.encryptionKeys.id param in the response body of the GET /api/security endpoint - from Step#3
encryption.ivYour randomly generated iv vector (12 bytes). - from Step#2
valueThe body of the Signing-Method that is encrypted with the raw AES key. - from Step#5
{
    "encryption":{
        "type":"AES/GCM/NoPadding",
        "key":{
           "encryptedValue": "base64string", 
           "encryptionKeyId": "<uuid>"
        	},
        "iv":"base64string" 
    },
    "value":"base64string"
}

6.2 BASE64 Encode the Body

Next, you have to base64 encode the JSON body which is to be passed in the Encrypted-Signing-Method header.

7. Send the correct header

There are two ways to supply the signing method in the header:

7.1 For Encrypted Transfer (Encrypted-Signing-Method)

You need to send the JSON base64 encoded body in the Encrypted-Signing-Method header from the previous step. The Encrypted-Signing-Method indicates that the signing method and the request body are encrypted.

7.2 For non-encrypted Transfer (Signing-Method)

The Signing-Method header can be passed as usual for non-encrypted transfers.

ParameterParam TypeValueDescriptionExample Value
Signing-MethodHeaderid:valueid: This is the ID of the signing method
value: This is the value of the signing method
756ae7a7-3713-43ee-9936-0dff50306488:123456

Encrypted Request Example:

Executing a Transaction

Headers
Encrypted-Signing-Method: <<BASE64 ENCODED JSON BODY from Step#6>>

Body
{
  "transactionRequest": {
    "type" : "TRANSFER",
    "secretType" : "MATIC",
    "walletId": "56137f2d-b4e9-42de-943b-cee828eb222a",
    "to" : "0x8D6331D6C5ba3306961F0b4Ea13ff13aa43560b9",
    "value": 1
  }
}

Updating a PIN Signing Method

Headers
Encrypted-Signing-Method: <<BASE64 ENCODED JSON BODY from Step#6>>

Body
{
  "value": "987654"
}

Creating an additional Signing Method

Headers
Encrypted-Signing-Method: <<BASE64 ENCODED JSON BODY from Step#6>>

Body
{
    "type": "EMERGENCY_CODE",
    "value": "w2v7yertaad21lhudqghzwcg4"
}