Message signing and signature validation

To prevent the man-in-the-middle attack, both the request and response message must be signed by the sender and the signature must be validated by the recipient.


The ZOLOZ service is forced to validate the signature of each request message, so the merchant must sign the request properly. The ZOLOZ service is also guaranteed to sign the response message, while the signature validation of the response message is optional for the merchant. However, it is strongly recommended for the merchant to validate the signature against all responses.

#Sign a message

#Message signing process flow

The following diagram shows how to sign a request message from the merchant's perspective and how to sign a response message from the ZOLOZ service's perspective.

image.png

Figure 1. Message signing activity diagram


#Procedure to sign a message

The following steps demonstrate how to sign a message.

#1. Get the private key

To sign a message, a private key must be used.

  • For a request message, a RSA 2048 key-pair must be generated on the merchant's side. The generated key-pair includes a private key. The merchant then uses the private key to sign the request message.
  • For a response message, a RSA 2048 key-pair is generated in the ZOLOZ system when the account of the merchant is created. The generated key-pair is unique for each merchant and includes a private key. The ZOLOZ service then uses the private key to sign the response message.


#2. Construct the content to be signed

The content to be signed is a string that is composed of several elements, which are different depending on whether the message is a request or a response.

#For a request message

The content string that needs to be signed by the merchant is constructed in the following format:

copy
<Request Method> <Request URI>
<Client ID>.<Request Time>.<Request Body>

Thus construct the content string to be signed by sequentially concatenating the following strings:

    1. The request method
    2. A white space character (" ")
    3. The requested URI
    4. A new-line character ("\n")
    5. The client ID
    6. A dot character (".")
    7. The request time that is set in the Request-Time header field.
    8. A dot character (".")
    9. The request body

The following example shows a content string to be signed by the merchant:

copy
POST /api/v1/zoloz/authentication/test
2089012345678900.2020-01-01T08:00:00+0800.{
  "title": "hello",
  "description": "just for demonstration."
}


#For a response message

The content string to be signed by the ZOLOZ service is the same with the content string to be validated by the merchant. Refer to the section construct the content to be validated (for a response message) for more information.


#3. Calculate the signature

Calculate the signature by using the following formula:

copy
SIGNATURE=base64urlsafe_encode(sha256withrsa_sign($CONTENT_TO_BE_SIGNED, $PRIVATE_KEY))

Methods that are used:

  • sha256withrsa_sign : the method to generate a digital signature for the content provided. For more information, see sha256withrsa_sign.
  • base64urlsafe_encode : the method to encode the generated digital signature. For more information, see base64urlsafe_encode.

Input parameters:

  • CONTENT_TO_BE_SIGNED : the content string that is constructed in Step 2.
  • PRIVATE_KEY : the private key that is generated in Step 1.

Output parameter:

  • SIGNATURE : the signature string that is finally generated.


#4. Configure signature in header

Specify the generated signature string in the Signature field of the HTTP request or response header in the following format:

copy
Signature: algorithm=RSA256, signature=<SIGNATURE>


#Validate the signature

#Signature validation process flow

The following diagram shows how to validate the signature for a request message from the ZOLOZ service's perspective, and how to validate the signature for a response message from the merchant's perspective.

image.png

Figure 2. Signature validation activity diagram

#Procedure to validate a signature

The following steps demonstrate how to validate a signature.

#1. Get the public key

To validate a signature, a public key must be used.

  • For a request message, the public key that the ZOLOZ service uses is from the RSA 2048 key-pair that is generated by the merchant. The public key must be registered in the ZOLOZ system before any request is sent. The ZOLOZ service then uses the registered public key to validate the signature for each request from the merchant.
  • For a response message, the merchant must get the public key that is provided by the ZOLOZ service. The public key is from the RSA 2048 key-pair that is generated by the ZOLOZ system when the account of the merchant is created. The merchant then uses the public key to validate the signature of each response that is returned from ZOLOZ.

For more information about how to register a public key for the request in the ZOLOZ system or obtain a public key for the response from the ZOLOZ system, see xxx.

#2. Construct the content to be validated.

The content to be validated is a string that is composed of several elements, which are different depending on whether the message is a request or a response.

#For a request message

The content string to be validated by the ZOLOZ service is the same with the content string that has been signed by the merchant. Refer to the section construct the content to be signed (for a request message) for more information.

#For a response message

The content string that needs to be validated by the merchant is constructed in the following format:

copy
<Request Method> <Request URI>
<Client ID>.<Response Time>.<Response Body>

Thus construct the content string to be validated by sequentially concatenating the following strings:

  • The request method
  • A white space character (" ")
  • The requested URI
  • A new-line character ("\n")
  • The client ID
  • A dot character (".")
  • The response time that is set in the Response-Time header field
  • A dot character (".")
  • The response body

The following example shows a content string to be validated:

copy
POST /api/v1/zoloz/authentication/test
2089012345678900.2020-01-01T08:00:01+0800.{
  "title": "hello",
  "description": "just for demonstration."
}


#3. Extract signature from header

Extract the signature from the Signature field of the HTTP request or response header.

copy
Signature: algorithm=RSA256, signature=<SIGNATURE_TO_BE_EXTRACTED>


#4. Validate the signature

Use the following formular to check whether the extracted signature matches the to-be-validated content string:

copy
IS_SIGNATURE_VALID=sha256withrsa_verify($CONTENT_TO_BE_VALIDATED, base64urlsafe_decode($SIGNATURE), $PUBLIC_KEY))

Methods that are used:

  • base64urlsafe_decode : the method to decode the signature that is extracted in Step 3. For more information, see base64urlsafe_decode.
  • sha256withrsa_verify : the method to verify the signature. For more information, see sha256withrsa_verify.

Input parameters:

  • CONTENT_TO_BE_VALIDATED : the content string that is constructed in Step 2.
  • SIGNATURE : the signature string that is extracted in Step 3.
  • PUBLIC_KEY : the public key that is fetched in Step 1.

Output parameter:

  • IS_SIGNATURE_VALID : a boolean value that specifies whether the extracted signature matches the to-be-validated content string.