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
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:
Param | Description | Required? |
---|---|---|
id | The unique ID of the signing method. | ✅ |
value | The value of the signing method. | ✅ |
physicalDeviceId | The physicalDeviceId which is the unique ID of the user's device. (Applicable for BIOMETRIC only) | ❌ |
idempotencyKey | A unique UUID for every request. | ✅ |
signature.type | This will be sha256 | ✅ |
signature.value | SHA256 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
:
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
:
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
:
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
Encrypted-Signing-Method
Header6.1 Preparing JSON Body for Encrypted-Signing-Method
Encrypted-Signing-Method
Next, prepare the following JSON body.
Param | Description |
---|---|
encryption.type | This will be AES/GCM/NoPadding . |
encryption.key.encryptedValue | The AES key that is encrypted with RSA-2048 public key (GET /api/security ) - from Step#3 |
encryption.key.encryptionKeyId | The value corresponds to the result.encryptionKeys.id param in the response body of the GET /api/security endpoint - from Step#3 |
encryption.iv | Your randomly generated iv vector (12 bytes). - from Step#2 |
value | The 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
)
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
)
Signing-Method
)The Signing-Method
header can be passed as usual for non-encrypted transfers.
Parameter | Param Type | Value | Description | Example Value |
---|---|---|---|---|
Signing-Method | Header | id:value | id : This is the ID of the signing methodvalue : 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
PIN
Signing MethodHeaders
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"
}
Updated 15 days ago