ZOLOZZOLOZDOCS

      The Gateway Protocol

      #Introduction

      The ZOLOZ service is provided in the form of a collection of WEB APIs which are exposed by our gateway service. The gateway is the key facility for data exchange between the customers and the ZOLOZ service.


      In this document, we introduce the gateway protocol, a set of rules that enables the interaction between the customer and the ZOLOZ service with robustness, reliability and security.


      Topics

      • Message Format
      • Transmission Security
      • Compatibility


      #Message Format

      The request and response of the APIs are carried by HTTP with particular format.

      #Request Message

      image.png

      #Request URL

      The format of the request URL is https://{host}/api/v{majorVersion}/{path} , in which

      • host is the domain of ZOLOZ service;
      • majorVersion is the major version of the interface, typically a positive integer;
      • path is the path of the interface.


      #Request Method

      The ONLY accepted request method is POST .


      #Request Header

      The request header contains information about the client, signature and encryption.


      #Request-Time (Mandatory)

      The request time in rfc3339 format, e.g., 2019-04-04T12:08:56+05:30 .


      #Content-Type (Mandatory)

      The media type of the request body sent to the recipient (see rfc2616 for more information). Only two content types is supported:

      • application/json; charset=UTF-8 : accepted when the request is not encrypted.
      • text/plain; charset=UTF-8 : accepted when the request is encrypted.


      #Client-Id (Mandatory)

      The client identifier assigned to the customer, it's guaranteed to be unique for each customer. Typically it's a string composing of 16 digits.


      #Signature (Mandatory)

      The information about the signature of the message, the header value is composed of following 2 key-value pairs, joined with comma:

      • algorithm : indicate the algorithm used for signing, only RSA256 is accepted.
      • signature : base64 encoded string of the signature content.


      Here's a sample header entry:

      copy
      signature: algorithm=RSA256, signature=IpmAgtDqkjOz5sEEVlEq8OkdShXMJyXaK+6gtX/idB3+Hlhqnzdf90redIiJkawUlrY+icf1NhzSISiULGIAih72y/QRg/LlyWIWRE+GHx+k7Wl1wEYazvXRDQWF2TIia7SyyIhtjqIXj4BZ+409X72SOnx21qOU5eKxkgJQ8ZEVg5BFzXe0E//ISxJURBkVC1Q8v+7mnuT+YzgKvD1aMo16sYZih9ueTlj4xDPC8nKEoT+WJGjbdV7Ww/PXP419bGii9e7agLdxudGjD2B9d/IeUj8/w75u6V7PtdS8jCpyZQ0a28PcpvMD7yQ5f0odh7/6xGL6jECx3Y2YiuYCkw==


      Refer to Signature and Validation section for more information.


      #Encrypt (Optional)

      The information about the encryption of the message, the header value is composed of following 3 key-value pairs, joined with comma:

      • algorithm : indicate the algorithm used for signing, only RSA_AES is accepted.
      • symmetricKey : base64 encoded string of the AES key encrypted with RSA.


      Here's a sample header entry:

      copy
      encrypt: algorithm=RSA, symmetricKey=FxE+siNhE2eQsnbui/6llu6TG9CaXFmT8gb2Z5bsvf2WGlAnoXoBrcB1bYodBnRs/CzSeEewFc4HOIqHejTepHehy86M9DUdefjYC783+LGBstQTPlLGsqcsYxPJTMCGYfTD6DSSXwqtKSiqD6q6C96zkp3/Q2ScmCAJprqtcA5SUj+cRmIdtG1OStSdHrQ+SstT74pwMbv1qlHbTeitZMTt5GNFXnhT1B3htS1sFb0BQ2OA+V2BtPW/izEP5ebrkfNQWmQKd6gc/i0j/DGBw4DQaxNfNvy2JHAljL5mP/ES9X0DJS6/MkimfDwXsSsTANWsjFfIoTodRn223HQC0w==


      Refer to Encryption and Decryption section for more information.


      #Request Body

      The request body is the content of the request message, contains the input parameters of the API. Refer to API specifications for more information about the content structure. The encoding of the content is different for non-encrypted request and encrypted request:

      • for non-encrypted request, the content is a JSON string;
      • for encrypted request, the content is the base64 encoded string of the encrypted data.


      #Full HTTP Request Samples

      #Non-encrypted request sample

      copy
      POST https://sg-production-api.zoloz.com/api/v1/zoloz/authentication/test HTTP/1.1
      Content-Type: application/json; charset=UTF-8
      Client-Id: 2089012345678900
      Request-Time: 2020-01-01T12:00:00+08:00
      Signature: algorithm=RSA256, signature=KEhXthj4bJ801Hqw8kaLvEKc0Rii8KsNUazw7kZgjxyGSPuOZ48058UVJUkkR21iD9JkHBGRrWiHPae8ZRPuBagh2H3qu7fxY5GxVDWayJUhUYkr9m
      
      {
        "title": "hello",
        "description": "just for demonstration."
      }


      With cURL we could send the sample request like this:

      copy
      curl -X POST                                         \
      -H 'Content-Type: application/json; charset=UTF-8'   \
      -H 'Client-Id: 2089123456789012'                     \
      -H 'Request-Time: 2019-04-04T12:08:56+05:30'         \
      -H 'Signature: algorithm=RSA256, signature=KEhXthj4bJ801Hqw8kaLvEKc0Rii8KsNUazw7kZgjxyGSPuOZ48058UVJUkkR21iD9JkHBGRrWiHPae8ZRPuBagh2H3qu7fxY5GxVDWayJUhUYkr9m' \
      -d '{
        "title": "hello",
        "description": "just for demonstration."
      }' https://sg-production-api.zoloz.com/api/v1/zoloz/authTest


      #Encrypted request sample

      copy
      POST https://sg-production-api.zoloz.com/api/v1/zoloz/authentication/test HTTP/1.1
      Content-Type: text/plain; charset=UTF-8
      Client-Id: 2089012345678900
      Request-Time: 2020-01-01T12:00:00+08:00
      Signature: algorithm=RSA256, signature=KEhXthj4bJ801Hqw8kaLvEKc0Rii8KsNUazw7kZgjxyGSPuOZ48058UVJUkkR21iD9JkHBGRrWiHPae8ZRPuBagh2H3qu7fxY5GxVDWayJUhUYkr9m
      Encrypt: algorithm=RSA_AES, symmetricKey=FxE+siNhE2eQsnbui/6llu6TG9CaXFmT8gb2Z5bsvf2WGlAnoXoBrcB1bYodBnRs/CzSeEewFc4HOIqHejTepHehy86M9DUdefjYC783+LGBstQTPlLGsqcsYxPJTMCGYfTD6DSSXwqtKSiqD6q6C96zkp3/Q2ScmCAJprqtcA5SUj+cRmIdtG1OStSdHrQ+SstT74pwMbv1qlHbTeitZMTt5GNFXnhT1B3htS1sFb0BQ2OA+V2BtPW/izEP5ebrkfNQWmQKd6gc/i0j/DGBw4DQaxNfNvy2JHAljL5mP/ES9X0DJS6/MkimfDwXsSsTANWsjFfIoTodRn223HQC0w==
      
      r8w8wbc8Nv6sC2meJzArtGjDkbiAzg55UaDiq7TId1a7uzcv18qpOxVkXvqa3q/6TPemDDItZ79oHMzDJyvAngYqfpZZaedArWPCDeddqUl62zU5VwaB1NVhNmjHLNQ6bA1LxpsnMGnb6n8iWAEU4MtJ3TpXerMY6RToSBbI/IBA4MJFbXds0z6XLqQh9XNrLL/J0FUSV0XGFiBRxVMvUP2ytzEKh9HE6fqX/ZqTqadtp89PRTJZM87Rkb3oPdJAlaM7JUaIznGrtKe45UwjtrdYk86QhOmpWXj4L2g0Gww=


      With cURL we could send the sample request like this:

      copy
      curl -X POST                                  \
      -H 'Content-Type: text/plain; charset=UTF-8'   \
      -H 'Client-Id: 2089123456789012'              \
      -H 'Request-Time: 2019-04-04T12:08:56+05:30'  \
      -H 'Encrypt: algorithm=RSA_AES, symmetricKey=FxE+siNhE2eQsnbui/6llu6TG9CaXFmT8gb2Z5bsvf2WGlAnoXoBrcB1bYodBnRs/CzSeEewFc4HOIqHejTepHehy86M9DUdefjYC783+LGBstQTPlLGsqcsYxPJTMCGYfTD6DSSXwqtKSiqD6q6C96zkp3/Q2ScmCAJprqtcA5SUj+cRmIdtG1OStSdHrQ+SstT74pwMbv1qlHbTeitZMTt5GNFXnhT1B3htS1sFb0BQ2OA+V2BtPW/izEP5ebrkfNQWmQKd6gc/i0j/DGBw4DQaxNfNvy2JHAljL5mP/ES9X0DJS6/MkimfDwXsSsTANWsjFfIoTodRn223HQC0w==' \
      -d 'r8w8wbc8Nv6sC2meJzArtGjDkbiAzg55UaDiq7TId1a7uzcv18qpOxVkXvqa3q/6TPemDDItZ79oHMzDJyvAngYqfpZZaedArWPCDeddqUl62zU5VwaB1NVhNmjHLNQ6bA1LxpsnMGnb6n8iWAEU4MtJ3TpXerMY6RToSBbI/IBA4MJFbXds0z6XLqQh9XNrLL/J0FUSV0XGFiBRxVMvUP2ytzEKh9HE6fqX/ZqTqadtp89PRTJZM87Rkb3oPdJAlaM7JUaIznGrtKe45UwjtrdYk86QhOmpWXj4L2g0Gww=' \
      https://sg-production-api.zoloz.com/api/v1/zoloz/authentication/test


      #Response Message

      image.png

      #Response Header

      #Response-Time

      The response time in rfc3339 format, e.g., 2019-04-04T12:08:56+05:30 .


      #Content-Type 

      The media type of the response body returned to the customer (see rfc2616 for more information). Only two content types are possible: 

      • application/json; charset=UTF-8 : if the response is not encrypted.
      • text/plain; charset=UTF-8 : if the response is encrypted.


      #Signature 

      Similar with that in request, the signature  header in response contains the information about the signature of the message, the header value is composed of following 2 key-value pairs, joined with comma:

      • algorithm : indicates the algorithm used for signing, only RSA256 is accepted.
      • signature : base64 encoded string of the signature content.


      Here's a sample header entry:

      copy
      signature: algorithm=RSA256, signature=IpmAgtDqkjOz5sEEVlEq8OkdShXMJyXaK+6gtX/idB3+Hlhqnzdf90redIiJkawUlrY+icf1NhzSISiULGIAih72y/QRg/LlyWIWRE+GHx+k7Wl1wEYazvXRDQWF2TIia7SyyIhtjqIXj4BZ+409X72SOnx21qOU5eKxkgJQ8ZEVg5BFzXe0E//ISxJURBkVC1Q8v+7mnuT+YzgKvD1aMo16sYZih9ueTlj4xDPC8nKEoT+WJGjbdV7Ww/PXP419bGii9e7agLdxudGjD2B9d/IeUj8/w75u6V7PtdS8jCpyZQ0a28PcpvMD7yQ5f0odh7/6xGL6jECx3Y2YiuYCkw==


      Refer to Signature and Validation section for more information.


      #Encrypt

      Similar with that in request, the encrypt  header in response contains the encryption information of the message, the header value is composed of following 2 key-value pairs, joined with comma:

      • algorithm : indicates the algorithm used for signing, only RSA_AES is accepted.
      • symmetricKey : base64 encoded string of the AES key encrypted with RSA.


      Here's a sample header entry:

      copy
      encrypt: algorithm=RSA_AES, symmetricKey=FxE+siNhE2eQsnbui/6llu6TG9CaXFmT8gb2Z5bsvf2WGlAnoXoBrcB1bYodBnRs/CzSeEewFc4HOIqHejTepHehy86M9DUdefjYC783+LGBstQTPlLGsqcsYxPJTMCGYfTD6DSSXwqtKSiqD6q6C96zkp3/Q2ScmCAJprqtcA5SUj+cRmIdtG1OStSdHrQ+SstT74pwMbv1qlHbTeitZMTt5GNFXnhT1B3htS1sFb0BQ2OA+V2BtPW/izEP5ebrkfNQWmQKd6gc/i0j/DGBw4DQaxNfNvy2JHAljL5mP/ES9X0DJS6/MkimfDwXsSsTANWsjFfIoTodRn223HQC0w==


      Refer to Encryption and Decryption section for more information.


      #Response Body

      The response body is the content of the returned message, contains the output parameters of the API. Refer to API specifications for more information about the content structure.


      #Content Encoding

      • for non-encrypted response, the content is a JSON string;
      • for encrypted response, the content is the base64 encoded string of the encrypted data.

      #Common Result Structure

      There's a common result structure in the response, i.e.:

      copy
      {
        "api_specified_field1":"value1",
        "api_specified_field2":"value2",
        "result": {
          "resultCode":"SUCCESS",
          "resultStatus":"S",
          "resultMessage":"success"
        }
      }


      The "result" field is intended to show business level and gateway level status. The interface level status are different from one API to another, please refer to the corresponding API specification documents. In this section, we only present the gateway level status.


      The enumeration of the gateway level status codes are listed below:

      No.

      resultCode

      resultStatus

      resultMessage

      http status

      1

      SUCCESS

      S

      success

      200

      2

      PARAM_MISSING

      F

      param missing

      400

      3

      PARAM_ILLEGAL

      F

      param illegal

      400

      4

      SIGNATURE_INVALID

      F

      signature invalid

      401

      5

      KEY_NOT_FOUND

      F

      key not found

      401

      6

      ACCEPTED_SUCCESS

      A

      accepted success

      202

      7

      ACCEPTED_IDEMPOTENT_ERROR

      A

      accepted idempotent error

      202

      8

      NO_INTERFACE_DEF

      F

      API is not defined

      404

      9

      API_IS_INVALID

      F

      api is invalid

      400

      10

      MSG_PARSE_ERROR

      F

      msg format invalid

      400

      11

      OAUTH_FAIL

      F

      oauth fail

      401

      12

      VERIFY_ISV_ACCESS_TOKEN_FAIL

      F

      verify isv access token fail

      401

      13

      PROCESS_FAIL

      F

      process fail

      500

      14

      ACCESS_DENIED

      F

      access denied

      403

      15

      SYSTEM_BUSY

      F

      system busy

      503

      16

      REQUEST_TRAFFIC_EXCEED_LIMIT

      F

      request traffic exceed limit

      429

      17

      UNSUPPORTED_OPERATION

      F

      Unsupported Operation

      500

      18

      SYSTEM_ERROR

      U

      system error

      500

      19

      UNKNOWN_EXCEPTION

      U

      Unknown exception

      500

      20

      PROCESS_TIMEOUT

      F

      process timeout

      500


      #Full HTTP Response Sample

      #Non-encrypted response

      copy
      HTTP/1.1 200 OK
      Content-Type: application/json; charset=UTF-8
      Response-Time: 2019-11-19T21:56:15-0800
      Signature: algorithm=RSA256, signature=xxxxxxxxxxxxxxxxxx
      
      {
        "title": "hello",
        "description": "just for demonstration."
        "result": {
          "resultCode":"SUCCESS",
          "resultStatus":"S",
          "resultMessage":"success"
        }
      }


      #Encrypted response

      copy
      HTTP/1.1 200 OK
      Content-Type: text/plain; charset=UTF-8
      Response-Time: 2019-11-19T21:56:15-0800
      Signature: algorithm=RSA256, signature=xxxxxxxxxxxxxxxxxx
      Encrypt: algorithm=RSA_AES, symmetricKey=xxxxxxxxxxxxxx
      
      xxxxxxxxxx encrypted response string xxxxxxxxxxxx



      #Transmission Security

      #Sequence Overview

      The transmission security is guaranteed with signature validation and message encryption. Message signing and signature validation is mandatory for all requests and response, and message encryption is optional, up to the customer's requirements.


      If encryption is adopted, then the message body should be encrypted before signed, the whole interacting sequence is illustrated below:

      The Gateway Protocol


      #Algorithm Description

      #utf8_encode 

      This method encodes the binary data to text string in UTF-8 encoding.

      #base64urlsafe_encode 

      This method implements the Base64 encoding algorithm as specified in RFC 3548, which encodes arbitrary binary data into text strings that can be safely used as parts of URLs, or included as part of an HTTP POST request.

      #base64urlsafe_decode

      This method implements the Base64 decoding algorithm as specified in RFC 3548, which decodes text string encoded with base64_encode to original binary data.

      #sha256withrsa_sign 

      This method implements the PKCS#1 v1.5 padding and modular exponentiation with the formal name RSASSA-PKCS1-v1_5 after calculating the hash over the data using SHA256.

      #sha256withrsa_verify

      This method validates whether the content string matches the signature generated with sha256withrsa .

      #rsa_encrypt 

      This method encrypts message with RSA/ECB/PKCS1Padding.

      #rsa_decrypt 

      This method decrypts cipher text encrypted with RSA/ECB/PKCS1Padding.

      #aes_encrypt

      This method encrypts message with AES.

      #aes_decrypt 

      This method decrypts cipher text encrypted with AES.


      #Signature and Validation

      To make sure no man-in-the-middle attack is carried out, both the request message and the response message should be signed by sender and be validated by recipient.


      ZOLOZ service forces to validate the signature of each request so the customer needs to sign the request properly; ZOLOZ service also guarantees to sign the response, however, the signature validation to the response is optional for the customer. Even though, it is highly recommended for the customer to validate the signature against all responses.


      #Sign Message

      image.png


      #1. Get the private key

      For request (the customer concerns)

      An RSA 2048 key-pair MUST be generated on the customer's side before hands, of which the private key is the desired key for request message signing.

      For response (ZOLOZ concerns)

      An RSA 2048 key-pair is generated in ZOLOZ's system once the account of the customer is created, it's guaranteed to be unique for each customer. ZOLOZ will use the private key for response message signing.


      #2. Construct the data to be signed

      For request

      The content string that need to be signed for the request is composed by several parts, the format is:

      copy
      <HTTP METHOD> <HTTP URI>
      <Client-Id>.<Request-Time>.<HTTP BODY>


      It could be constructed by sequentially concatenate following strings:

      • The HTTP method (typically "POST")
      • A white space character (" ")
      • The requested URI
      • A new-line character ("\n")
      • The client ID
      • A dot character (".")
      • The request time (declared in the header) in format "yyyy-MM-dd'T'HH:mm:ssZ"
      • A dot character (".")
      • The HTTP body


      Here's an sample content string to be signed:

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


      For response

      The content string to be signed by ZOLOZ for the response is the same with the content string to be validated by the customer. Please refer to next section for more information.


      #3. Calculate the signature

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


      The signature is calculated with above formula, in which:

      • sha256withrsa_sign : refer to algorithm description.
      • base64urlsafe_encode : refer to algorithm description.
      • CONTENT_TO_BE_SIGNED : content string to be signed.
      • PRIVATE_KEY : private key fetched in step 1.
      • SIGNATURE : generated signature string.


      #4. Configure signature in header

      Once the signature is generated, put the signature string into the "Signature" field of HTTP request header in the format below:

      copy
      Signature: algorithm=RSA256, signature=<the generated signature string>


      #Validate Message with Signature


      image.png


      #1. Get public key

      For request (ZOLOZ concerns)

      An RSA 2048 key-pair MUST be generated on the customer's side before hands, of which the public key MUST be registered to ZOLOZ's system before any request is sent. ZOLOZ will use the public key registered to validate the signature of each request from the customer.


      For response (the customer concerns)

      An RSA 2048 key-pair is generated in ZOLOZ's system once the account of the customer is created, it's guaranteed to be unique for each customer. The customer needs to acquire the public key of ZOLOZ's before hands and then validate the signature of each response with this public key.


      #2. Construct the content to be validated

      For request (ZOLOZ concerns)

      The content string of the request to be validated by ZOLOZ is the same with the content string being signed by the customer. Please refer to previous section for more information.


      For response (the customer concerns)

      The content string that needs to be validated by the customer is composed by several parts, the format is:

      copy
      <clientId>.<responseTime>.<responseBody>


      It could be constructed by sequentially concatenate following strings:

      • The client ID
      • A dot character (".")
      • The response time (declared in the header) in format "yyyy-MM-dd'T'HH:mm:ssZ"
      • A dot character (".")
      • The HTTP body


      Here's an sample content string to be validated:

      copy
      2089012345678900.2020-01-01T08:00:01+0800.{
        "title": "hello",
        "description": "just for demonstration."
      }


      #3. Extract signature from header

      The desired signature string could be extracted from "Signature" header:

      copy
      Signature: algorithm=RSA256, signature=<the desired signature string>


      #4. Validate signature

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


      The content and the signature is validated with above formula, in which:

      • base64urlsafe_decode : refer to algorithm description.
      • sha256withrsa_verify : refer to algorithm description.
      • CONTENT_TO_BE_VALIDATED : content string to be validated.
      • SIGNATURE : signature string extracted in step 3.
      • PUBLIC_KEY : public key fetched in step 1.
      • IS_SIGNATURE_VALID : whether the signature matches the content.


      #Encryption and Decryption

      If the customer wants their transmitted data to be encrypted, the encryption capability could be turned on. By default, an encrypted request results in an encrypted response, and vice versa.


      #Encrypt Message


      image.png


      #1. Get the public key

      For request (the customer concerns)

      An RSA 2048 key-pair is generated in ZOLOZ's system once the account of the customer is created, it's guaranteed to be unique for each customer. The customer needs to acquire the public key of ZOLOZ's before hands and then encrypt the randomly-generated symmetric key with this public key for each request needs to be encrypted.


      For response (ZOLOZ concerns)

      An RSA 2048 key-pair MUST be generated on the customer's side before hands, of which the public key MUST be registered to ZOLOZ's system before any request is sent. ZOLOZ will use the public key registered to encrypt the randomly-generated symmetric key for each response (needs to be encrypted) returned to the customer.


      #2. Prepare the content to be encrypted

      The content to be encrypted is the plain message of the business request/response, typically a JSON string.


      #3. Generate AES key

      Generate an 128-bits AES key randomly.


      #4. Encrypt the content

      copy
      ENCYRPTED_CONTENT_STRING=base64urlsafe_encode(aes_encrypt($CONTENT_TO_BE_ENCRYPTED, $AES_KEY))


      The data is encrypted with above formula, in which:

      • base64urlsafe_encode : refer to algorithm description.
      • aes_encrypt : refer to algorithm description.
      • CONTENT_TO_BE_ENCRYPTED : the content string to be encrypted.
      • AES_KEY : the AES key generated in step 3.
      • ENCRYPTED_CONTENT_STRING : string of the encrypted content.


      #5. Encrypt the AES key

      copy
      ENCYRPTED_AES_KEY=base64urlsafe_encode(rsa_encrypt($AES_KEY, $PUBLIC_KEY))


      The signature is calculated with above formula, in which:


      #6. Set the header and body

      6.1 Configure the Encrypt header

      Put the encrypted AES key into the "Encrypt" field of HTTP header in the format below:

      copy
      encrypt: algorithm=RSA_AES, symmetricKey=<the encrypted AES key>
      6.2 Configure the Content-Type header

      Set the content type as text/plain :

      copy
      content-type: text/plain
      6.3 Set the HTTP body

      Set the encrypted content string as the HTTP body.


      #Decrypt Message


      image.png


      #1. Get the private key

      For request (ZOLOZ concerns)

      An RSA 2048 key-pair is generated in ZOLOZ's system once the account of the customer is created, it's guaranteed to be unique for each customer. ZOLOZ will use the private key to decrypt the symmetric key carried with the encrypted request.


      For response (the customer concerns)

      An RSA 2048 key-pair MUST be generated on the customer's side before hands, of which the private key is the desired key to decrypt the symmetric key carried with the encrypted response for the customer.


      #2. Get the content to be decrypted

      The data to be decrypted is the whole HTTP body, for both HTTP request and HTTP response.


      #3. Extract the encrypted AES key

      Extract the encrypted AES key from the Encrypt header, the header is in following format:

      copy
      encrypt: algorithm=RSA_AES, symmetricKey=<the encrypted AES key>


      #4. Decrypt the AES key

      copy
      AES_KEY=rsa_decrypt(base64urlsafe_decode($ENCRYPTED_AES_KEY), $PRIVATE_KEY)


      The AES key could be decrypted with above formula, in which:

      • base64urlsafe_decode : refer to algorithm description.
      • rsa_decrypt : refer to algorithm description.
      • ENCRYPTED_AES_KEY : the encrypted AES key extracted from step 3.
      • PRIVATE_KEY : the private key fetched in step 1.
      • AES_KEY : the original AES key randomly-generated to encrypt the message content.


      #5. Decrypt the content

      copy
      PLAIN_CONTENT_STRING=utf8_encode(aes_decrypt(base64urlsafe_decode($ENCRYPTED_CONTENT), $AES_KEY))


      The content is decrypted with above formula, in which:


      #API Compatibility

      The version of the API is encoded in url with pattern of v\d+ (e.g., v1 , v2 and etc.). ZOLOZ SaaS service will provide APIs of new version when incompatible changes are introduced. Meanwhile, compatible changes might be introduced at anytime for an existing version of API and the customer MUST properly handle possible compatible changes of the API. 


      Any case of following changes should be considered as compatible change:

      1. New optional field is added to the request.
      2. New valid value is defined for a request field.
      3. Allowed length of a request field increases.
      4. New field is added to the response.
      5. The order of the fields of the request or the response changes.


      ZOLOZ Team