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
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 6 months ago