Covercrypt Application Level Encryption API
Cloudproof Encryption provides libraries and tools to encrypt and securely index large repositories of data with advanced, high-performance security primitives.
See the use cases and benefits and a description of the cryptosystems used.
The libraries are available in multiple languages to facilitate encryption close to the data source and decryption close to the decryption target, including mobile devices and browsers.
This section describes the Application Level Encryption API, the Encrypted Search API is on this page.
Implementations and quick start¶
The application-level encryption scheme is called Covercrypt. It is open-source and written in Rust. For the cryptographic documentation and implementation details, please check its Github repository.
Unless low-level programming in Rust, implementers should use Covercrypt through the various cloudproof_xxx
user libraries:
- cloudproof_java: the Cloudproof Java Library,
- cloudproof_js: the Cloudproof Javascript Library,
- cloudproof_python: the Cloudproof Python Library,
- cloudproof_flutter: the Cloudproof Flutter Library.
- cloudproof_spark: the Cloudproof Spark Library.
All these libraries are open-source and available on Github
The user libraries all contain extensive tests, and it is highly recommended to start by hacking those tests.
Setup¶
It is possible to create keys using the libraries; however, it is more likely that you will want to store them in a KMS. Please go to the KMS documentation to fetch and run a local KMS.
The library is published on npm: simply install the library in your package.json
The library contains web assembly for cryptographic speed
You need Java 8+ and Maven version 3+
The cloudproof_java
library is deployed on Maven central.
Add the library to your POM:
<dependency>
<groupId>com.cosmian</groupId>
<artifactId>cloudproof_java</artifactId>
<version>6.0.0</version>
<type>jar</type>
</dependency>
Encryption and decryption can be accomplished in the KMS, however, you will likely want to perform them locally using the native library, compiled from Rust.
The cloudproof_java
library leverages Java Native Access to call the native library.
Builds of the native libraries are already provided on package.cosmian.com and can be fetched and copied via the Python script ./scripts/get_native_libraries.py to:
src/main/resources/linux-x86-64
(with support of GLIBC 2.17+)src/main/resources/darwin-x86-64
src/main/resources/win32-x86-64
To build the library yourself, please see the Covercrypt project. In your java project, the library build needs to be placed inside in
src/main/resources/linux-x86-64
folder for a Linux Intel machinesrc/main/resources/linux-amd64
folder for a Linux AMD machinesrc/main/resources/darwin
folder for a Mac running MacOSsrc/main/resources/win32-x86
folder for a Windows machine
To run tests only, place the library inside the corresponding folder above replacing main
with test
Check the JNA documentation for alternative locations for the native library.
To use the native library, use statically the class Covercrypt
object.
The instance is thread-safe and can be used for all subsequent calls.
The version 4.0.0
is available on PyPI:
Import classes:
The library is published on pub.dev
as a Dart library: https://pub.dev/packages/cloudproof. To install it:
The published package contains cryptographic native libraries called through FFI functions.
Download the prebuilt libraries and header for released versions at https://github.com/Cosmian/cloudproof_cpp/releases.
Include header file:
- Compile and run on Linux
- Compile and run on MacOS
- Compile and run on Windows
cloudproof.dll
should be in the same directory as main.exe
Creating a policy¶
A policy defines the space of rights that are used for encryption. It is composed by a set of axes that contain attributes.
For example, the following two axes are divided into four attributes and define a policy:
Department
:Finance
,Marketing
,Human Res.
,Sales
Country
:France
,UK
,Spain
,Germany
A combination of axis attributes is associated to a partition. For example
Department::Finance && Country France
points to a valid partition under the above
policy.
An access policy is defined by a set of partitions. It can be written as a boolean expression of axis attributes:
In the following demo, we will create a policy that combines two axes, a
security level
, and a department
. A user will be able to decrypt data only
if it possesses a key with a sufficient security level and the correct
department.
Policy Axes¶
Security Level Axis:
The first policy axis is the Security Level. It is hierarchical and is
composed of 3 levels: Protected
, Confidential
, and Top Secret
. Since this
axis is hierarchical, when a user is granted access to a given level, it is
granted access to all lower levels. The attributes must be provided in
ascending order.
Department Security Axis:
The second policy axis is the Department axis. It is composed of 3 values:
HR
, MKG
, and FIN
. This axis is not hierarchical: granting access to an
attribute of this axis to a user does not give access to any other attribute.
Hybridization¶
Covercrypt offers the possibility to hybridize the classic asymmetric scheme with the winner of the NIST post-quantum algorithm selection process: Kyber. Hybridization can be applied with granularity since it is specified at the attribute level. A partition corresponding to a combination of attributes with at least one hybridized attribute is hybridized. Any data encrypted for a hybridized partition will result in a hybridized ciphertext.
Rotations¶
Rotations allow to refresh the value of a given partition. The maximum number of creations of partition values is set in the policy.
Generating the master keys¶
The master authority possesses the master key pair:
- a master secret key which is used to generate user keys;
- and a public key which is used for encryption. Since it cannot decrypt, the public key can be freely distributed to encrypting systems.
Keys can be generated locally using the WASM code
To generate keys you can use a Cosmian KMS server and, unless you run in dev mode, an API Key to authenticate to the server.
To generate keys from a Cosmian KMS server, instantiate a KmsClient
with its URL
and, unless you run in dev mode, an API Key to authenticate to the server.
And create master keys
The master keys can be exported from the KMS and their bytes recovered to use with the native library
To use the native library, simply instantiate a CoverCrypt
object.
To generate keys from a Cosmian KMS server, instantiate a KmsClient
with its URL
and, unless you run in dev mode, an API Key to authenticate to the server.
The Python methods calling the server are asynchronous
.
Encrypting Data¶
Data is encrypted using the Public Key and an encryption policy that determines the target partitions of the ciphertext.
Anyone who has access to the Public Key can encrypt data, however, only users possessing user keys with the right access policy can decrypt the ciphertext.
A Covercrypt ciphertext is the concatenation of a encrypted header and an encrypted content.
- The encrypted content is a plaintext symmetrically encrypted using an ephemeral secret key (i.e. a random key generated on the fly).
- The header is the encapsulation of the ephemeral key for a given encryption policy, concatenated with some optional metadata. The metadata, if present, is symmetrically encrypted using the same ephemeral key.
Header and encrypted content can be generated separately using the various APIs. Check the inline documentation of the various languages and the test suites for details.
The code below shows the encryption of 3 messages with 3 different encryption policies targeting 3 different partitions.
Encrypting data is done using the encrypt()
function which calls the WASM function.
Encrypting data is done using the coverCryptEncrypt()
function which calls the KMS to encrypt
Encrypting using the native library is fast and provides many options.
a protected marketing message¶
a top-secret marketing message¶
a protected finance message¶
Encrypting using the KMS is possible (and compatible with the native library) but is inefficient compared to using the native library, due to the added I/O and stress on the KMS server.
The only reason to encrypt using the KMS is to enable a “pure” java solution without native code (which is, for instance, a requirement for a plugin in an Oracle database )
a protected marketing message¶
a top-secret marketing message¶
a protected finance message¶
Encrypting data is done using the encrypt()
function that concatenates the
header (encapsulation of the ephemeral symmetric key) and the symmetrically
encrypted data.
These can be done separately; see CoverCrypt.encrypt_header
a protected marketing message¶
a top secret marketing message¶
a low secret finance message¶
Generating User Decryption Keys¶
User Decryption Keys are generated from the Master Private Key using access policies.
Let us create 2 users with different access policies to illustrate their effect.
User Decryption Keys can be generated by calling the local WASM
User keys can be locally generated using the native library
the confidential marketing user¶
This user can decrypt messages from the marketing department only, with a security level of Confidential or below:
the top secret marketing financial user¶
This user can decrypt messages from the marketing department OR the financial department, with a security level of Top Secret or below:
the confidential marketing user¶
This user can decrypt messages from the marketing department only, with a security level of Confidential or below:
the top secret marketing financial user¶
This user can decrypt messages from the marketing department OR the financial department, with a security level of Top Secret or below:
exporting the keys¶
As with the master keys, the user keys can be exported to be used with the native library
the confidential marketing user¶
This user can decrypt messages from the marketing department only, with a security level of Confidential or below:
the top secret marketing financial user¶
This user can decrypt messages from the marketing department OR the financial department, with a security level of Top Secret or below:
the confidential marketing user¶
This user can decrypt messages from the marketing department only, with a security level of Confidential or below:
the top secret marketing financial user¶
This user can decrypt messages from the marketing department OR the financial department, with a security level of Top Secret or below:
the confidential marketing user¶
This user can decrypt messages from the marketing department only, with a security level of Confidential or below:
the top secret marketing financial user¶
This user can decrypt messages from the marketing department OR the financial department, with a security level of Top Secret or below:
the confidential marketing user¶
This user can decrypt messages from the marketing department only, with a security level of Confidential or below:
Decrypting Ciphertexts¶
The confidential marketing user can successfully decrypt a protected marketing message:
.. however, it can neither decrypt a marketing message with higher security:
… nor decrypt a message from another department even with lower security:
As expected, the top-secret marketing financial user can successfully decrypt all messages
Rotating Attributes¶
At any time the Master Authority can rotate an attribute.
When that happens future encryption of data for a given attribute cannot be decrypted with keys that are not “refreshed” for that attribute.
It is best to perform attribute rotations using the KMS: the master keys will be automatically rekeyed and as long as a user key is active in the KMS (the key has not been revoked), it will also be automatically rekeyed.
rotating the Department::MKG attribute¶
Before rotating attributes, let us make a local copy of the
current confidential marketing user
to show what happens to non-refreshed keys after
the attribute rotation.
creating a new confidential marketing message¶
The rekeyed public key is exported from the KMS to encrypt a new marketing confidential
message using the native library.
decrypting the messages with the rekeyed key¶
The automatically rekeyed confidential marketing user key can still decrypt
the “old” protected marketing
message, as well as the new confidential marketing
message.
decrypting the messages with the NON rekeyed key¶
However, the old, non-rekeyed confidential marketing
user key can still decrypt the old protected marketing
message
but not the new confidential marketing
message:
The whole code¶
The whole code in a single blob of the steps above
If you want to see full code of usage of cloudproof_js
, please check the examples directory in Github.
If you want to see full code of usage of cloudproof_java
, please check the examples directory in Github.
The full code is available in the examples directory of the Github repo.
The full code is available in the examples directory of the Github repo.