A Developer's Guide to Constructing Encrypted PII Messages for Binance via Fireblocks

🚧

Early Access feature

This feature is currently in Early Access. For more information about participating in Early Access, contact your Customer Success Manager.

Introduction

For institutions using Fireblocks to transact with major exchanges like Binance, correctly constructing and transmitting Personally Identifiable Information (PII) is critical for ensuring regulatory compliance and the successful processing of transactions. Sending PII requires a robust security model that goes beyond standard transport-layer encryption.

This guide provides a practical, compliance-aware walkthrough for developers and compliance officers on how to structure the PII payload, handle the necessary encryption, and correctly format the transaction.extraParameters object in the Fireblocks API. It breaks down each field and explains the specific data requirements based on key global jurisdictions.

📘

Note for Compliance Officers

This document details the technical data structure for compliant PII transmission. The core obligation is to ensure your institution has a robust AML/CFT program that includes counterparty due diligence, risk-based transaction monitoring, and adherence to the specific data requirements of all relevant jurisdictions.

Core Concept: End-to-End Encryption of PII

It is critical to understand that you must never send raw, unencrypted PII in an API call. The piiData object detailed in this guide represents the plaintext data structure that must be encrypted before it is submitted to the Fireblocks API.

Fireblocks documentation indicates that PII encryption is a manual implementation step that developers must handle. This ensures a secure, end-to-end model where only the intended recipient (in this case, Binance) can decrypt and access the sensitive user data.

Binance PII Data Encryption Guide – RSA-Only Model

Overview

Binance requires RSA-only encryption for PII data transmission:

  • Hybrid encryption (RSA + AES) is not supported.
  • Using hybrid encryption will result in failed Travel Rule submissions or empty compliance data.

RSA-Only Encryption Model

This method encrypts the entire PII data payload directly with Binance’s RSA public key.
Process:

  1. Direct RSA Encryption – Serialize the PII data to JSON and encrypt the whole payload using RSA-OAEP with SHA-256.
  2. Single Encrypted Blob – The result is a single base64-encoded string containing the encrypted PII data.
  3. Send in API Call – Pass this encrypted blob in the piiData field of the Fireblocks transaction request.

Production Usage: Encryption and Transaction Creation

In production, you must fetch the Binance public key from Fireblocks before encrypting the PII data.

RSA-Only Encryption Utility (Example)

import * as forge from 'node-forge';

/**
 * Example: Encrypts each PII field individually using RSA-only encryption
 */
export async function encryptPiiFieldsIndividually(piiData: any, publicKey: string): Promise<any> {
  async function encryptPrimitives(obj: any): Promise<any> {
    if (obj === null || obj === undefined) return obj;
    if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean') {
      return await encryptWithRSAOnly(obj, publicKey);
    }
    if (Array.isArray(obj)) return Promise.all(obj.map(item => encryptPrimitives(item)));
    if (typeof obj === 'object') {
      const result: any = {};
      for (const [key, value] of Object.entries(obj)) {
        result[key] = await encryptPrimitives(value);
      }
      return result;
    }
    return obj;
  }
  return await encryptPrimitives(piiData);
}

Example: Creating a Binance Fireblocks Transaction with RSA-Only Encryption

import { FireblocksSDK } from "fireblocks-sdk";
import { encryptPiiFieldsIndividually } from './encryptWithRSAOnly';
import { piiData } from './piiPayload';

const fireblocksSDK = new FireblocksSDK(privateKey, apiKey, baseUrl);

async function getBinancePublicKey() {
  const credentialsResponse = await fireblocksSDK.getExchangeAccountsCredentialsPublicKey({
    // Specify Binance exchange account ID
  });
  return credentialsResponse.publicKey;
}

async function createBinanceTransaction() {
  const publicKey = await getBinancePublicKey();
  const encryptedPiiData = await encryptPiiFieldsIndividually(piiData, publicKey);

  const transactionRequest = {
    operation: "TRANSFER",
    source: { type: "VAULT_ACCOUNT", id: "1" },
    destination: { type: "EXCHANGE_ACCOUNT", id: "binance_exchange_account_id" },
    amount: "100",
    assetId: "BTC",
    extraParameters: { piiData: encryptedPiiData }
  };

  const result = await fireblocksSDK.createTransaction(transactionRequest);
  console.log('Binance transaction created:', result.id);
}

Real-World Example: Compact Polish Deposit Scenario

This example demonstrates a common real-world scenario where minimal required information is provided for a withdrawal.

  • Transaction Type: Withdrawal
  • Jurisdiction: France (FR)
  • Relationship: ThirdParty
  • Entity: Individual

Scenario: A user is making a withdrawal from their exchange account to another beneficiary, where the user is an individual located in France..

Before Encryption (Compact PII Data)

{
  "extraParameters": {
    "piiData": {
      "type": "exchange-service-travel-rule",
      "typeVersion": "1.0.0",
      "data": {
        "beneficiary": {
          "participantRelationshipType": "ThirdParty",
          "entityType": "Individual",
          "names": [
            {
              "primaryName": "John",
              "nameType": "Latin",
              "secondaryName": "Doe"
            }
          ],
          "postalAddress": {
            "country": "BE"
          }
        },
        "beneficiaryVASP": {
          "vaspCode": "BINANCE"
        },
        "transactionData": {
          "withdraw": {
            "isAddressVerified": true
          }
        },
        "originatingVASP": {
          "vaspCountry": "FR"
        }
      }
    }
  }
}

After Encryption (Compact Encrypted Data)

{
  "extraParameters": {
    "piiData": {
      "type": "exchange-service-travel-rule",
      "typeVersion": "1.0.0",
      "data": {
        "beneficiary": {
          "participantRelationshipType": "DkGFzfPCLi3SNl6BrrS1C4X/DmuqfVvU83iczY+pDgamI3FUTmzghoGvtjERSH6uqKo3h9gwAWQN8mYV7PGdgkV7cnSS6/H4CNJWV7BlN63RU7DmsmVdHoGbA0F7GnriQvKlnTFPU/CCXJDcsaXG7cHa5VtST8rw+acw73fnUpwUnGMLnw0QOUoYrvu6eGo+BX1aZu+Ve0hrhJTcYXXfnvekkXWCLxDu8AYltJSy4YgzsFNvHb3JyOOuPvJg3qka2NfVrzRXv+7pQy6c4eyErfBJZ6T8i/WXsu9gVZXuOC24wtZi99pP2XGz9ogW2hv9edmEUTitZXneWm26sbtwN9jBPVh4ZRLfGg9wxV1fN/g6MPVbil7Ilu6olO9gRlPj2GUyFIfNPFAziqGEw7CEFvPlQuLv5n2/Pbh98jS/sGANwjKZhXBKyy79WLs/HDVZw6E99+Vxf786HdmIc4MEyj+AELhqcdp8uF0D1/xA+hDFiDpcZjV3JASX9b8EPOaxix9P7TdPepoFoZo4fJFQtaXvAunnsYiG2bE/NareEjLZvqcHadeaCdy29sXCmxeaj1v5hL5GZJFFkBEUa9QLcle0YXQQa3ukkc1W0tChIeGwSEY/qNW/FZ5jg3Pqm8gpdwGzd0gZk/JO8YDIthtTRdgm7zjydIxVZGChTO/h4WM=",
          "entityType": "CvnHs/CzrfdTpGukJXmJH+88n2cW9C0Ezc6HtJtDzN6+e7dk+GoGrK/ia9Kptncrh7Q+6AVHR3pmrJFH10Y8kwxLoNOmJkPtNDJLoVPDSxAn4So7Jw0mA+OGXu8J1e/b1v9u4g3/2L5373MURnsrMydU0vt77YaBZgmZo0dtukLE4kGTnW2lUKexdeRs6NR99r+VQNYG38XGi2/OAjwvBPIAxfmaXBoNMCVda0JZkjlweezwIGL8theV+RMPtQBm8mUsBpbcIiBLAFA4/pQgCKVHZuUMkfaSXh6zPBga6hQu4N0fhLxTj1VwW1Mocd373ifUAn5mziMB4tunObI6jy91s0zunmIajZeHqxIvxci1sMEI6RXnuzKfbkadUzM9cyUMjnzkrQk5q5VuurxfZRqFHuw9Ikq8dNUavAetwgJipUi2aTVh0+uVgZ84QKusJ08LqD3N4k6eghZwIDUkCFXNZnK1reK+oIqGcbs8y0r+Vmr1zh5GukA55+yqRJXu/YxAlS3HIwp+HnhSvM8Wz1O5/PgCHm2iRcP3+pCYWJltkPoKPzynurAN6I1tGSak7+AiPwiJsd5sqdNylR5eFR4N28U61vYhk4nebsvvI5J+7M9+f25hs4hDloV+bmj0wzN3QnCRS3RyaPg91fdCo2iTR5PTuLvjVJ0GX/h1674=",
          "names": [
            {
              "primaryName": "SpDXvmGFXH3qe0jAVZeinBniH18VBPsAqnLz+SxidNd9Hh6XKbs10cHMPoda4Yga3dDLXSZTRMb9hJPbsYlanFgWpcIW6rq4KGeK/Q9LiN1gVSGwZrXMD2Jx/3+hPVcSUqYqGiirZpoeQqJUTzmJvglRCWDDNbE88jFcQ+XEvj0v9tC1rrHrxrowe1QaxFeOt8HMl2PjGVzUGCD9QdRsG0DbBa4To49EsvXl6qCMr11pioCWzAVgYxRJU5HlfikbsU00dxXTVVaHAFGfGgeTSBBVpNLTvUuk7Q4CW4TIa9PiDYiZsT9KW3X0tjXLs0xflrUXMXUWDC3bVfEMcFtM75YyOFrMY4IhGfyND6o+4MyeqC7LmYc09o9wmheiRS/l3J77SNc8w7tlqoSgvVVb45TDpBtf611SQ8GnCQ9rTg9rKROwPXA58micxFKrgVVYfY+E0uo90kzs/Hfw0OohrC/3vS6d3ocXAEp8FEtmCvyRxK+xgTv3obIzL6eVqI2TBDkkyjT3gGBrbS0a8GPZSKUw9W0cNnYjxZ/rxF1xBUG1gg+cE7St2yNwQ9m3gcneoB8U3AA5y/f5Zw7iz5ekAmMdrUFWf5ENNodNNv66KVNQLwpSIWeHiVkr5mqEIooAJDaFDaYKw6A2GRJzU+ZQ7ca3rOumleUq6kXfQcCmpr4=",
              "nameType": "UFvT9EbXqfGJGH3UPsXtRbwyi9VDb3JgEyGXDM6x4Pkk/R8nlfEVnKFSmt0LSU1Vnzl/k8pjMsLcap33RDENMWTRAfjasnqDK7uZCNO8m37SBZiTLmTYrX3k5V4hF0p6SQqvltPV4cye4AwALxZKtc95jzsfJUxgylaXbmuR8+W8RoHZrhid4YCFmarpC8xCz0fcrWrbRtfV/wuv4wHotkX7SQJj0pf31xsRjfDYIV6Fo0tlnhI1JTdVh+ztE9e76OcRdlpM2Fk7UM42+CXUSvvO3iP4E1ot5K7O+u+3a8pcVWNbAIycLlz79fz2LFXiQ7jc63Yg/sG/P2yQqk/ivDT/ZWjSoCNlB8oi7VDpL2ir0Xwh1+D6I9n6f1G4jc0Fkqr0DP00P93jpmBQzqPi2V7TBrnIwxPnQeEzj1SXE0ENMbj2P/PGeinGW34h6/0WFKyyOubMqLnvG5lPUusFPA7NFY7NdS/1OAU/y4J52R9YFWkW9o2jdn9G3iLbjNKx8g0yRbnT0sTXql9E+VCv2HPYS1Wuoqo/S1LhG6j0y9ugUCS1+advbxHm0/4ZD5zJ4+5FHIlH8s5+CJ7/FGFsRRN/R2jAW9GSqdzczzYm4X24l8cn4xHRWR2XO0jqlYmoH8sBMrZVgfvJnDy4KotlthZT5ooIOQJY+58x6gXnUL0=",
              "secondaryName": "KjXjKySekOb13IvuP4ainsMzGCmxK9CUeVI6VMLp3MYxz1zFbZBq95v8Ly5TBoH+RL176yioR5o4l0NHEgL8+vjjSeau/o9cHRZK16VjrGmF2MmpuFeD4NPN9IAsD8M+xeq2X06EK5ns9ebuGCADAiEGIEbBfnjZcJpUhnlllTptbuzBoeaK/k1545XMA30f6SuR+6hGxDBX6rX+vYJOvEBhSfK9km1mJ2y89it38QY2eRcDD8Li4nuLPaKrqzWGcN+Lp8KrII604D9ewUj/a9LfefrZBB5H+gL0XI2h7rVfiYNBJghXakfunS595nBNTjbxz5spuDxE7k0EqhW6t2N70FzyNVUjmxo0nFCSRViONXuiyhddZfRcIeTXJf1hXp0/cujqvOkbdrl2yPXl2pZ0/XZaCHfx76unLaLHUcFKCVpib5FXi5i7C6Gd+8QuBliUiUAdWUJGpcqQLkz7/zALdZLqISZ5WLyKENIt/Rdo/GzQ35CZVCe9TtIIIEHq0wmMArCB73KFzMrrJStefPA4tNtbWM4iwPmahoSWFYl96pIclGNdRdFNTF1jM4VgfboB27YG/6YFJMcWYJvXR5gkbeYUgRRe/q/B7iFvGKdNIrCe34iCGEZ8/hNs+ljBFmcxEbOiFjoAg3sOe3WKnpLaI5jaFyel4Jar7XkKAxg="
            }
          ],
          "postalAddress": {
            "country": "o9MZlFzz76bKfw3giyekwbhpZo3Nn1+o/NTzFQnSWaozIKa9xoAiOE8IvmU9tkT3yZLYOeaX6F6Am2hyzpers9lMHr2Ha1pOFnreQUKE9x2fEFZyAXv625Hz8Ja+ZeywlkbAok1atpc7+JC8GD7quErQwC/qgZ8yzW926JyQ38sZPHY+W0IM2sc7S0KoL77Yu5+gixQPbiUdMfYjimuRRwW+4NzsSOWUcZdQ+NB/khz/7CDc9q6tqYFuHg17sFo6QO2rQSpcgfzDrqmdCX0ZnSRBf5FZG2I0tHA2t24UuRJJGNIU66jr9b4h2pJFWpE+UwSmx8skyI+0DCk4P8gxhS6ZhQ93TGpSgpI5rWW7pJLLzlmEeVF5bm7zYQg2eu0HTUi3DEyUHfW0g/LpGEfLCudwSXRjGUUXI7tSV6BxC4EY7T5pt6RkNrnTdjSo8B4azdv06BqVjYzeJFwXL7Zo4khoaQETQf3PiTlwMQw/WQox/65IfpKfM1KhHtPFCiG1v358q2FO/S0yV6hcKNVRNfrZXG5v32DDZ8S/K8Cs0+XBEBl8OxHo581uahVKONzb2VwBGTxcXouWHVLEq928wDKnhAPvUmFMkHtkpmdSxOWr0qoMUD9WQFvkYqm9RXeczoN/RTsAqMSr1InoqfmqU9TZBCdjiMDnhe4ggAvFKkU="
          }
        },
        "beneficiaryVASP": {
          "vaspCode": "VTiePIZHqIn6q17/SWZ8fdpWga72UvaVjvwBs2PQ/R5DyN6GwDOC6msAFr3+1h/14PwFfawmWXpWu6xmKm7iyUHpMmmnnPlUKSjlNeb+k2QVTHPXYT6eboT3V8gav47mIBfv+XMm2AtXfLRGpWF5or6Q929QqxXgOOl89xwdYxRFnboSB/T9coZ2lonf15F/n+8XEMmE/g77iGwlY5pIi7VmAhi0MIJthRgxIXbuB5yzL1MtaPQr5a4tTY9J0WR6MlMjkeGODV0VyVX90aajDgTv4ocB0TLwGkC4GRTLBsdyGD3jkpp0Lion5ip+BT0MhYg2xvshef/GJ4cob2bZy+10GAdWUbid2n66HQUJjIyPuPtAZLzf/hZiL5dsgykRz/FpT291eoTeQ0V6RIYLBGSqSPkc+n56Pqum0c47Oan5078R9/k5YLpTX9DD464m5pHSPPh/sg5TeBydd31bHJy0EfwGMJPCK4yjaTlK2At6vLzhJ+BZ6au8oWoDvbCbS2bh1jJh5x/V/4HAkv/h7woGb3OY+z/GazfFEhCBAC4WdvGExHqbQhbhcOlbZr3Wt6b3Vx1U06u+acwLUwt3P9yuufAvQkjxYp60nSKKJxjj0Vnk/Qjf1vCXab8y7siEXthVO1MqTsozGtgCqzHw8aNtg7rEAykSd8AHyyjRqz8="
        },
        "transactionData": {
          "withdraw": {
            "isAddressVerified": "g6y8yN5t+5GrJfFkhqrOz5dfJjTRiIO2qYH+OXsRNaTrtoJjPwda7OOnAmuSp2yBdRFTPKxgcWzBo5fofQvOyl64RdrWmtKFkWBDAtJUzoIE5s6yk5qp+wi5+gNdo4bHmrKaJXaOsaKrO+o+kfg0ySt8K1qrsZK7AFa+yqwabUmiDwRdElromyDpACv2n2ol/1W2Oh87nAHIW8fUWsEiuI8nM83X5Do6ZlsUGjTXRhIVVuu4Yd9Jkeld1OSe2iSETFb2XEy0ml5viU5H31AJ1RQaNCvBVpzu/1fe6YgB05MQjTiL01/kn2cT3PlZ5WaKZxXQuuoNAR0y5eeJPiwfdBCCrL7Z8KJpsCRspRBXxXoUFkN56XUfBHaRwoeA4flSLfpmfKYSNcATUr13sd/fH7n6wk6mU8Zl0CJJkoWQaUCk0cM54wxWGeRtgSqPAteBsAw2olBpRrK5fIvi5YWd7ez88CtlIZwfsAI7WaMtZMTTlC8E9BdRhJVjX4neadpVfNYoiVPLiEzfo9gK5jqyeuFgYG1fAhWYvKVk+rw2Csn5iqO/AXhkEQht1riw4BnrfymFGJY8+9hrz+KTUZndG1Xw5GbFlEuitqg9yRGCUdhJVALoSeJ71YCMFIWPoq/3IRogFTqEBtzkP4N9ohUBlZVxPXZhZFc+Axe6SsaH+Wo="
          }
        },
        "originatingVASP": {
          "vaspCountry": "ppyFQ37QrH2GUityQet2+PMZdkqbgxv3tM7hiokv0TLUjZikj6TT/8jaDXumx2itIDKYr+N7zhvPtM9cm9mMWTjo2D7m3LOPNXu0uRPOCNWOQAACOlx21rC5Sc+yUazLq7e8kyi2wlF3ngH9DIjlVeQ6aGZk5q6HEWm4pvuqOaLA6h4qLsLB5VLg4ygEOw0Lqmc04Y5pKRkrB8f4MrAQtzUjwaQabUXheeAncakIKlRGYfOWYnyqKjJ+X7WD2dK95nNHahORltLeZkPVpHz7ERNqlDtRWlplbBT08PZ0pv3IVWxkFDPc1UB5NVGl0PhkdLSmCLvQe8DwmeBMZzC8o0Ks+vLlmJZbcbjYFmosaH5ZlbJh01Azs1xLaYqhNF/NwFSbYqL5vm7GsKS6wXgKCDJkikyIXG1UavKhL2HdrOIXOv07E/ox0pH7Sn8rs3p6aVM5s0fQKV5nRaM9s5ixbC3VAX5uVKG0mBSu9G//Q/RrjUXCdcaKD4lKw9hzmX1linKJCnCjEjwaDpRtPXledumNFt7CWn+dcvjG7xhOro/EeTpTcT1IqcPw+D0NnZLddNyx/xrJC5YMU3yZ7tKHLsvVZyotC6UTTjBQJUCLt0rpEvd7stZtpp/Nn5i1KeSwYbXIaEMthNZQaO63gMi8od/R0LCcYeEHInZ5qYhD1n0="
        }
      }
    }
  }
}

Mandatory properties per jurisdiction

The mandatory properties vary from jurisdiction to jurisdiction. To simplify mapping and usage, see the following resource:

Final Checklist for Developers

Before deploying your integration, ensure you have completed the following:

  • Select a Cryptographic Library/SDK: Integrate a library that can perform RSA-OAEP with SHA-256 using Binance’s public key.
  • Implement Public Key Retrieval: Securely fetch Binance’s public key from the Fireblocks API before each transaction.
  • Map PII Fields: Correctly map customer data to the required piiData fields.
  • Handle Jurisdictional Logic: Implement rules for required PII based on transaction amount and jurisdictions.
  • Encrypt the Payload: Confirm that all sensitive fields are correctly RSA-encrypted.
  • Test with Sandbox: Validate your integration thoroughly in the sandbox environment.
  • Confirm Data Accuracy: Ensure encrypted plaintext matches KYC records on file.