<commit_before>---
authors: <NAME> <<EMAIL>>
state: draft
---

<!--
    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->

<!--
    Copyright 2016 Joyent Inc.
-->

# RFD 71 Manta Client-side Encryption

## Introduction

This document will describe the proposed design and implementation of a client-side encryption mechanism for Manta, similar to the functionality provided by Amazon S3's Java, .NET, and Ruby SDKs.

In section 1, we discuss the proposed design for this feature in detail: first outlining the changes needed to implement client-side encryption in a general sense, then reviewing design constraints and requirements for implementing such a feature in Manta, and finally, reasoning through each piece of the design. If you are interested in the motivation behind client-side encryption in Manta, you should read this section.

In section 2, we provide a detailed summary of the design of the JDK implementation.

In section 3, we provide a detailed summary of the design of the node.js implementation.

## Terms

| Term           | Definition                                                  |
| -------------- | ----------------------------------------------------------- |
| Plaintext      | [Unencrypted data](https://en.wikipedia.org/wiki/Plaintext) |
| Ciphertext     | [Encrypted data](https://en.wikipedia.org/wiki/Ciphertext) |
| Authentication | [Cryptographic authentication](https://en.wikipedia.org/wiki/Message_authentication) - such as [MAC](https://en.wikipedia.org/wiki/Message_authentication_code) or [AE](https://en.wikipedia.org/wiki/Authenticated_encryption) |
| Metadata       | Refers to metadata about objects stored in Manta |

## 1. Design Discussion

### Client-side Encryption Description

Encryption used in object stores with an HTTP API such as Swift, S3, and Manta typically fall under one of two types of implementations: client-side and server-side. Client-side encryption performs all of the encryption and decryption operations entirely in the client SDK with no encryption-specific operations being executed on the object store server. This implies that key management is entirely handled by the client. Server-side encryption typically handles key management, encryption and decryption entirely using the object store's server logic on behalf of the client. This RFD will be focused solely on client-side encryption.

Conceptually, client-side encryption's primary use case is when you do not trust the provider of your object-store. Security is ensured because the client has full control over encryption algorithms, keys and authentication. Additionally, when server-side encryption is not available on an object store, client-side encryption can be used to provide similar functionality to server-side encryption provided that the user is willing to relax requirements such as authentication. This can make sense when the provider of the object-store is not viewed as a potential adversary and is a trusted party.
  
From a design perspective the implementation of client-side encryption in Manta loosely resembles the Java S3 SDK implementation. Like the S3 implementation, we use the JVM's support for encryption facilities to do encryption, we support fully client-managed private keys, we support loosening strict checking of ciphertext authentication so we can do more operations (such as HTTP range requests), we support multi-part uploads and encrypting streams.

### Desired Client-side Encryption Functionality

In order for an object store client SDK to provide encryption and decryption as a seamless part of its API, there needs to be support for the following operations and constraints:

 * Client-side encryption can be selectively enabled or disabled.
 * Streamable operations can be encrypted or decrypted without changing the API from non-encrypted operations.
 * Retryable operations are not affected by enabling encryption.
 * Encryption algorithms supporting O(1) additional memory per operation are supported. 
 * HTTP range requests of ciphertext can be decrypted.
 * Objects uploaded through the multipart upload interface can be encrypted and decrypted.
 * The schemes for client-side encryption should be compatible between all supported client SDKs. Objects encrypted using one SDK can be seamlessly decrypted with other SDKs that support client-side encryption.
 * The encryption key file formats are compatible between all supported SDKs.
 * The encryption key default file paths and environment variables are compatible between all supported SDKs.
 * Users of the SDK can select cipher and strength of encryption algorithm used.
 * Functionality to allow for encrypted metadata is provided.
 * Standardized headers are set that inform Manta that a given object is encrypted.

### Unsupported Operations

Due to the inherent limitations of client-side encryption, some operations will not be supported. The list of operations not supported is as follows:

 * Manta jobs cannot be supported with client-side encrypted objects. Clients can of course upload the keys to Manta themselves and import them into jobs as assets if they need to, but there will be no first class support for such operations.
 * Decryption via signed links will not natively be supported by Manta server-side operations. A client could still download a signed link and decrypt it themself.
 * Decryption of objects contained in the public directory will not be natively supported by Manta server-side operations. 
 * If using a [Authenticated Encryption with Associated Data (AEAD) cipher](https://en.wikipedia.org/wiki/Authenticated_encryption), authentication will not be possible when doing HTTP range requests.

### HTTP Headers Used with Client-side Encryption

The following headers will be added to manta as natively supported headers like `Durability-Level` and not treated from an API perspective as "metadata" (`m-*` parameter). The rational behind this is that it is enforcing the contract for consistent behavior between client-side encryption implementations across SDKs.

#### `m-encrypt-support`
In order to give the maintainers of Manta and client SDKs more options when implementing future functionality, we should create a new HTTP metadata header that is supported in Manta outside of user-supplied metadata. This header would be used to mark a given objects as being encrypted using client-side encryption. One example of how this header could be useful is if we wanted to implement gzip compression in the future, ciphertext does not compress well and we would be able to selectively disable compression for encrypted files. Another example is that it could be used as a basis for a identifying files that would be candidates for a future migration to server-side encryption.

```
m-encrypt-support: client
```

#### `m-encrypt-key-id`
To provide an audit trail to the consumers of client-side encryption, we set a header indicating the ID of the key used to encrypt the object. This would assist users in debugging cases where files have been encrypted using multiple keys and could allow the client to support multiple encryption keys in the future.

```
m-encrypt-key-id: XXXXXXXXX
```

#### `m-encrypt-iv`
In order to make sure that the same ciphertext is not generated each time the same file is encrypted, we use an [initialization vector (IV)](https://en.wikipedia.org/wiki/Initialization_vector). This IV is stored in Manta as header metadata in base64 encoding.   
```
m-encrypt-iv: TWFrZSBEVHJhY2UgZ3JlYXQgYWdhaW4K
```

#### m-encrypt-mac
A cryptographic checksum of the ciphertext is stored in this header so that ciphertext can be authenticated. This prevents classes of attacks that involve tricky changes to the ciphertext binary file. When using AEAD ciphers, it will contain the authentication data (AD) instead of [hash-based message authentication (HMAC)](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code) data. The value of the header will be stored in base64 encoding.
```
m-encrypt-mac: XXXXXXXXX

```

#### `m-encrypt-cipher`
In order to allow differing clients to easily select the correct encryption algorithm, we set a header indicating the type of cipher used to encrypt the object. This header is in the form of `cipher/width/mode`.

```
m-encrypt-cipher: aes/256/cbc
```

#### `m-encrypt-original-content-length`
For a plethora of use cases it is valuable for the client to be able to be aware of the unencrypted file's size. We store that in bytes.
```
m-encrypt-original-content-length: 1048576

```

#### `m-encrypt-metadata`
Like the free form `m-*` metadata headers, we support free form encrypted metadata. The value of this header is ciphertext encoded in base64. Metadata stored in plaintext is written as JSON. The value of this header will be limited to a maximum of 4k bytes as base64 ciphertext. 
```
m-encrypt-metadata: XXXXXXXXX

```

#### `m-encrypt-metadata-iv`
Like `m-encrypt-iv` we store the IV for the ciphertext for the HTTP header `m-encrypt-metadata`. 
```
m-encrypt-metadata-iv: TWFrZSBEVHJhY2UgZ3JlYXQgYWdhaW4K

```

#### `m-encrypt-metadata-mac`
Like `m-encrypt-mac` we store the MAC in base64 for the ciphertext for the HTTP header `m-encrypt-metadata` so that we can verify the authenticity of the header ciphertext.
```
m-encrypt-metadata-mac: XXXXXXXXX

```

#### `m-encrypt-metadata-cipher`
Like `m-encrypt-cipher` we store the cipher for the ciphertext for the HTTP header `m-encrypt-metadata` so that our client can easily choose the right algorithm for decryption.
```
m-encrypt-metadata-cipher: aes/256/cbc
```

```
The following headers are stored by S3, but aren't addressed above:

TODO: Find out if we need to store cipher and/or key padding settings.
TODO: Find out if we need to store AEAD tag length.
```

### Cryptographic Authentication Modes

Depending on the threat model determined by the consumer of the client SDK, different modes of authentication of the ciphertext would be desirable. If the consumer trusts the object store provider, then enabling a mode that skips authentication when it prevents an operation from operating efficiently makes sense. One example of an operation that would not work in an authenticated mode would be random reads (e.g. HTTP range requests). With a security in mind, the client SDK will operate by default in a fully authenticated mode unless explicitly disabled. Thus, consumers of SDKs supporting client-side encryption would be able to choose between one of two modes:

 * `MandatoryObjectAuthentication` (default)
 * `OptionalObjectAuthentication`
 
We only provide two modes unlike S3 which provides three modes (`EncryptionOnly`, `AuthenticatedEncryption`, and `StrictAuthenticatedEncryption`). `EncryptionOnly` mode in S3 does not authenticate ciphertext at all, `AuthenticatedEncryption` authenticates ciphertext when it is possible with the operation being performed and `StrictAuthenticatedEncryption` always authenticates and will cause an exception to be thrown if the operation can't be performed with authentication.   

### Key Management

Initially, there will be no support server-side for key management. All key management will need to be done by the implementer of the SDK. The default key format and location will be standardized across all implementations of Manta client-side encryption in their respective SDKs.

S3 provides a Key Management Service (KMS) and the design of any equivalent service is beyond the scope of this RFD. 

```
TODO: Define the default location for encryption keys.
TODO: Define the default portable format for encryption keys.

```

### Metadata Support

Encrypted metadata will be supported by serializing to a JSON data structure that will be encrypted and converted to base64 encoding. This will be stored as metadata on the object via the HTTP header `m-encrypt-headers`. 

### Future considerations

Ideally, our client-side encryption implementation will be designed such that when we build server-side encryption support customers can seamlessly migrate between schemes. This can be possible if we have consistent headers/metadata for identifying ciphers, MAC, IV and key ids. 

## 2. Java Manta SDK Client-side Encryption Design and Implementation

Client-side encryption within the Java Manta SDK will be implemented as an optional operation that wraps streams going to and from Manta. Client-side encryption will be enabled using configuration and from an API consumer's perspective there will not be a change in the API. When operations are not supported by the encryption settings, then appropriate exceptions will be thrown indicating the conflict between the setting and the operation. An example of this would be an attempt to use a HTTP range operation when `MandatoryObjectAuthentication` is enabled. Furthermore, care will need to be taken to allow for operations that are retryable to continue to be retryable - such as sending [File](https://docs.oracle.com/javase/8/docs/api/java/io/File.html) objects.   

### Cipher Selection and Library Support

The JVM implementation of client-side encryption relies on the encryption algorithms and ciphers as provided as part of the running JVM's implementation of the Java Cryptography Extension (JCE)](https://en.wikipedia.org/wiki/Java_Cryptography_Extension). Thus, users of client-side encryption are assumed to trust the security of the JCE implementation in the JVM that they choose to run.

In the Oracle JDK there is limited default support for strong encryption algorithms. In order to enable stronger encryption, you must download and install the [Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html). This isn't an issue with the OpenJDK. Also, strong encryption algorithms are supported using the [JCE API](https://en.wikipedia.org/wiki/Java_Cryptography_Extension) by [The Legion of the Bouncy Castle](http://www.bouncycastle.org/java.html) project.

We will also support algorithms supplied by Bouncy Castle and the Java runtime via the [JCE API](http://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html). The Java Manta SDK currently bundles Bouncy Castle dependencies because they are used when doing [authentication via HTTP signed requests](https://github.com/joyent/java-http-signature).

We've identified the following ciphers as the best candidates for streamable encryption:

```
TODO: <NAME> - please add reccomendations from JCE and BouncyCastle. Please note if they are compatible with OpenSSL.

```

### Configuration

All settings related to client-side encryption will be defined as part of the Java Manta SDK's [ConfigContext](https://github.com/joyent/java-manta/blob/master/java-manta-client/src/main/java/com/joyent/manta/config/ConfigContext.java) interface. This allows for the Java Manta SDK to be easily integrated into other libraries' configuration systems.
  
```
TODO: Explicitly define the configuration parameters needed for client-side encryption.
TODO: Do we want to support multiple keys?

We will need:
ClientSideEncryptionEnabled: true | false (default)
PermitUnencryptedDownloads: true | false (true)
EncryptionAuthenticationMode: Optional | Mandatory (default)<commit_msg>RFD 71: Added limitations section.<commit_after>---
authors: <NAME> <<EMAIL>>
state: draft
---

<!--
    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->

<!--
    Copyright 2016 Joyent Inc.
-->

# RFD 71 Manta Client-side Encryption

## Introduction

This document will describe the proposed design and implementation of a client-side encryption mechanism for Manta, similar to the functionality provided by Amazon S3's Java, .NET, and Ruby SDKs.

In section 1, we discuss the proposed design for this feature in detail: first outlining the changes needed to implement client-side encryption in a general sense, then reviewing design constraints and requirements for implementing such a feature in Manta, and finally, reasoning through each piece of the design. If you are interested in the motivation behind client-side encryption in Manta, you should read this section.

In section 2, we provide a detailed summary of the design of the JDK implementation.

In section 3, we provide a detailed summary of the design of the node.js implementation.

## Terms

| Term           | Definition                                                  |
| -------------- | ----------------------------------------------------------- |
| Plaintext      | [Unencrypted data](https://en.wikipedia.org/wiki/Plaintext) |
| Ciphertext     | [Encrypted data](https://en.wikipedia.org/wiki/Ciphertext) |
| Authentication | [Cryptographic authentication](https://en.wikipedia.org/wiki/Message_authentication) - such as [MAC](https://en.wikipedia.org/wiki/Message_authentication_code) or [AE](https://en.wikipedia.org/wiki/Authenticated_encryption) |
| Metadata       | Refers to metadata about objects stored in Manta |

## 1. Design Discussion

### Client-side Encryption Description

Encryption used in object stores with an HTTP API such as Swift, S3, and Manta typically fall under one of two types of implementations: client-side and server-side. Client-side encryption performs all of the encryption and decryption operations entirely in the client SDK with no encryption-specific operations being executed on the object store server. This implies that key management is entirely handled by the client. Server-side encryption typically handles key management, encryption and decryption entirely using the object store's server logic on behalf of the client. This RFD will be focused solely on client-side encryption.

Conceptually, client-side encryption's primary use case is when you do not trust the provider of your object-store. Security is ensured because the client has full control over encryption algorithms, keys and authentication. Additionally, when server-side encryption is not available on an object store, client-side encryption can be used to provide similar functionality to server-side encryption provided that the user is willing to relax requirements such as authentication. This can make sense when the provider of the object-store is not viewed as a potential adversary and is a trusted party.
  
From a design perspective the implementation of client-side encryption in Manta loosely resembles the Java S3 SDK implementation. Like the S3 implementation, we use the JVM's support for encryption facilities to do encryption, we support fully client-managed private keys, we support loosening strict checking of ciphertext authentication so we can do more operations (such as HTTP range requests), we support multi-part uploads and encrypting streams.

### Desired Client-side Encryption Functionality

In order for an object store client SDK to provide encryption and decryption as a seamless part of its API, there needs to be support for the following operations and constraints:

 * Client-side encryption can be selectively enabled or disabled.
 * Streamable operations can be encrypted or decrypted without changing the API from non-encrypted operations.
 * Retryable operations are not affected by enabling encryption.
 * Encryption algorithms supporting O(1) additional memory per operation are supported. 
 * HTTP range requests of ciphertext can be decrypted.
 * Objects uploaded through the multipart upload interface can be encrypted and decrypted.
 * The schemes for client-side encryption should be compatible between all supported client SDKs. Objects encrypted using one SDK can be seamlessly decrypted with other SDKs that support client-side encryption.
 * The encryption key file formats are compatible between all supported SDKs.
 * The encryption key default file paths and environment variables are compatible between all supported SDKs.
 * Users of the SDK can select cipher and strength of encryption algorithm used.
 * Functionality to allow for encrypted metadata is provided.
 * Standardized headers are set that inform Manta that a given object is encrypted.

### Unsupported Operations

Due to the inherent limitations of client-side encryption, some operations will not be supported. The list of operations not supported is as follows:

 * Manta jobs cannot be supported with client-side encrypted objects. Clients can of course upload the keys to Manta themselves and import them into jobs as assets if they need to, but there will be no first class support for such operations.
 * Decryption via signed links will not natively be supported by Manta server-side operations. A client could still download a signed link and decrypt it themself.
 * Decryption of objects contained in the public directory will not be natively supported by Manta server-side operations. 
 * If using a [Authenticated Encryption with Associated Data (AEAD) cipher](https://en.wikipedia.org/wiki/Authenticated_encryption), authentication will not be possible when doing HTTP range requests.

### HTTP Headers Used with Client-side Encryption

The following headers will be added to manta as natively supported headers like `Durability-Level` and not treated from an API perspective as "metadata" (`m-*` parameter). The rational behind this is that it is enforcing the contract for consistent behavior between client-side encryption implementations across SDKs.

#### `m-encrypt-support`
In order to give the maintainers of Manta and client SDKs more options when implementing future functionality, we should create a new HTTP metadata header that is supported in Manta outside of user-supplied metadata. This header would be used to mark a given objects as being encrypted using client-side encryption. One example of how this header could be useful is if we wanted to implement gzip compression in the future, ciphertext does not compress well and we would be able to selectively disable compression for encrypted files. Another example is that it could be used as a basis for a identifying files that would be candidates for a future migration to server-side encryption.

```
m-encrypt-support: client
```

#### `m-encrypt-key-id`
To provide an audit trail to the consumers of client-side encryption, we set a header indicating the ID of the key used to encrypt the object. This would assist users in debugging cases where files have been encrypted using multiple keys and could allow the client to support multiple encryption keys in the future.

```
m-encrypt-key-id: XXXXXXXXX
```

#### `m-encrypt-iv`
In order to make sure that the same ciphertext is not generated each time the same file is encrypted, we use an [initialization vector (IV)](https://en.wikipedia.org/wiki/Initialization_vector). This IV is stored in Manta as header metadata in base64 encoding.   
```
m-encrypt-iv: TWFrZSBEVHJhY2UgZ3JlYXQgYWdhaW4K
```

#### m-encrypt-mac
A cryptographic checksum of the ciphertext is stored in this header so that ciphertext can be authenticated. This prevents classes of attacks that involve tricky changes to the ciphertext binary file. When using AEAD ciphers, it will contain the authentication data (AD) instead of [hash-based message authentication (HMAC)](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code) data. The value of the header will be stored in base64 encoding.
```
m-encrypt-mac: XXXXXXXXX

```

#### `m-encrypt-cipher`
In order to allow differing clients to easily select the correct encryption algorithm, we set a header indicating the type of cipher used to encrypt the object. This header is in the form of `cipher/width/mode`.

```
m-encrypt-cipher: aes/256/cbc
```

#### `m-encrypt-original-content-length`
For a plethora of use cases it is valuable for the client to be able to be aware of the unencrypted file's size. We store that in bytes.
```
m-encrypt-original-content-length: 1048576

```

#### `m-encrypt-metadata`
Like the free form `m-*` metadata headers, we support free form encrypted metadata. The value of this header is ciphertext encoded in base64. Metadata stored in plaintext is written as JSON. The value of this header will be limited to a maximum of 4k bytes as base64 ciphertext. 
```
m-encrypt-metadata: XXXXXXXXX

```

#### `m-encrypt-metadata-iv`
Like `m-encrypt-iv` we store the IV for the ciphertext for the HTTP header `m-encrypt-metadata`. 
```
m-encrypt-metadata-iv: TWFrZSBEVHJhY2UgZ3JlYXQgYWdhaW4K

```

#### `m-encrypt-metadata-mac`
Like `m-encrypt-mac` we store the MAC in base64 for the ciphertext for the HTTP header `m-encrypt-metadata` so that we can verify the authenticity of the header ciphertext.
```
m-encrypt-metadata-mac: XXXXXXXXX

```

#### `m-encrypt-metadata-cipher`
Like `m-encrypt-cipher` we store the cipher for the ciphertext for the HTTP header `m-encrypt-metadata` so that our client can easily choose the right algorithm for decryption.
```
m-encrypt-metadata-cipher: aes/256/cbc
```

```
The following headers are stored by S3, but aren't addressed above:

TODO: Find out if we need to store cipher and/or key padding settings.
TODO: Find out if we need to store AEAD tag length.
```

### Cryptographic Authentication Modes

Depending on the threat model determined by the consumer of the client SDK, different modes of authentication of the ciphertext would be desirable. If the consumer trusts the object store provider, then enabling a mode that skips authentication when it prevents an operation from operating efficiently makes sense. One example of an operation that would not work in an authenticated mode would be random reads (e.g. HTTP range requests). With a security in mind, the client SDK will operate by default in a fully authenticated mode unless explicitly disabled. Thus, consumers of SDKs supporting client-side encryption would be able to choose between one of two modes:

 * `MandatoryObjectAuthentication` (default)
 * `OptionalObjectAuthentication`
 
We only provide two modes unlike S3 which provides three modes (`EncryptionOnly`, `AuthenticatedEncryption`, and `StrictAuthenticatedEncryption`). `EncryptionOnly` mode in S3 does not authenticate ciphertext at all, `AuthenticatedEncryption` authenticates ciphertext when it is possible with the operation being performed and `StrictAuthenticatedEncryption` always authenticates and will cause an exception to be thrown if the operation can't be performed with authentication.   

### Key Management

Initially, there will be no support server-side for key management. All key management will need to be done by the implementer of the SDK. The default key format and location will be standardized across all implementations of Manta client-side encryption in their respective SDKs.

S3 provides a Key Management Service (KMS) and the design of any equivalent service is beyond the scope of this RFD. 

```
TODO: Define the default location for encryption keys.
TODO: Define the default portable format for encryption keys.

```

### Metadata Support

Encrypted metadata will be supported by serializing to a JSON data structure that will be encrypted and converted to base64 encoding. This will be stored as metadata on the object via the HTTP header `m-encrypt-headers`. 

### Future considerations

Ideally, our client-side encryption implementation will be designed such that when we build server-side encryption support customers can seamlessly migrate between schemes. This can be possible if we have consistent headers/metadata for identifying ciphers, MAC, IV and key ids. 

### Limitations

***Your data on Manta with client-side encryption is only as strong as the security of your instances that host the encryption keys.***

Encryption is only as secure as your keys. Since client-side encryption does not handle do any form of key management, a large part of security is left up to the implementer of the SDK. For example, if you are running an application that uses the SDK in the same datacenter as Manta and storing your keys in one of your instances, you effectively have the same level of security as not having any encryption if you do not trust the operators of the data center. The only benefit encryption would provide would be an assurance that the data stored was unavailable when the Manta hard disks were disposed. 

In contrast to the scenario above, if your keys were protected by an [HSM](https://en.wikipedia.org/wiki/Hardware_security_module) in a secure datacenter (that you trust) that is separate from Manta (which you don't trust), the benefits of client-side encryption would be realized because your keys could have a different threat profile than Manta itself. 

## 2. Java Manta SDK Client-side Encryption Design and Implementation

Client-side encryption within the Java Manta SDK will be implemented as an optional operation that wraps streams going to and from Manta. Client-side encryption will be enabled using configuration and from an API consumer's perspective there will not be a change in the API. When operations are not supported by the encryption settings, then appropriate exceptions will be thrown indicating the conflict between the setting and the operation. An example of this would be an attempt to use a HTTP range operation when `MandatoryObjectAuthentication` is enabled. Furthermore, care will need to be taken to allow for operations that are retryable to continue to be retryable - such as sending [File](https://docs.oracle.com/javase/8/docs/api/java/io/File.html) objects.   

### Cipher Selection and Library Support

The JVM implementation of client-side encryption relies on the encryption algorithms and ciphers as provided as part of the running JVM's implementation of the Java Cryptography Extension (JCE)](https://en.wikipedia.org/wiki/Java_Cryptography_Extension). Thus, users of client-side encryption are assumed to trust the security of the JCE implementation in the JVM that they choose to run.

In the Oracle JDK there is limited default support for strong encryption algorithms. In order to enable stronger encryption, you must download and install the [Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html). This isn't an issue with the OpenJDK. Also, strong encryption algorithms are supported using the [JCE API](https://en.wikipedia.org/wiki/Java_Cryptography_Extension) by [The Legion of the Bouncy Castle](http://www.bouncycastle.org/java.html) project.

We will also support algorithms supplied by Bouncy Castle and the Java runtime via the [JCE API](http://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html). The Java Manta SDK currently bundles Bouncy Castle dependencies because they are used when doing [authentication via HTTP signed requests](https://github.com/joyent/java-http-signature).

We've identified the following ciphers as the best candidates for streamable encryption:

```
TODO: <NAME> - please add reccomendations from JCE and BouncyCastle. Please note if they are compatible with OpenSSL.

```

### Configuration

All settings related to client-side encryption will be defined as part of the Java Manta SDK's [ConfigContext](https://github.com/joyent/java-manta/blob/master/java-manta-client/src/main/java/com/joyent/manta/config/ConfigContext.java) interface. This allows for the Java Manta SDK to be easily integrated into other libraries' configuration systems.
  
```
TODO: Explicitly define the configuration parameters needed for client-side encryption.
TODO: Do we want to support multiple keys?

We will need:
ClientSideEncryptionEnabled: true | false (default)
PermitUnencryptedDownloads: true | false (true)
EncryptionAuthenticationMode: Optional | Mandatory (default)
{'fraction_non_alphanumeric': 0.060377947836951426, 'fraction_numerical': 0.004185538029048883, 'mean_word_length': 4.5458167330677295, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 27, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 8, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5772482', 'n_tokens_mistral': 7926, 'n_tokens_neox': 7466, 'n_words': 4232}