API encryption guide

Encryption

The calls against the API need to be encrypted before sending. The scenario of sending encrypted API-calls will be like this:

  1. Create a HTTP-request (XML/JSON for SOAP/REST).

  2. Encrypt the HTTP-request.

  3. Use the same HTTP-request with the encrypted data.

  4. Send the request.

The scenario of receiving encrypted API-calls will be like this:

  1. Get the response.

  2. Decrypt the encrypted response.

The current encryption algorithm that is configured can be checked through the API-call GetObject with type "ApplicationInfo". This type is always non- encrypted.

As default, the encryption algorithm will be AES-256.

When call GetObject with type "ApplicationInfo", the response will contain an object named "SecurityMode" with the following types:

ApplicationInfo.SecurityMode.IsEnabled = true
ApplicationInfo.SecurityMode.CompressionAlgorithm = ""
ApplicationInfo.SecurityMode.EncryptionAlgorithm = AES
ApplicationInfo.SecurityMode.EncryptionLength = 256
ApplicationInfo.SecurityMode.HashAlgorithm = SHA256-HMAC

The structure of an encrypted request should be like this:

  • Encrypted SOAP-request

  • Encrypted REST-request

Encrypted SOAP-request
<?xml version="1.0" encoding="utf-8"?>

<s:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

  <s:Header>
    <Action s:mustUnderstand="1"
            xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">
      http://www.pointsharp.com/netid/server/portal/IServiceSoap/GetObject
    </Action>
  </s:Header>

  <s:Body>
    <GetObject xmlns="http://www.pointsharp.com/netid/server/portal">
      <Info>
        <SessionId></SessionId> (1)
        <Blob></Blob> (2)
        <Count></Count> (3)
      </Info>
    </GetObject>
  </s:Body>

</s:Envelope>
1 The SessionId type is mandatory. The SessionId is receieved from the first login call (see API:Login for information receiving this value). The value must a base64-string.
2 The Blob type is mandatory. The value must contain the encrypted call as a base64-string.
3 The Count type is mandatory. The value is a counter of calls within the same session. This means that two identical calls cannot be sent twice, it must always be a unique value per call. The simpliest way of doing this is to sequence the counter per call, for example, 1, 2, 3, 4, 5 etc. The value must be an numeric value.
Encrypted REST-request
{
  "SessionId":"", (1)
  "Blob":"", (2)
  "Count":"" (3)
}
1 The SessionId type is mandatory. The SessionId is receieved from the first login call (see API:Login for information receiving this value). The value must a base64-string.
2 The Blob type is mandatory. The value must contain the encrypted call as a base64-string.
3 The Count type is mandatory. The value is a counter of calls within the same session. This means that two identical calls cannot be sent twice, it must always be a unique value per call. The simpliest way of doing this is to sequence the counter per call, for example, 1, 2, 3, 4, 5 etc. The value must be an numeric value.
Example 1. Example of loading a user using encryption with SOAP.
  1. See the example in the GetObject section for a SOAP-request. Take the Info-element data from the XML request:

    <Info>
      <SessionId>fS1gy9uVDX6lFuX36hFWpTPLupI=</SessionId>
      <Type>USER</Type>
      <Id>3</Id>
      <Count>2</Count>
    </Info>
  2. Convert the XML to JSON:

    {
      "SessionId":"fS1gy9uVDX6lFuX36hFWpTPLupI=",
      "Type":"USER",
      "Id":"3",
      "Count":"2"
    }
  3. Encrypt the data into a base64-string:

    jPaQFMGlrNYC0EomAiB/Vjtc/HK43JfpUYwqIi9+YuJqKZKqsjN34D+qNjqElqAGWjVJ+RjWr9nz baqETF3QyqBcCeEvBb+OPj1QRWrKm1E=
  4. Add the encrypted base64-string into the Blob type:

    <?xml version="1.0" encoding="utf-8"?>
    <s:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    
      <s:Header>
        <Action s:mustUnderstand="1"
                xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">
          http://www.pointsharp.com/netid/server/portal/IServiceSoap/GetObject
        </Action>
      </s:Header>
    
      <s:Body>
        <GetObject xmlns="http://www.pointsharp.com/netid/server/portal">
          <Info>
            <SessionId>fS1gy9uVDX6lFuX36hFWpTPLupI=</SessionId>
            <Blob>jPaQFMGlrNYC0EomA...</Blob>
            <Count>2</Count>
          </Info>
        </GetObject>
      </s:Body>
    
    </s:Envelope>
  5. Send the SOAP-request.

  6. Receive the SOAP-reponse:

    <?xml version="1.0" encoding="utf-8"?>
    
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    
      <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    
        <GetObjectResponse xmlns="http://www.pointsharp.com/netid/server/portal">
          <GetObjectResult>
            <Blob>mTh8F9LeVKSKYPrGsKHidZlI...</Blob>
          </GetObjectResult>
        </GetObjectResponse>
    
      </s:Body>
    
    </s:Envelope>
  7. Decrypt the content of the Blob type which will be the response:

    {
      "User": {
        "Id": "3",
        "Name": "John Doe",
        "EmploymentType": "PermanentContract",
        "SerialNumber": "191212121212",
        "Phone": "0701234567",
        "Email": "john.doe@contoso.com",
        "OrganizationName": "Contoso Ltd"
      },
      "Status": {
        "Code": "Success",
        "Description": "Success"
      }
    }
Example 2. Example of loading a user using encryption with REST.
  1. See the example in the GetObject section for a REST-request.

    {
      "SessionId":"fS1gy9uVDX6lFuX36hFWpTPLupI=", "Type":"USER",
      "Id":"3",
      "Count":"2"
    }
  2. Encrypt the data into a base64-string:

    jPaQFMGlrNYC0EomAiB/Vjtc/HK43JfpUYwqIi9+YuJqKZKqsjN34D+qNjqElqAGWjVJ+RjWr9nz baqETF3QyqBcCeEvBb+OPj1QRWrKm1E=
  3. Add the encrypted base64-string into the Blob type:

    {
      "SessionId":"fS1gy9uVDX6lFuX36hFWpTPLupI=",
      "Blob":"jPaQFMGlrNYC0EomA...",
      "Count":"2"
    }
  4. Send the REST-request.

  5. Recieve the REST-respose:

    {
      "Blob":"ptwyPYz+p0H6TJ50d..."
    }
  6. Decrypt the content of the Blob type which will be the response:

    {
      "User":\{ "Id":"3",
      "Name":"John Doe",
      "EmploymentType":"PermanentContract",
      "SerialNumber":"191212121212",
      "Phone":"0701234567",
      "Email":"john.doe@contoso.com",
      "OrganizationName":"Contoso Ltd"
      },
      "Status":{
        "Code":"Success",
        "Description":"Success"
      }
    }

Encryption key and initial vector

For making a base64-encoded encrypted string, a key and initial vector is needed for this operation.

All the information needed for the key and initial vector is received through the login operation. See the example in the API:Login section for receiving this information.

Information needed from the login procedure:

  • The date and time, for example, 2019-09-06 06:33:35 (19 bytes)

  • The server nonce (32 bytes)

  • The client nonce (32 bytes)

Additional information: * Type ("key" or "iv"). * Count ("1" or current sequence counter of the call).

Derive the encryption key:

  1. Concat the server nonce, client nonce, type and count which always will be total amount of 68 bytes (servernonce+clientnonce+"key"+"1") (32+32+3+1).

  2. Run the 68 bytes of data through HMAC with the date and time (19 bytes) as key. The current HMAC-algorithm can be loaded from the GetObject:ApplicationInfo call (ApplicationInfo.SecurityMode.HashAlgorithm).

  3. Take the first bytes of the HMAC-result depending on algorithm that will be used for the encryption. See the length specification below. For AES- 256 the size of key needs to be 32 bytes.

  4. The derived key is the first 32 bytes in this example and should be used as encryption key.

Derive the encryption iv (initial vector):

  1. Concat the server nonce, client nonce, type, and count (servernonce+clientnonce+"iv"+count) (32+32+2+X).

  2. Run the data through HMAC with the date and time (19 bytes) as key. The length of the HMAC-algorithm can be loaded from the GetObject:ApplicationInfo call (ApplicationInfo.SecurityMode.HashAlgorithm).

  3. Take the first bytes of the HMAC-result depending on algorithm that will be used for the encryption. See the length specification below. For AES, the size of iv needs to be 16 bytes.

  4. The derived iv is the first 16 bytes in this example and should be used as encryption iv.

Key length specification:

  • AES-128 = 16 bytes

  • AES-192 = 24 bytes

  • AES-256 = 32 bytes

  • 3DES-128 = 16 bytes

  • 3DES-192 = 24 bytes

Initial vector length specification: * AES = 16 bytes * 3DES = 8 bytes