Back-end integration for the iOS app
Overview
When posting schedules to a URL for back-end integration, the app offers an optional hybrid encryption mechanism to enhance data security:
- Symmetric AES Encryption: Encrypts the data payload.
- Asymmetric RSA Encryption: Encrypts the AES encryption keys for secure key exchange.
This mechanism protects your data during transmission, making it unreadable to unauthorized parties. To use encryption, you must provide a valid public key for the receiving server, which is securely stored in the device's keychain.
The sections below provide guidance for server developers and integrators.
Posting the schedule in the JSON format
When the JSON payload is sent in the request body without encryption and authentication:
Content of HTTP headers:The user-agent header is system-generated.
The request body will contain the JSON data.When the JSON payload is sent in the request body without encryption but with authentication (for example, Username: User1, Password: password123):
Content of HTTP headers:The app includes the Authorization header with the value Basic VXNlcjE6cGFzc3dvcmQxMjM=. The server decodes this value (Base64 decoding yields User1:password123) and extracts:
- Username: User1
- Password: password123
Server Behavior (Example: PHP-Based Server Application)
When a server-side application is running on PHP, the server processes the Authorization header, decodes it, and populates the php-auth-user and php-auth-pw headers for internal use or debugging purposes.When the JSON payload is sent in the request body with encryption but without authentication:
Content of HTTP headers:The data in the request body will look like this:
When the JSON payload is sent in the file without encryption:
Content of HTTP headers:Form values:
The file will be uploaded as 'daysoff.json'. The name 'daysOffSchedulerData' with the filename 'daysoff.json' are specified in the 'Content-Disposition' of body prefix string.
When the JSON payload is sent in the file with encryption:
Content of HTTP headers:Form values:
The file will be uploaded as 'daysoff.json.bin'. The name 'daysOffSchedulerData' with the filename 'daysoff.json.bin' are specified in the 'Content-Disposition' header within the body prefix string.
Posting the schedule in the HTML format
When the HTML payload is sent in the request body without encryption and authentication:
Content of HTTP headers:If you use the HTML options 'Include HTML and BODY tags' and/or 'Include CSS', the query strings 'includeHTMLAndBodyTags' and 'includeCSS' will be set to 'yes' or 'no' accordingly. The HTML option 'Inline CSS' is not included.
The request body will contain the HTML data.When the HTML payload is sent in the request body with encryption:
Content of HTTP headers:To keep the HTML body clean, the AES and IV keys are included in the HTTP headers as 'x-encrypted-aes-key' and 'x-encrypted-iv', respectively. The encrypted payload is sent directly in the HTML body.
When the HTML payload is sent in the file without encryption:
Content of HTTP headers:Form values:
The file will be uploaded as 'daysoff.html'. The name 'daysOffSchedulerData' with the filename 'daysoff.html' are specified in the 'Content-Disposition' header within the body prefix string.
When the HTML payload is sent in the file with encryption:
Content of HTTP headers:Form values:
The file will be uploaded as 'daysoff.json.bin'. The name 'daysOffSchedulerData' with the filename 'daysoff.json.bin' are specified in the 'Content-Disposition' header within the body prefix string.
A new boundary is generated every time you post a file. Authentication for posting the schedule in the HTML format is handled the same way as for posting in the JSON format.
NOTE: The postButton form value is not included when posting data in the request body. In this case, the request contains only the raw payload without a multipart/form-data boundary structure to organize "parts."
For more information about the format of the prefix and suffix, see:
Encryption Details
AES Encryption:Data is encrypted in chunks. The AES key and IV (Initialization Vector) are encrypted using RSA and Base64-encoded.
Data Format in Request
Form Fields:Server-side Data Extraction and Decryption
- Parse the Multipart/Form-Data request, extract encryptedAESKey and encryptedIV from the form fields and Base64-decode them.
- Decrypt the AES key and IV using the server's RSA private key. Use RSA decryption with OAEP padding and SHA-256.
- Decrypt the file data using the decrypted AES key and IV. The file data in the file form field is the AES-encrypted data. Decrypt it using AES-256-CBC with PKCS#7 padding and the decrypted AES key and IV.
Sample Pseudocode for Server-Side Decryption
Step 1: Base64 decode the received dataThe payload is now decrypted and can be processed.
NOTE: While we continue to improve our security measures, the app does not currently support additional integrity verification mechanisms, such as tamper detection or HMAC or AES-GCM with authentication tag.
Generating RSA Keys Using OpenSSL using command-line
The server-side developers need to generate an RSA key pair:- A private key that remains securely stored on the server.
- A public key that is shared with your app to encrypt the data.
- -algorithm RSA: Specifies the RSA algorithm
- -out private_key.pem: Saves the private key in a file named private_key.pem
- -pkeyopt rsa_keygen_bits:2048: Specifies the key size (2048 bits in this example)
- -pubout: Extracts the public key from the private key
- -in private_key.pem: Specifies the input file containing the private key
- -out public_key.pem: Saves the public key in a file named public_key.pem
Testing
We provide a simple Encryption-Decryption Tool that you can use to test the encrypted data and see the expected decrypted results.
Sample unencrypted JSON payload:
{
"schedule": [
{
"rowNumber": 0,
"employee": {
"firstName": "John",
"lastName": "Doe"
},
"daysOff": [
true,
false,
false,
false,
false,
false,
true
]
},
{
"rowNumber": 1,
"employee": {
"firstName": "Jane",
"identifier": "123",
"lastName": "Smith"
},
"daysOff": [
true,
false,
false,
false,
false,
false,
true
]
},
{
"rowNumber": 2,
"employee": {
"firstName": "Sarah",
"identifier": "T-800",
"lastName": "Connor"
},
"daysOff": [
true,
false,
false,
false,
false,
false,
true
]
},
{
"rowNumber": 3,
"employee": {
"firstName": "Sherlock",
"identifier": "221b",
"lastName": "Holmes"
},
"daysOff": [
true,
false,
false,
false,
false,
true,
false
]
},
{
"rowNumber": 4,
"daysOff": [
true,
false,
false,
false,
false,
true,
false
]
},
{
"rowNumber": 5,
"daysOff": [
false,
false,
false,
false,
false,
true,
true
]
},
{
"rowNumber": 6,
"daysOff": [
false,
false,
false,
false,
false,
true,
true
]
}
],
"header": {
"startAndEndDatesOfWeek": "Dec 1, 2024 - Dec 7, 2024",
"week": [
{
"month": "Dec",
"dayOfWeek": "Sun",
"dayOfMonth": 1
},
{
"month": "Dec",
"dayOfWeek": "Mon",
"dayOfMonth": 2
},
{
"month": "Dec",
"dayOfWeek": "Tue",
"dayOfMonth": 3
},
{
"month": "Dec",
"dayOfWeek": "Wed",
"dayOfMonth": 4
},
{
"month": "Dec",
"dayOfWeek": "Thu",
"dayOfMonth": 5
},
{
"month": "Dec",
"dayOfWeek": "Fri",
"dayOfMonth": 6
},
{
"month": "Dec",
"dayOfWeek": "Sat",
"dayOfMonth": 7
}
],
"weekNumber": 2
}
}
Encryption-Decryption Tool
No data yet