Securing a Connection
Securing your Connection and Data
This page will help you to:
- Understand the components required to secure a connection
- Provide examples of how to generate the required JSON Web Token (JWT)
- View fields to be provided in the JWT header and payload
- Message level encryption
Security Overview
Today, API Security is a key priority for protecting important data, especially within Financial Services. Here at HSBC, when it comes to data security, our market leading API Developer platform goes further than just industry best practice.
The diagram below illustrates how Authentication, Authorisation, TLS and Message Level Encryption combined, stack up to provide you with world class API Security.
The following measures and their components are required to establish a secure connection between HSBC the API consumer:
Category | Definition | Components |
---|---|---|
Transport Layer Security | HTTPS Connection (TLS) | SSL Certificate |
Digital Identity Client/Partner's Platform Identification |
Message Level Encryption | Private Key & Public Keys for message encryption |
API Authentication & Authorization | The Client/ Partner's Platform Profile ID - Provided by HSBC | |
Customer ID - Unique ID of Customer on Partner's Platform -Provided by Partner's Platform | ||
Associated Account's ID | ||
Signed and Base64 encoded JWT (JWS) - created by the client/ partner |
Here is an example of an example of an HTTP(s) Request
HTTP Request |
Key |
Description |
Example Value |
|
---|---|---|---|---|
Version 3 (EDGE) | Prior to Version 3 | |||
Header
|
Authorization |
JSON Web Token (See: Authentication) |
JWS asdf1234asdf1234.1234asdfqwer1234.qwerqwerqwer123412341234 |
|
X-HSBC-Trade-Finance-Token | ||||
X-HSBC-Request-Correlation-Id | Unique Identifier for each request, format as per uuid. | 65535c2e646a499d91da-6af957df3f78 | 65535c2e-646a-499d-91da-6af957df3f78 | |
X-HSBC-Request-Idempotency-Key | Value same as X-HSBC-Request-Correlation-Id, only required for POST requests | N/A | ||
X-HSBC-countryCode | ISO 3166 Alpha-2 Country Code | SG | ||
Content-Type |
Content-Type of Request |
application/json |
||
Body | Base64 String |
Base64 encoded string consisting RAW Request Content encrypted by bank's public key From Version 3 onwards, a payload wrapper is added to surround the base64 encoded string |
{"encryptedRequestBase64": "eyJraWQiOiJndGUtY2xpZW50IiwiZW5jIjoiQTEyOEdDTSIsImFsZyI6IlJTQS1PQUVQ..."} |
eyJraWQiOiJndGUtY2xpZW50IiwiZW5jIjoiQTEyOEdDTSIsImFsZyI6IlJTQS1PQUVQ... |
Here is an example of an example of an HTTP(s) Response
HTTP Response |
Description |
Example Value |
|
---|---|---|---|
Version 3 (Edge) | Priori to Version 3 | ||
200 OK/ 201 Created |
Encrypted Response |
{"encryptedResponseBase64: "eyJraWQiOiJndGUtY2xpZW50IiwiZW5jIjoiQTEyOEdDTSIsImFsZyI6IlJTQS1PQUVQ..."} |
eyJraWQiOiJndGUtY2xpZW50IiwiZW5jIjoiQTEyOEdDTSIsImFsZyI6IlJTQS1PQUVQ... |
Decrypted Response |
|
|
|
400 Bad Request | Requester Side Errors |
|
eyJraWQiOiJndGUtY2xpZW50IiwiZW5jIjoiQTEyOEdDTSIsImFsZyI6IlJTQS1PQUVQ... |
401 Unauthorized |
Authorization credentials are missing or invalid. |
|
|
403 Forbidden | Failed in Authorization of requested resource |
|
|
404 Not Found | Empty resource/resource not found. | {"encryptedResponseBase64: "eyJraWQiOiJndGUtY2xpZW50IiwiZW5jIjoiQTEyOEdDTSIsImFsZyI6IlJTQS1PQUVQ..."} |
eyJraWQiOiJndGUtY2xpZW50IiwiZW5jIjoiQTEyOEdDTSIsImFsZyI6IlJTQS1PQUVQ... |
500 Internal Server Error | The request failed due to an internal error. |
|
|
503 Service Unavailable | The request failed due to an internal error. |
|
Transport Layer Security
To encrypt the communication, the connection between the partner and HSBC uses Transport Layer Security (TLS) via HTTPS as a security protocol. TLS is a cryptographic protocol designed to provide communications security over a computer network.
When the partner requests a HTTPS connection to HSBC, a Digital Certificate is required. This certificate contains the cryptography needed to begin the automatic Secure Sockets Layer (SSL) handshake which involves the generation of shared secrets to establish a uniquely secure connection between the partner and HSBC.
Please ensure your organisation has a valid Digital Certificate from a recognised Certificate Authority before attempting connectivity to our APIs.
Message Level Encryption
Message Level Encryption (MLE) ensures Data privacy of messages either in transit or at rest and involves a PGP handshake and encryption key exchange.
HSBC uses Message Level Encryption for our Corporate and Institutional APIs to ensure the highest level of security is applied to the data exchanged by our APIs.
Public key encryption involves a pair of keys known as a public key and a private key. These keys are assigned to an entity that needs to authenticate its identity electronically, or to sign or encrypt data. Each public key is published and the corresponding private key is kept secret. Data that is encrypted with the public key can only be decrypted with the corresponding private key.
Public key cryptography enables encryption, decryption and non-repudiation. HSBC's APIs support asymmetric encryption that uses a public key to encrypt data and a private key to decrypt data. The public key is available in a trusted certificate, whereas the private key is confidential and not shared.
For Message Encryption purposes, both your organisation and HSBC will need to exchange Public Keys so both parties can decrypt and encrypt messages via the API communication.
We know that MLE carries an overhead, as both parties need to encrypt and decrypt both request and response messages, however this practice has the important advantage of non-repudiation, giving assurance to both sender and receiver that the message has not been modified.
PGP Encryption
PGP is an encryption program that provides cryptographic privacy and authentication for data communication. PGP is used for signing, encrypting, and decrypting texts, e-mails, files, directories, and whole disk partitions and to increase the security of e-mail communications.
- What is the purpose?
-
For API Message Encryption purposes, the Public PGP Keys have to be exchanged between the API Consumer (Client) and HSBC the API Provider (HSBC).
- Where to get a set of PGP keys?
-
Clients can generate their own Private Key / Public Key pair using a key generation tool such as GnuPG or GPG.
Public PGP Key Specification:
- Signing algorithm: 2048-bit
- RSA Hashing algorithm: SHA-256
Once your Certificate is ready, contact your HSBC Client Integration contact to trigger the Key Exchange Procedure.
- How to use the PGP keys?
-
The Client uses HSBC's Public Key to encrypt a message every time it sends to HSBC. The Client verifies HSBC's digital signature every time a message is received from HSBC. HSBC uses the Client's Public Key to do the same upon messages sent and received from the Client.
For security purposes, HSBC's Public Key is renewed every year and a Certificate Renewal process will be triggered.
- Key Storage and Duration of Validity
-
Component Storage Validity Client's Private Key The Private Key should be maintained and handled with the most secure approach possible. The most common and yet secure approach is: key password - Do not save the password in plain text or hard-coded in an application. We recommend to encrypt it by any Password Encryption Tools/ key storage - Store inside a password-protected key repository, such as JKS or PKCS12 keystore. The Keystore password should also be encrypted. There is no Validity Period. However, if the Client suspects there is a chance that the key is leaked, or any other security reason, a new Private Key and its associated Public Key should be generated. Client's Public Key Since the Public Key is publicly distributed, a moderately secure storage approach is acceptable. The Client can store the physical file in any machine's file system, or for centralised key management - store all keys and certificates in one single key repository. For a self-signed PGP Public key, the same condition as above applies. However, the validity period of a CA-signed Certificate is depended on the purchase plan of the issuing CA. The most common standard is 1 to 2 years. HSBC's Public Key Same as above. The validity period is usually 1 Year plus 1 to 2 months extra. The extra period is a buffer to enable a client to switch a "to-be-expired" certificate to a new one during the PGP Key Renewal Process.
Digital Identity
Digital Signature is used to ensure that your API requests are not tampered with and originate from the expected source. It composes of:
- Message Level Encryption
- API Authentication and authorisation
API Authentication - JWT Validation
API Authentication is performed using a signed JSON Web Token (JWT). The token must be provided in the header of the HTTP request every time you invoke HSBC's API services. This ensures only authorised and pre-approved organisations can access and utilise our API services.
The JWT is generated by the partner, not provided by HSBC. There are many utilities available that can provide JWT generation and validation logic for all commonly used programming languages. The following example uses the "io.jsonwebtoken" java library.
- Building the JWT
-
What you will need:
Client/ Partner Private Encryption Key - for signing the JSON Web Token your system generated
Client/ Partner Public Encryption Key alias - The Public Key should be shared with HSBC as part of the client/ partner on-boarding process.
Client/ Partner Profile ID - The identifier HSBC provided you during the on-boarding process.
- Code example
-
The below code provides a JWT example in Java:
public static String generateAuthToken(String apiSchema, String clientProfileId, String onBehalfOf, String requestPayload, List<PGPPrivateKey> clientPgpPrivateKeys) { System.out.println("#a. Generating Auth Token..."); String token = new String(); PGPPrivateKey clientPgpPrivateKey = clientPgpPrivateKeys.get(0); try { System.out.println("#a.1. Using HashMap to build token structure..."); // header Map<String, Object> headers = new HashMap<String, Object>(); headers.put("kid", Long.toHexString(clientPgpPrivateKey.getKeyID()).toUpperCase()); headers.put("typ", "JWT"); headers.put("ver", "1.0"); headers.put("alg", TOKEN_ALG); // claims Map<String, Object> claims = new HashMap<String, Object>(); claims.put("jti", UUID.randomUUID().toString()); claims.put("iat", System.currentTimeMillis() / 1000); claims.put("sub", clientProfileId); //API Profile ID Bank Assigned to you during on-boarding if (apiSchema == "EDGE") { claims.put("aud", "baas"); // Obo, optional, only used when an API request is send on behalf of an End Customer if (onBehalfOf != null) { Map<String, Object> obo = new HashMap<String, Object>(); obo.put("sub", onBehalfOf); //End Customer ID, provided by your platform during on-boarding claims.put("obo", obo); } } else if (apiSchema == "GTRF") { claims.put("aud", "GTRF.MKT"); } // print token object printAuthToken(headers, claims); System.out.println("#b.Preparing Auth Token Signature by converting Client Private Key from PGP to RSA: "); PrivateKey clientRsaPrivateKey = new JcaPGPKeyConverter().getPrivateKey(clientPgpPrivateKey); //Convert PGP Key to RSA Key System.out.println("#b.1. RSA Key for token signing:\n" + clientRsaPrivateKey.toString() + "\n"); System.out.println("#c. Generating token using jwtBuilder: "); JwtBuilder jwtBuilder = Jwts.builder().setHeader(headers).setClaims(claims).signWith(clientRsaPrivateKey, SIGNATURE_ALG); token = jwtBuilder.compact(); System.out.println("#c.1 Generated Token:\nJWS " + token); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (PGPException e) { e.printStackTrace(); } return token; }
Fields in the JWT Header
The below table defines the fields (“claims”) that should be put inside the JWT header:
Code | Name | Type | Mandatory | Description | Example |
---|---|---|---|---|---|
typ | Token Type | String | Yes | MUST set this to “JWT” | "JWT" |
kid | Key ID | Long.toHexString | Yes | Public Key Id which HSBC uses to verify JWT signature. HSBC reads the public key by this key ID, from the PGP key file provided by our client/ partners, to verify JWT signature. | "900864F8C11EB743" |
alg | Signing Algorithm | String | Yes | Algorithm to verify the signature on the token. The following algorithms are supported: RS256, RS384, RS512, PS256, PS384, PS512. | "PS256" |
ver | Version | String | Yes | HSBC private claim. Currently the partner MUST set it as "1.0". | "1.0" |
Note: We recommend the PS256, PS384, and PS512 algorithms over the other RSA algorithms. The PKCS#1.5 padding scheme (RS256, RS384, and RS512) does not provide the desired level of security and generally should be replaced by the PSS padding scheme.
Example structure:
{
"typ": "JWT",
"kid": "A9248D0E4A463426",
"alg": "PS256"
"ver": "1.0"
}
Fields in the JWT Payload
The below table defines the fields (“claims”) that should be put inside the JWT payload:
Code | Name | Type | Mandatory | Description | Example |
---|---|---|---|---|---|
jti | JWT ID | String | Yes | Case sensitive unique identifier of the token even among different issuers. There is a negligible probability that the same value will be accidentally assigned to a different data object; if the application uses multiple issuers, collisions MUST be prevented among values produced by different issuers as well. The "jti" claim can be used to prevent the JWT from being replayed. The "jti" value is a case-sensitive string. | "74760410-f963-11e8-b2a3-1bb26e1e5b69" |
iat | Issued At | Long | Yes | Identifies the time at which the JWT was issued. The value must be a NumericDate. | 1565150776 |
sub | Subject | String | Yes | Identifies the who send the request. MUST provide "Client/ Partner Profile ID" value | "TAAS000000001" |
obo.sub | OnBehalfOf | String | No | Identifies the the request is being sent on-behalf of which customer | "customer001" |
aud | Audience | String | Yes | Identifies the recipients that the JWT is intended for. Always "taas" or "baas" | "taas" |
payload_hash | Payload hash value | String | Yes | Hashing value of the HTTP request payload body. This is used for Mule policy to do validation | "1dab559f1f4bf4f3ca..." |
payload_hash_alg | Payload hash algorithm | String | Yes | Hashing algorithm of the payload_hash. Below algorithm supported:
|
"RSASHA256" |
Example structure:
{
"jti": "5ccfd3a0-36a1-11ea-b780-eeee0af2723c",
"iat": 1578987726,
"sub": "TAAS000000XXX",
"obo": {
"sub":"customer001"
},
"aud": "taas",
"payload_hash": "a00ccb...",
"payload_hash_alg": "RSASHA256",
}
Related articles