File signature and encryption

Encrypting and signing digital files before sending them to the Pismo platform is crucial for ensuring both security and authenticity. Encryption protects the data by converting it into a format that can only be read by someone who has the appropriate decryption key, thereby safeguarding it from unauthorized access and potential breaches. This ensures that sensitive information, such as personal details, financial data, or confidential business documents, remains private and secure during transmission.

Digital signatures, on the other hand, provide a means to verify the authenticity and integrity of the files. By signing a file, the sender attaches a unique cryptographic signature that can be verified by the recipient to confirm that the file has not been altered in transit and that it indeed comes from the purported sender. This helps prevent tampering, forgery, and impersonation, thereby establishing trust and confidence in the communication process.

To this end, Pismo provides features for both signing and encrypting your files. These features meet the following criteria:

  • Authenticity: They confirm that the file originates from the customer, verifying the sender's identity.
  • Integrity: They ensure that the file remains unchanged and untampered from the moment it was signed.
  • Confidentiality: They use managed encryption keys, allowing customers to encrypt files before sending, protecting their data from unauthorized access.

You can sign and upload your bulk files using Pismo's Upload bulk file and Upload public key APIs. For the manual upload method, refer to Bulk file-based payment processing.

File signature

Before sending your bulk file, you must create a key, generate a signature file, and sign the bulk file. The key you create must comply with RSA-3072 and the key type must be asymmetric. An asymmetric key refers to a cryptographic system that uses a pair of keys for encryption and decryption: a public key and a private key.

📘

What is RSA-3072?

RSA-3072 refers to an RSA encryption key size that is 3072 bits long. RSA (Rivest-Shamir-Adleman) is an asymmetric cryptographic algorithm used for secure data transmission. The key size, in this case 3072 bits, determines the strength of the encryption. A larger key size generally means stronger security, but it also requires more computational power.

RSA-3072 is considered secure for most purposes and provides a higher level of security compared to shorter key sizes like RSA-2048. It's often used in applications requiring long-term security, such as digital signatures, SSL/TLS certificates, and secure email communication.

Creating public and private keys

Create a public and a private key to validate the signatures. Here is how you generate a public key.

  1. Run the following command to create a private key. In this example, private-key.pem is the private key you create. pem stands for "Privacy Enhanced Mail," which is a format used to store and exchange cryptographic keys and certificates.
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out private-key.pem
  1. Create a public key (public-key.der) from the private key.
openssl pkey -in private-key.pem -outform der -out public-key.der -pubout

📘

About DER

All key materials are in the DER format and encoded in base64. DER (Distinguished Encoding Rules) is a binary format for encoding data structures described by ASN.1 (Abstract Syntax Notation One). It is commonly used in cryptography for encoding certificates, keys, and other data.

  1. Generate key material from the public key.
base64 -i public-key.der

📘

About key material

Key material in RSA-3072 represents the actual key data used for performing cryptographic operations such as encryption, decryption, signing, and verification.

  1. Copy and paste the generated key material in the key_material field in Upload public key to upload your public key to Pismo.

The following is a sample request for uploading a public key:

curl --request POST \
     --url https://api-sandbox.pismolabs.io/corporate/v1/bulk-payments/keys \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "id": "<key_id>",
  "key_material": "<key_material>",
  "expired_at": "2025-05-21T12:27:00Z"
}
'

For details about the fields in the request, see Upload public key.

When the request is processed successfully, a 201 Created response is returned confirming the key you sent previously.

{
  "id": "<key_id>"
}

Retrieving a public key using the key ID

If you need to retrieve a public key you've sent, you can use the Get public key endpoint with the public key ID. This endpoint allows you to query a Pismo public key to validate a signature or to retrieve a public key that you uploaded.

Signature file format

Once you create a public key, the next step is to create a signature file using Upload bulk file. Before you proceed, there are some key points to consider regarding the format of the signature file.

  • Without the key ID (the id parameter in Upload public key), it is impossible to identify the public key used to sign the file.
  • To validate a signature, you must provide the bulk file, a signature file, and a corresponding public key to Pismo. There are two ways to do this. One, you can use the Upload bulk file endpoint. In this scenario, you specify the key ID (id) and the signature in the request header. Another way is to manually create a temp.sign file that contains the binary signature data, create a signature file, and upload it to a Pismo-designated AWS S3 bucket.
  • The actual key is uploaded and securely stored in Pismo's database. The actual key can only be provided when you use the Upload public key endpoint, which is mutually authenticated and operates over a private network, ensuring no risk of key exposure.
  • Only the key ID (id) is sent to Pismo, not the actual key.

Creating a signature and signing the bulk file

The following steps demonstrate how you can create a signature file called temp.sign to sign your bulk file.

openssl dgst -sha384 -sign private-key.pem -out temp.sign 2024-05-21-15-55-00-<bulk_id>.original

In this example, 2024-05-21-15-55-00-<bulk_id>.original is the bulk file you want to send to Pismo.

Generating the base64 signature hash code

Generate base64-encoded content for the signature file:

base64 -i temp.sign

After successfully encoding the signature file, a base64 hash code is generated. Here is an example of the base64 hash code.

Format of the signature file

A signature file contains three attributes: bulk_id, key_id, and signature.

{
  "bulk_id": "<bulk_id>",
  "key_id": "<key_id>",
  "signature": "<signature>"
}
  • bulk_id: The bulk identifier as specified in the bulk file. This ID is client-generated. You must generate this ID and provide it to Pismo.
  • key_id: The identifier of the public key corresponding to the private key used to sign the file.
  • signature: The signature encoded in base64 that you generated in the Generating base64 signature hash code section.

This format is used for both the bulk file you send and the output file generated by Pismo.

Once the signature file and the bulk file are successfully uploaded, Pismo validates and returns the following response with a Pismo signature.

{
  "bulk_id": "<bulk_id>",
  "key_id": "<key_id>",
  "signature": "<Pismo-signature>"
}

Verifying a file signature

Verifying file signatures is a multi-step process.

  1. Validating the signature
  2. Decoding the base64 hash code
  3. Retrieving the public key
  4. Creating a der file
  5. Verifying the signature

Validating the signature

Upon sending the signature and the bulk file to Pismo, the latter validates, signs, and returns a Pismo version of the signed file to you (2024-05-21-15-55-00-<_bulk_id_>-out.sign). The following example is an output signature file generated by Pismo, note that the signature attribute contains a base64 string.

After sending the signature and the bulk file to the Pismo platform, the platform validates, signs, and returns a Pismo version of the signed file to you. The filename should be something like: 2024-05-21-15-55-00-<_bulk_id_>-out.sign. The contents of the file take the following format. Note that the signature attribute contains a base64 string.

{
  "bulk_id": "<bulk_id>",
  "key_id": "<key_id>",
  "signature": "<Pismo-signature>"
}

Decoding the base64 hash code

To verify the signature in the output signature file, follow these steps.

  1. Create a new JSON text file (pismo-signature.base64), following the same format as the returned signature file.
  2. Copy the generated base64 hash code from the signature attribute into the signature attribute of this new file.
  3. Use the following command to create a pismo-signature.sign file.
base64 -i pismo-signature.base64 -D > pismo-signature.sign

Retrieving the public key

Use Get public key to retrieve the public key you uploaded, this step is essential because you need the key_material value to create a der file in the subsequent step. Once successful, the following response is returned.

200 Ok
{
  "id": "<key_id>",
  "key_material": "<key_material>",
  "expires_at": "2025-05-21T12:27:00Z"
}

Creating a der file

The key_material attribute in the returned response represents the public key. Copy and save it to a file (pismo-key.base64). Then use the following command to decode the string and output it to a der file (pismo-key.der).

base64 -i pismo-key.base64 -D > pismo-key.der

Verifying the signature

To verify the signature, you need the DER file (pismo-key.der), the signature file (pismo-signature.sign), and the Pismo-signed bulk file. Use the following command to proceed with the verification.

openssl dgst -sha384 -verify pismo-key.der -keyform DER -signature pismo-signature.sign 2024-05-21-15-55-00-<bulk_id>-out.original

If the verification is successful, a Verified OK message is returned in the command window

File encryption

Encryption specification

After signing the bulk file, it must be encrypted using an AES-256 symmetric key. You can obtain this key using the Get AES key endpoint. Keep in mind that each key is single-use, so every time you want to encrypt a bulk file, you must send a new request using a different client-generated bulk ID. The encryption must adhere to the following specifications.

  • Algorithm: AES-256
  • Key-type: Symmetric

📘

About the AES key and the symmetric key type

  • An AES key is a cryptographic key used in the Advanced Encryption Standard (AES) algorithm, which is a symmetric encryption algorithm. The suffix 256 in AES-256 refers to the bit length of the key used in the algorithm. AES is widely used for securing data due to its efficiency and strong security properties.
  • The key type “symmetric” refers to a cryptographic system where the same key is used for both encryption and decryption.

If the request is successfully processed (200 ok), you should receive a response in the following format.

{
  "aes_key": "<your_aes_key>",
  "iv": "<your_iv>"
}

For details about aes_key and iv in the response, see Get AES key.

Run the following command using the values returned for aes_key and ivin the response to encrypt a bulk file.

openssl enc -aes-256-cbc -in 2024-05-21-15-55-00-<bulk_id> -out 2024-05-21-15-55-00-<bulk_id>.original -K "<your_aes_key>" -iv "<your_iv>"