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.