Use of "RSA Keys Generator" to send signed requests

RSA Key Generator can be used to generate an RSA PKCS#8 key pair (private and public key).

To demonstrate how it works and send a SIGNED request to Binance Spot Testnet, we’ve created the following walk through steps.

STEPS:

1st Part - Generate RSA Keys and submit RSA Public Key

  1. Go to RSA Keys Generator releases and download the latest version that matches your Operation System;
  • .CHECKSUM is used to check the integrity of the app. You can consult more details at README.md;
  1. Open the application and you’ll see this user interface where you can generate your RSA Keys:
  • Key size - The size of the keys to be generated. You can choose 2048 bit (default) or 4096 bit.
  • Generate Key pair - Creates a new private and public key that’s listed in their respective text boxes.
    As alternative, you can also directly paste your existing private key to the text box and it’ll auto generate its associated public key.
  • Copy /Save - You can either Copy the keys or (recommended) save the keys locally into Private_key.txt and Public_key.txt (the file extension defaults to .txt but it’s customizable).
  1. Now that you have the keys, go to Binance Spot Testnet and “Log In with GitHub” to authenticate there;

  2. Register your RSA Public Key;

  3. Save the generated “API key” (you’ll use it later).

2nd Part - Create Signature and Submit Request

Notes:

  • GET /api/v3/account will be used as SIGNED endpoint example;
  • Private_key.txt will be the private key that’s in PEM format;
  • For simplicity, the timestamp will be fixed at 1668757000921;
  • The following steps is to understand the Logic, it doesn’t submit a successful request as you would need to have the timestamp for signature and the final payload’s timestamp in synced and updated with current time;
  1. Construct the request payload by arranging a list of parameters (separated with &) into a String

recvWindow=5000&timestamp=1668757000921

  1. Build the signature:

Go to the location you saved private key and do the following shell command on the console:

echo -n "recvWindow=5000&timestamp=1668757000921" | openssl dgst -sha256 -sign Private_key.txt | openssl enc -base64 -A

Command details
  • openssl dgst -sha256 -sign Private_key.txt
    Signs the payload with the saved Private_key.txt in PEM content format and by using the RSASSA-PKCS1-v1_5 algorithm with SHA-256 hash function.
  • openssl enc -base64 -A
    Encodes output as base64 string and deletes any newlines in the signature.

Output:

Ht98de2Spf+oJO+URdVsyIg7o2LFRdCgTDsgBrBku22boLhQ9WLMpQ72RQqXQfUnW2j8abungG5+FiB2GaA5QiwfKSGxbB9fhQYwaMlrEvJnefeRXD9SW1Is5KjpJWEyT6FuYcqkz/J6pndzPo9im1Ps6k1vPqa98sjCqODY8Kxg702jY5srv6kkLIvqgL22kniV+etruKNpiAIJcdyqF+5skS3fIQLpuRqZAykpv5y0fkJLDLWVHLqNhTxE8QQchPD5xAXmIsgo8Zx5Xt/9UPt8Al/oQm6f0dCWsYCU5zua/mwKrmvKesCW/cM0DYyXUxeJDt2ylejpDVS5+Dm1MA==

Console Example:

  1. Submit (curl) request with the generated signature:

curl -H "X-MBX-APIKEY: IlINyGFcb0KpZhxxNm8192xJFVYW5W3FsZpkW2oGwh6muwVogI70hKD17KbK1F8z" -X GET -G --data "recvWindow=5000" --data "timestamp=1668757000921" --data-urlencode "signature=Ht98de2Spf+oJO+URdVsyIg7o2LFRdCgTDsgBrBku22boLhQ9WLMpQ72RQqXQfUnW2j8abungG5+FiB2GaA5QiwfKSGxbB9fhQYwaMlrEvJnefeRXD9SW1Is5KjpJWEyT6FuYcqkz/J6pndzPo9im1Ps6k1vPqa98sjCqODY8Kxg702jY5srv6kkLIvqgL22kniV+etruKNpiAIJcdyqF+5skS3fIQLpuRqZAykpv5y0fkJLDLWVHLqNhTxE8QQchPD5xAXmIsgo8Zx5Xt/9UPt8Al/oQm6f0dCWsYCU5zua/mwKrmvKesCW/cM0DYyXUxeJDt2ylejpDVS5+Dm1MA==" https://testnet.binance.vision/api/v3/account

Command details
  • -H "X-MBX-APIKEY: xxx"
    This sends API Key you got from Binance Spot Testnet as header.
  • --data "param=value"
    For each parameter.
  • --data-urlencode "signature=xxx"
    Since the signature may contain / or =, it needs to be URL encoded to avoid issues when sending the request. The url encoded signature is:

Ht98de2Spf%2BoJO%2BURdVsyIg7o2LFRdCgTDsgBrBku22boLhQ9WLMpQ72RQqXQfUnW2j8abungG5%2BFiB2GaA5QiwfKSGxbB9fhQYwaMlrEvJnefeRXD9SW1Is5KjpJWEyT6FuYcqkz%2FJ6pndzPo9im1Ps6k1vPqa98sjCqODY8Kxg702jY5srv6kkLIvqgL22kniV%2BetruKNpiAIJcdyqF%2B5skS3fIQLpuRqZAykpv5y0fkJLDLWVHLqNhTxE8QQchPD5xAXmIsgo8Zx5Xt%2F9UPt8Al%2FoQm6f0dCWsYCU5zua%2FmwKrmvKesCW%2FcM0DYyXUxeJDt2ylejpDVS5%2BDm1MA%3D%3D%25%20

Output:

{"code":-1021,"msg":"Timestamp for this request is outside of the recvWindow."}

Console Example:


SCRIPT