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) 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 aFile
object referencing the file to be decrypted
options
object:privateKeyPemMap
is a dictionary object that maps public key hashes (stored asstring
) to private keys in PEM format (also stored asstring
)- 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 astring
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 astring
representing the URL of the key server utilized by your enterprisegroupNames
is astring
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 filePartial 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>