Skip to main content

Signature

BBMSL online API provides the payment functions. Client and BBMSL must exchange RSA keys before making API calls, and the length of RSA key must be 2048 bits. When making API call to BBMSL, client uses the RSA private key to sign the API request. After receiving the API request, BBMSL will use the client’s RSA public key to verify whether the signature is matched to the content of API request.

About the sign:

  • Please use RSA2, SHA256WithRSA algorithm to sign the data.
  • The secretkey is following the PKCS8 spec.
  • Please use PKCS8 format private key to sign the data. (header: -----BEGIN PRIVATE KEY----- -----END PRIVATE KEY-----)
  • The sign string format is using string, please convert object to string.
  • Please note that signature is not a independent api. It is a cryptography to ensure the non-repudiation.
  • The content to be signed must be the same as api request content.
  • Each api request may contain signature.

RSA key pair#

An RSA key pair contains the private key and the public key. The private key is required for generating the signature, while the public key is used for verifying the signature.

Generating an RSA key pair#

Many tools can be used to generate the RSA key pair. The following steps assume that you use OpenSSL to generate the RSA key pair.

  1. Install OpenSSL.
  • For linux system, use the following command:
$ sudo apt-get install openssl
  1. Generate RSA key pair.
  • For linux system, use the following command:
$ openssl
OpenSSL> genrsa -out rsa_private_key.pem 2048 ## Generate private key
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt ## Transform private key into PKCS8 format
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem ## Generate public key
OpenSSL> exit
  • For windows system, use the following command:
C:\bbmsl>cd C:\OpenSSL-Win32\bin ##enter OpenSSL directory
C:\OpenSSL-Install-Dir\bin>openssl.exe ## Enter OpenSSL
OpenSSL> genrsa -out rsa_private_key.pem 2048 ## Generate private key
OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt ## Transform private key into PKCS8 format
OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem ## Generate public key
OpenSSL> exit

After that, you can see two files under current folder, rsaprivatekey.pem and rsapublickey.pem. The former is the private key and the latter is the public key.

Uploading RSA public key#

After the RSA2 key pair is generated, you must exchange the public key with the BBMSL server for signature verification by completing the following steps:

  • Upload your public key to BBMSL merchant portal
  • Obatin BBMSL public key

Signing the request#

The following figure illustrates a sample API request. The content enclosed by the two curly braces (inclusive) is what needs to be signed to create the RSA signature. And the generated signature is put in the signature parameter. Docusaurus

Perform the following steps to sign the message:

  1. Extract the content to be signed. For example:
"{\"paymentConfig\":{\"googlePayAllowed\":false,\"applePayAllowed\":true,\"enableAutoReceipt\":true,\"enableEmailInput\":true,\"cardNameRequired\":false,\"callbackUrl\":{\"fail\":\"https://www.bbmsl.com/fail\",\"success\":\"https://www.bbmsl.com/success\",\"cancel\":\"https://www.bbmsl.com/cancel\"}},\"orderInfo\":{\"merchantReference\":\"Martin0331\",\"currency\":\"HKD\"},\"lineItems\":[{\"quantity\":1,\"priceData\":{\"unitAmount\":1.22,\"name\":\"Alan\"}}]}"
  1. Hash the JSON content by using the SHA256withRSA algorithm. Then use the client's RSA private key to sign the value to obtain the signature. To achieve a better security level, the length of the RSA key/pairs must be 2048 bits. The following sample illustrates a raw signature:
sXSGdA4tR4B0wnF6Nr8ShpfNMtHISWuzLpdKoNWskIgCcspMVFFzgkez4BrmtYXkMqZh1tyz/8sNNU3F2VTu0fOx+ZP4CnmVjNu8bciu4hTtnytA3Y1GZ/yXAUD+mVYGXeyDO3fHrqDdI7k3xV/Q8FCOd0culTsN6RRMxMZq+oqR2x+EjOXVofp7BZJwhQE8Us4Al573FQz5EHDvCLx35lq2hoMhXLCVLVDBHcpCgotuY4mg91MXh/qqcFGY/hQKhGdWAbZ9tcp2Q5s2ESh37rqxnOwZrrepK8NC6vMBPUiSPxQefpev2nG0JzAHOjRPbBXYw1XBS6RBYKAmufZZiQ==
  1. Base64-encode the signature. A sample result is listed below:
c1hTR2RBNHRSNEIwd25GNk5yOFNocGZOTXRISVNXdXpMcGRLb05Xc2tJZ0Njc3BNVkZGemdrZXo0QnJtdFlYa01xWmgxdHl6LzhzTk5VM0YyVlR1MGZPeCtaUDRDbm1Wak51OGJjaXU0aFR0bnl0QTNZMUdaL3lYQVVEK21WWUdYZXlETzNmSHJxRGRJN2szeFYvUThGQ09kMGN1bFRzTjZSUk14TVpxK29xUjJ4K0VqT1hWb2ZwN0JaSndoUUU4VXM0QWw1NzNGUXo1RUhEdkNMeDM1bHEyaG9NaFhMQ1ZMVkRCSGNwQ2dvdHVZNG1nOTFNWGgvcXFjRkdZL2hRS2hHZFdBYlo5dGNwMlE1czJFU2gzN3JxeG5Pd1pycmVwSzhOQzZ2TUJQVWlTUHhRZWZwZXYybkcwSnpBSE9qUlBiQlhZdzFYQlM2UkJZS0FtdWZaWmlRPT0=
  1. Use the obtained string as the value of the Signature parameter. The following sample shows a whole API request:
{
"request": "{\"paymentConfig\":{\"googlePayAllowed\":false,\"applePayAllowed\":true,\"enableAutoReceipt\":true,\"enableEmailInput\":true,\"cardNameRequired\":false,\"callbackUrl\":{\"fail\":\"https://www.bbmsl.com/fail\",\"success\":\"https://www.bbmsl.com/success\",\"cancel\":\"https://www.bbmsl.com/cancel\"}},\"orderInfo\":{\"merchantReference\":\"Martin0331\",\"currency\":\"HKD\"},\"lineItems\":[{\"quantity\":1,\"priceData\":{\"unitAmount\":1.22,\"name\":\"Alan\"}}]}",
"signature":"c1hTR2RBNHRSNEIwd25GNk5yOFNocGZOTXRISVNXdXpMcGRLb05Xc2tJZ0Njc3BNVkZGemdrZXo0QnJtdFlYa01xWmgxdHl6LzhzTk5VM0YyVlR1MGZPeCtaUDRDbm1Wak51OGJjaXU0aFR0bnl0QTNZMUdaL3lYQVVEK21WWUdYZXlETzNmSHJxRGRJN2szeFYvUThGQ09kMGN1bFRzTjZSUk14TVpxK29xUjJ4K0VqT1hWb2ZwN0JaSndoUUU4VXM0QWw1NzNGUXo1RUhEdkNMeDM1bHEyaG9NaFhMQ1ZMVkRCSGNwQ2dvdHVZNG1nOTFNWGgvcXFjRkdZL2hRS2hHZFdBYlo5dGNwMlE1czJFU2gzN3JxeG5Pd1pycmVwSzhOQzZ2TUJQVWlTUHhRZWZwZXYybkcwSnpBSE9qUlBiQlhZdzFYQlM2UkJZS0FtdWZaWmlRPT0="
}

The sign code snippet in Java:

signature.java
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "SHA256WithRSA";
public String sign(String content, String privateKey) throws Exception {
final Base64.Encoder encoder = Base64.getEncoder();
final Base64.Decoder decoder = Base64.getDecoder();
byte[] keyBytes = decoder.decode(privateKey);
byte[] data = content.getBytes(StandardCharsets.UTF_8);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(data);
return encoder.encodeToString(signature.sign());
}

How to use the sign method:

signature.java
String request = "{\"paymentConfig\":{\"googlePayAllowed\":false,\"applePayAllowed\":true,\"enableAutoReceipt\":true,\"enableEmailInput\":true,\"cardNameRequired\":false,\"callbackUrl\":{\"fail\":\"https://www.bbmsl.com/fail\",\"success\":\"https://www.bbmsl.com/success\",\"cancel\":\"https://www.bbmsl.com/cancel\"}},\"orderInfo\":{\"merchantReference\":\"Martin0331\",\"currency\":\"HKD\"},\"lineItems\":[{\"quantity\":1,\"priceData\":{\"unitAmount\":1.22,\"name\":\"Alan\"}}]}";
String privateKey = "Your private key";
String signature = sign(request, privateKey);

The sign code snippet in PHP:

signature.php
<?php
$privateKey = "Your private key";
$privateKeyPem = "-----BEGIN PRIVATE KEY-----\n" . wordwrap($privateKey, 64, "\n", true) . "\n-----END PRIVATE KEY-----";
$request = "{\"paymentConfig\":{\"googlePayAllowed\":false,\"applePayAllowed\":true,\"enableAutoReceipt\":true,\"enableEmailInput\":true,\"cardNameRequired\":false,\"callbackUrl\":{\"fail\":\"https://www.bbmsl.com/fail\",\"success\":\"https://www.bbmsl.com/success\",\"cancel\":\"https://www.bbmsl.com/cancel\"}},\"orderInfo\":{\"merchantReference\":\"Martin0331\",\"currency\":\"HKD\"},\"lineItems\":[{\"quantity\":1,\"priceData\":{\"unitAmount\":1.22,\"name\":\"Alan\"}}]}";
openssl_sign($request, $encrypted, $privateKeyPem, OPENSSL_ALGO_SHA256);
$signature = base64_encode($encrypted);
?>