Software Development Kit (SDK)

ℹ️
This page describes how to use the Confidencial SDK, which lets developers perform Confidencial actions such as decryption within their applications. Please contact us if you would like to get access to it.
ℹ️
The SDK is currently available in JavaScript and consists of one function, which supports the decryption of files. Support for encryption and other languages is coming soon. Have a language you’d like to see supported? Contact us.
ℹ️
While the SDK does not currently support encryption, the Confidencial
Command-Line Interface (CLI)
Command-Line Interface (CLI)
can be used to encrypt files and can be invoked from JavaScript code running in a Node environment (using the child_process module)

Set up

Referencing the library

To use the Confidencial SDK in your JavaScript code, include a reference to the main SDK file, c11-sdk-js.min.js. For example, if the SDK is being used within a web page, include the following line within the <head> element of the HTML
<script src="sdk-location/c11-sdk-js.min.js"></script>
where sdk-location is the path to the main SDK file.

Namespace

All SDK functions are contained within the C11 namespace (e.g. C11.removeEncryption)

Private (decryption) keys

To use decryption functions within the SDK, valid private (decryption) keys are required for all files to be decrypted. Private keys for individual users can be obtained by following the instructions in
🔑
Obtaining public-private key pairs for use with the Confidencial SDK
. Private keys for groups are stored within a Confidencial Key Server and are never exposed. Instead of decrypting client-side, decryption for groups is done within the key server. The removeEncryption function described below is used for both individual-user and group decryption.

Functions

removeEncryption(file, { privateKeyPemMap, keyServerAccessToken, keyServerUrlOrigin, groupNames })

Removes encryption from (decrypts) a file

Input arguments

  • file is a File object referencing the file to be decrypted
  • options object:
    • privateKeyPemMap is a dictionary object that maps public key hashes (stored as string) to private keys in PEM format (also stored as string)
      • The keys in this dictionary object are strings that represent the hashes of public keys
      • The values in this dictionary object are strings that represent the corresponding private keys in PEM format
      • Both public key hashes and private key PEMs can be obtained using the Confidencial
        🖥️
        Desktop App
        or
        🌐
        Web App
        ; see
        🔑
        Obtaining public-private key pairs for use with the Confidencial SDK
      • See the partial code example below for how a private key map can be assembled once public key hashes and private key PEMs are obtained
    • keyServerAccessToken is a string value representing a JSON Web Token (JWT) that can be used to access the key server utilized by your enterprise (this may be hosted by your enterprise or by Confidencial)
      • The key server utilized by your enterprise will be configured to validate JWTs based on a JSON Web Key Set (JWKS) file, which contain the public key(s) corresponding to the private key(s) used to sign valid JWTs
    • keyServerUrlOrigin is a string representing the URL of the key server utilized by your enterprise
    • groupNamesis a string array (string[]) representing the list of groups from which decryptions should be attempted. For each group listed, the key server will check that the user specified in the provided JWT is a member of the group, and if so, attempt to use private keys belonging to the group to decrypt content in the provided document.

Return value

Upon success removeEncryption returns a File object representing the decrypted file

Partial example of decryption via locally-stored, individual key

The example below assumes privateKeyfileElement and encryptedPdfFileElement are HTML file inputs and publicKeyHashElement is an HTML text input.
const privateKeyFile = privateKeyfileElement.files[0]; const encryptedPdfFile = encryptedPdfFileElement.files[0]; const publicKeyHash = publicKeyHashElement.value; const privateKeyMap = {}; privateKeyMap[publicKeyHash] = await privateKeyFile.text(); const decryptedFile = await C11.removeEncryption(encryptedPdfFile, { privateKeyPemMap: privateKeyMap });

Full example of decryption via 1) locally-stored, individual key; and 2) remotely-stored, group key

The example below contains a complete HTML page that allows a user to decrypt a file. The HTML page contains file inputs for the user to upload a file to be decrypted and a file representing the private (decryption) key in PEM format. The page also contains inputs for the user to supply other parameters required for individual-user and group decryption.
⚠️
To avoid CORS errors, the HTML page below should be accessed through a web server (running either locally or in the cloud). Viewing this page directly in a web browser will not work if your browser is enforcing CORS restrictions (as most browsers do by default).
ℹ️
NOTE: The script below assumes the main SDK file, c11-sdk-js.min.js, is being served by a local web server running on port 8080. Adjust the <script src="..."> line in the code below accordingly if you are hosting the SDK file in a different location.
⚠️
To avoid invalid character errors, make sure the web server serving the SDK file is sending the appropriate content type header (Content-Type: application/javascript; charset=UTF-8)
<!DOCTYPE html> <html> <head> <title>C11-SDK-Encryption-Removal</title> <script src="http://127.0.0.1:8080/c11-sdk-js.min.js"></script> <script> async function removeEncryption() { console.log("removeEncryption started"); const option1 = document.getElementById('privateKeyEncryption'); const option2 = document.getElementById('groupEncryption'); const option3 = document.getElementById('bothEncryption'); const isPrivateKeyEncryption = option1.checked || option3.checked; const isGroupEncryption = option2.checked || option3.checked; const publicKeyHashElement = document.getElementById("PublicKeyHash"); if (publicKeyHashElement?.value?.length === 0 && isPrivateKeyEncryption) { alert("Please enter your Public Key Hash"); return; } const privateKeyfileElement = document.getElementById("privateKey"); if (privateKeyfileElement?.files?.length === 0 && isPrivateKeyEncryption) { alert("Please upload your private Key"); return; } const encryptedPdfFileElement = document.getElementById("encryptedPdfFile"); if (encryptedPdfFileElement.files.length === 0) { alert("Please upload encrypted Pdf File"); return; } const opkssAccessTokenElement = document.getElementById("opkssAccessToken"); if (opkssAccessTokenElement?.value?.length === 0 && isGroupEncryption) { alert("Please enter your OPKSS/keyServer Access Token"); return; } const keyServerUrlOriginElement = document.getElementById("keyServerUrlOrigin"); if (keyServerUrlOriginElement?.value?.length === 0 && isGroupEncryption) { alert("Please enter your OPKSS/keyServer Origin URL"); return; } const encryptedPdfFile = encryptedPdfFileElement.files[0]; let privateKeyMap = {}; if (isPrivateKeyEncryption) { const privateKeyFile = privateKeyfileElement.files[0]; const publicKeyHash = publicKeyHashElement.value; privateKeyMap[publicKeyHash] = await privateKeyFile.text(); } let opkssAccessTokenValue; let keyServerUrlOriginValue; let remoteGroupNamesValue = []; if (isGroupEncryption) { opkssAccessTokenValue = opkssAccessTokenElement.value; keyServerUrlOriginValue = keyServerUrlOriginElement.value; if (document.getElementById("remoteGroupNames")?.value?.length > 0) remoteGroupNamesValue = document.getElementById("remoteGroupNames")?.value?.split(","); } const decryptedFile = await C11.removeEncryption(encryptedPdfFile, { privateKeyPemMap: privateKeyMap, keyServerAccessToken: opkssAccessTokenValue, keyServerUrlOrigin: keyServerUrlOriginValue, groupNames: remoteGroupNamesValue }); if (window.navigator.msSaveOrOpenBlob) // IE10+ window.navigator.msSaveOrOpenBlob(decryptedFile, filename); else { // Others var a = document.createElement("a"), url = URL.createObjectURL(decryptedFile); a.href = url; a.download = encryptedPdfFile.name; document.body.appendChild(a); a.click(); setTimeout(function () { document.body.removeChild(a); window.URL.revokeObjectURL(url); }, 0); } } document.addEventListener('DOMContentLoaded', function () { const option1 = document.getElementById('privateKeyEncryption'); const option2 = document.getElementById('groupEncryption'); const option3 = document.getElementById('bothEncryption'); const input1 = document.getElementById('privateKeyDiv'); const input2 = document.getElementById('groupDiv'); // Function to toggle visibility of inputs based on radio button selection function toggleInputs() { if (option1.checked) { input1.classList.remove('hidden'); input2.classList.add('hidden'); } else if (option2.checked) { input1.classList.add('hidden'); input2.classList.remove('hidden'); } else if (option3.checked) { input1.classList.remove('hidden'); input2.classList.remove('hidden'); } } // Initial toggle on page load toggleInputs(); // Event listener for radio button change option1.addEventListener('change', toggleInputs); option2.addEventListener('change', toggleInputs); option3.addEventListener('change', toggleInputs); }); </script> <style> form { margin: 20px auto; max-width: 600px; padding: 20px; border: 1px solid #ccc; border-radius: 5px; } label { display: block; margin-bottom: 10px; font-weight: bold; } input[type="text"], input[type="file"] { display: block; margin-bottom: 20px; width: 100%; padding: 10px; border-radius: 5px; border: 1px solid #ccc; box-sizing: border-box; } input[type="button"] { background-color: #08329d; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; } input[type="button"]:hover { background-color: #3e558e; } .hidden { display: none; } </style> </head> <body> <form> <input style="display: inline;" type="radio" id="privateKeyEncryption" name="encryptionMethod" checked="checked" value="privateKeyEncryption"> <label style="display: inline;" for="privateKeyEncryption"> Decrypt using Private Key</label> <input style="display: inline;" type="radio" id="groupEncryption" name="encryptionMethod" value="groupEncryption"> <label style="display: inline;" for="groupEncryption"> Decrypt using groups</label> <input style="display: inline;" type="radio" id="bothEncryption" name="encryptionMethod" value="bothEncryption"> <label style="display: inline;" for="bothEncryption"> Decrypt using both</label></br></br></br> <div id="privateKeyDiv" class="hidden"> <label for="PublicKeyHash">Your Public Key Hash:</label> <input type="text" id="PublicKeyHash" name="PublicKeyHash" placeholder="Enter Your Public Key Hash" /> <label for="privateKey">Your Private Key:</label> <input type="file" accept=".key" id="privateKey" name="privateKey" /> </div> <label for="encryptedPdfFile">Encrypted Pdf File:</label> <input type="file" accept=".pdf" id="encryptedPdfFile" name="encryptedPdfFile" /> <div id="groupDiv" class="hidden"> <label for="opkssAccessToken">Your OPKSS/keyServer Access Token:</label> <input type="text" id="opkssAccessToken" name="opkssAccessToken" placeholder="Enter Your OPKSS/keyServer Access Token" /> <label for="keyServerUrlOrigin">Your OPKSS/keyServer Origin URL:</label> <input type="text" id="keyServerUrlOrigin" name="keyServerUrlOrigin" placeholder="Enter Your OPKSS/keyServer Origin URL" /> <label for="remoteGroupNames">Your Groups names:</label> <input type="text" id="remoteGroupNames" name="remoteGroupNames" placeholder="Enter group names to decrypt for. [optional] e.g. group1, group2" /> </div> <input type="button" value="Decrypt" onclick="removeEncryption()" /> </form> </body> </html>