PKI

The following examples are in PHP.

First time connection with PKI 🔗︎ click to copy

To use PKI for your connection you must put in a support request for the Mydex team to enable it. If required you can also send the public key of a key pair for the initial payload of first time connection data. This will only be used for the first time connection data transaction.

When connecting to a PDS for the first time a key pair will be generated between your connection and the PDS. The private key will be sent to you in the payload to your api callback path (in pki_private_key). You will need to store this for later use. Note: This will be a different key per PDS. If you have opted for encrypted first time connection data, this will be sent to your api callback encrypted so you will need to follow the steps below in 'Decrypting data sent from the API' to extract the data from it.

Decrypting data sent from the API 🔗︎ click to copy

With PKI enabled for your connection, after making a request to the API you will receive an encrypted response similar to the below.

Example request to: https://sbx-api.mydex.org/api/pds/pds/{{uid}}.json?dataset=field_ds_personal_details&con_id={{con_id}}&key={{key}}&source_type=connection&api_key={{api_key}}
{"key":"cI4+IY5jUQMmFencRKn+lVLOT\/3ZRwWOoSq+1cAB6XE\/Dvij5iOhtNvxTzw7kWF2PnLfYFdet\/0p5fRjPM4p3xSc4VBopzuW5l88lK9dQhFY9ghGZP8Ls8QUBkcUTfBdQ5MpQ2RpHcEEv0sizxkKMh5DZUMPJlWyyrJzMEZx4hUndI02txNEQWGghqNSejqny+YwWl4efLp3DfyzXt9gc2sHKjhONNtsuHUmmRPSyz0g71pPKxtT7gTIItU4Ot0xrhMvFzaIJil3Pm\/of2O8UuCotR0g6rN21wkOGWctpeAwqyZd8h3Pqh3KzQ7XA9cP52qKwHe3jNR2rowavgowJtQbp6fYOXcPpw15kpVzwv+zMcUqctlMHQt1kgD24Hl6IidE8XxqXvOzxe3jQ2qDAdmhTTZLs3D940wN9qUM+NXvwnAs1msnbDxmFueq1ThbcynUc6mEDad+\/H1KWLJBxWGCSa3spPbaSNrUhQgrMS9ptnPoZ9WHOai3ULNN0cdxT\/pa49iiJ+49WZ2tJL4p5XdGFFCvOrZ7tqvIAgOXU9nZFLtnA2+avPLgdMk0ikwkKa060UDZimhieXFO0CBaTgvLOksKPODdTnkpICZQXmFwIGTqj1MdKQug6UrKvuEibQ5QIvvw+Z6RyA8mV544dQcdSdnXxo19Gl7PmrDELxo=","data":"aElSUlljblZCS3luMklOYk1Fend5U1prakV4NDZYYzZaUWRzd2RRTXd3UFRiWi9jeS8wMFNSUXFIeXVHOWpreVFxdE93NnhENTVhOXVxZXVLcjRZWHdUNVpTQnZoc2E1MUxIeFpITW96TDBQeVBScitJTXFPWEZGMjdLWGNVSDhXUVRVdm5qUWphREM3bHpHMTN3eG5Kdmw4aTFzOE81THZieVpabkh0N3Y4eENzNWREdXdTZGp3V252VzB3dmZSaGtJZmlrdGl0aVl6QXVxc2xCbjhlWGpsczBhUldMT0EySUNybVh4REQ3QmVQcW5BQnRDZHUxdTVXUDBSZ1gvcEZoQXBHS09ST2M1c3JzSi96TzNmNHNFLzNUTThHdzlyNFVQWXJZSTJNWFUvSi9LOTdjQmtFV3RrcURSZXFja3FqdzcxSDF3SFNsNzN2Yzg2TXlLeTN1STNodE5ORjN4b2YzR0FoTVFIbG5WQnhXdldab1R0ZFFwUDRQNmxaT2I0bzhVSzZZU0hMejMwdE41NjdkMUVmaDdtNC9tYlFHTlJGV3JxYVJ5YTVJbzRmNFZzSnNkQUVtdFZPc1JxYWgxUjNVRjAyT2FaZ3dIWlJLcmRZQU1Bc1Q5K0prWTU0eElHWXN5M0x2WWMxT1RWL2ptYUhEYWdlWjUreEFHVVhHaUVFbVBqU1NlUkVGMGFDOUl0QXIyZzdLVDZTMzRjOFRyVCtvZDhmaER4YUpNbjhMb09oZDIrOStGWldoR3pXb1BOcTcraXkrWG5Tay8rVkQ0M3ordkc2TldNS0NRSnY3TjMwZ09LUmh6Wkh0ZmxMeTZqT0NucElGTXd0UFBobFpqWWtaUFRWdEZ0SUlHTEZHS2YvVmhiR3I3S2RHc2pHdk1NNDZKdmJXbVc2eUJheWE1RWJBUnhlOEJCUDhuVktxRHRiSWxlTGZjQTNoeTN2Nmt1NXpPMW0vMjk2K2lNMFg3bnNxU2lBNC9uNURPb1lFSkoraHhmU2tEYkgrYjRQRjRKVUJFV0RwQWFtQ3p0RDVCREN4b2JIV0xQK29CS212S2ZhbWhpUTJ2cXFNaG4zRTVxbkFlaGJjRFV4VHFSWFltSlJhYlZUOWdzdzdjcXNORHBWWFFrWld0WDcrajAveWdXbGVBeWpHZTBSdUNmbUhvT0RIYVhEK21OdDNxTmxxTmhLZm1uRi9pdklJdG1KVlJnT2lTVkw5QXNGdzRXcm1KQ2J2c0RPY3psNlkwZDlDRHpMSlB6c2RCQk0rMzBvSGxGK2lrWXJiZmxhZ0dRL2YwNEROQ0ZpdHpzL1VrN1JiT0xzZlR3d0ltamt4UTJvclkxalVuYTFvSktxb3dMN2dqdkkva3pTcm5TNHI1UXE2Wjl0VWpRcnZzc3NtQTF6S0l6a1RYV3g5U2RxLzJLN1pjMVpDR3lDclZzdm1YTTVDVFEra2ZyWkJCVUZUaHhGWEh4bElHNDZQbVJqZzlFUzJQZHRWSXUwdXlDWGVWenM4YnM4RVUxT1NEZjNXSnlHbEVNTjZ2RE8yYTBXUEh1N0tPb05kK01pc2t4bkFWSmZSQXJFZWVLM2ljZithQkxFOEQ3Q3M1MjZ6Z2lRMUpxMDg5UHFoTmJ0dHN6MHl1aU9Xeml6cmFISXFtakw4cVdJWDU4bFhvVlhyM21Td0QzMHc3b3FDTUVoSXE4bHFtZ2VxeWV0akJtT0VEV2g4OFN1RFg2b1ZJQVluSzRJWnJuNGRoQVJNUWFDUFJ3aklEbDV4ZExGaDJPQ3lhemVaWWhMVXZxUEhjejVIUnpvbWZSdjBERGZTdVIzeXFqeTRYUkVZTTd0dlJqc1c5MUI0NzhISGszaVJSb0tVY0Vpam5wUEZSL3FUemc5TmY0ZmRDQzVYY2tKSml2eDNZbmNLb3VDVzc4eEZVbWxCQzhnZnJpMm5CUkFJVzZqb01NTWlRbDlCTTZtT2Q1bTdidnNWU0oyV1BRZUFwS1QzT1N4TEtKQit2QjZ6MlRwS2YzdkZ1di91VHFOQlo5eEZ5VDN2ZTF3TTdVK1FGRDZzK3M3bXJUK2RqQ3M4RytiRVBnbFR0NFhNK2tBdmNyREJ2b0d1Mi81aGRKa3NxenNpN2ZBREZYT0p2SVZWZW9UNk93ZXhRWGdrQW9CcjcrTlZqeEpnODJCbSsrazd3Y2tLbXJVeTRtRVJNSnRkVlJMdjZKVnRJbDEwUmpoMjdrL09WWDQzOGMzZmZsZENNNTFsbzFzblBBdEtaUjJId3piOUVTa3Z1Lzg2TFV4dzIwcjVLenlxTHMyNXRhb1laV0lYQ0hFM0hWemdNWHcyNEVHM2dSUllWeXR0RUZOMGhaK1hHS1IzKzE5UXdqUS9lNWU3VlVyMjBLSFFMWG44RTRMUlVzL0lSa3kzUzY2VDBKSm93U0t1K0QvR3ZEUmRZcis1Yk5rYjg9"}

We json_decode() this and get the two parts: key and data. The key must now be decrypted with your private key. The user-connection-specific private key is sent as part of the response on first-time-connection and you should have this stored somewhere within your system.

The data is made up of the two parts key and data because the data is encrypted with a one-time-use password and so you will need this password to decrypt the data. Sending the password as-is would obviously not be secure and would almost void the use of encryption, so we instead send the encryption of the password (as key).

The response data is also base64-encoded to ensure it is transferred successfully so you will first need to decode that. An example of this process is shown below in PHP.

// We are using the following constants to define the encryption details.
define('CIPHER_METHOD', 'aes-256-cbc');
define('INITIALIZATION_VECTOR', '0000000000000000');

// Extract data.
$data_to_decrypt = json_decode($data_to_decrypt, 1);
$encrypted_password = base64_decode(utf8_decode($data_to_decrypt['key']));
$encrypted_data = base64_decode(utf8_decode($data_to_decrypt['data']));

// Decrypt the password using the private key.
$password = '';
openssl_private_decrypt($encrypted_password, $password, $private_key);

// Decrypt the data using the password.
$decrypted_data = openssl_decrypt($encrypted_data, CIPHER_METHOD, $password, 0, INITIALIZATION_VECTOR);

The data can then be read from the $decrypted_data variable:

{"field_ds_personal_details":{
  "instance_0":{
    "field_personal_email_address":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_faname":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_fname":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_gender":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_home_phone":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_maname":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_marital_status":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_mname":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_mobile_phone":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_nickname":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_number_children":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_suffix":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_title":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}},
    "field_personal_work_phone":{"value":"","access":{"r":{"a":"1","s":"A"},"w":{"a":"1","s":"A"}}}
  }
}}


Sending encrypted data to the API 🔗︎ click to copy

To update a PDS with new data when PKI is enabled for your connection, you will need to send the data encrypted with your key.

Say we want to update a PDS with the following data:

Array
(
    [field_ds_personal_details] => Array
        (
            [0] => Array
                (
                    [field_personal_fname] => SampleName
                )

        )

)

This must first be encrypted. We generate a random password and use this to encrypt the data. We then encrypt the password with our private key to send along with the data. This is the reverse of the process described above.

// We are using the following constants to define the encryption details.
define('CIPHER_METHOD', 'aes-256-cbc');
define('INITIALIZATION_VECTOR', '0000000000000000');

// Generate a one-time use password to encrypt data.
$password = openssl_random_pseudo_bytes(32);

// Encrypt the data with the new password.
$encrypted_data = openssl_encrypt($data_to_encrypt, CIPHER_METHOD, $password, 0, INITIALIZATION_VECTOR);

// Encrypt the password with private key to send over.
$encrypted_password = '';
openssl_private_encrypt($password, $encrypted_password, $private_key);

// Add both sets of encrypted data to our array.
$post_data = array(
  'key' => base64_encode($encrypted_password),
  'data' => base64_encode($encrypted_data),
);

To update the PDS we then make the API request as usual, sending our encrypted $post_data from above.

// Substitute in the PDS details here.
$api_request_url = 'https://sbx-api.mydex.org/api/pds/pds/{{uid}}.json?con_id={{con_id}}&key={{key}}&api_key={{api_key}}&source_type=connection';

// Our encrypted JSON data.
$data = json_encode($post_data);
// $data is of the form:
{"key":"ZANGjViC4HO5EPSACFKB\/NjttScVTkEUDb4q9V0DY4wk2dJcepqfo9anFsqO2R96y3hhuPVgN\/45oikih0uSJvwOVM2OqxMAe+ae+Ywlc5dW45KLx8ZyOdO181VW162v9nZC6XSfbrKFDp8fvwKr0rDcLCTvS80rE5R3Pqo9qnp0jC1cK+PR1gthDUzbEFk0wdZQlJsrhkHQhJyGNCXgvr9jUsUhbXg\/Y1ifFX6YAd8Og+xVZXbzqoT\/zwy21s4J0qkIWDDYG0YzcgWxZ9hu6lUULbxTEz9c7yTgjXYc5HcRKa69eU9U5hxs19dI21Wj2ezwyCsv8fN69c0UIVMXIfB48iAandHd\/iUT+fEXgj4iJ8DAMKgCMkigIieWnJp3ShKNY4lv2thJJmU\/EEmkbrgqKQlia00d0uEdkvC8rRL+41k1IJm2srZ2BXt5Dw5Kwd0MwDeeh\/FxXoABDN9ZX8Peps74Ayt683B2L4bYyByDj\/GgBvIhOOby\/Pcn6w653opoggYF5nktwn+ZBK6JNPXA0e8cpdD2vrOWBJ87sKCal4hrpmp1DnMECrC6ZtFh6V9EXwzPFZ7mOnwDK1bwHwEd+R1f5MBg0JiVyAgimvTIROz+U0OYaOYwnhTZ9rD1RcHKemxbYa7MhMuwcsb1wiipZn4bSBqupuKDNOrlqio=","data":"V0Jza05NdllwRDN5bk92UVVTZGxrTExDYzRDSE5qMHBoRC9wKzBwZHRxazZrbWpNQ21rVHFLWFdGRTVMNGtxRmhnTjdFSkg5eTNMbldvb1paTXNDNE9UaWpTVG1pMnY0ZGdpeStuR01Bb0U9"}
// Send a PUT request to the API.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_request_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($data)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$api_request_response = curl_exec($ch);
$api_response_array = json_decode($api_request_response, true);

The API returns a response as usual, but of course it is now encrypted.

{"key":"IrQvwWjOnIlvTArStmttwqNqkBn5KDYpfkVepi5G2u7bH4+ZTcSQ90WImj8gjkznsq3FqpljiwoEl4qQ2KWUIcJjURQVlByyKTLgMMI2OK1nPHGZgltMBkfHl3cn7nCJzH4wsdqpdrWnG1xBQIgE1+yCpj238EkPyz56GocL0va0ILTej3H2w6VvjvGTvs\/OAWdqB3A5VdBfen2fnH+HpenqTz0EfwWFcnnZ8oJiUviBoOSI9WfBkQabjRn67M1CXNEs\/rVek1MvN2EITPzGtJoNZwYutk8a5wNQlzsJ4wmo85MSCdJmu1PSzXrbn77meybYLmHVMk31mM+i7XPTVBdtc0x3T86SZabZb7r6aYvl17G7vEkTPMXh3vHSE6AK8CRPS8XjRSLX5u5pcIt2bq99V0mkiuaeg+xLy6O0TnG6TIya2RIGwiNlnfSFB0zhN+g1fY1v+ZiVYPm91IbyW57\/XlH+tEpGiii3WsUwKrPid8S6HYC7vSxJKnHyaaPKtLgX4pPdyCCHQhVFvBAE41NsfynHoKmhRCcPx11clhtvV8MyxX302h4s3fau\/uPjHYTddrJRigUE\/L7FGAvKBE8jnu7mK9LJ92qv1T3guI9lBAyKTSalmm3H10xul3iw90PKirc+MkdrbsLAhi9a4gGmWrhL8GWWMi76Y1+98Mw=","data":"QStEcUNsWVl3NnYwbVMvQmhoL3E0TlNIUk5uVWlpb3VqTXZMWnFFYlFudkJINlBwaVlXWnZzU0FWYXlSU2VKcXpzbDZYdVJkeUdLS1BMTHZnZW5xc0l0RVNwOWNpcnZ5NnlFOW1uQ2xROUw2b2VqUGtpQzEvejg0STlHY2NrU0U="}

We decrypt this as in the previous example and see the response.

{"success":"1","data":{"field_ds_personal_details":[{"field_personal_fname":"SampleName"}]}}