Skip to content

martinpaljak/cdoc4j

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cdoc4j · Build Status Release Maven Central Javadocs MIT licensed

Small Java library for handling CDOC encryption format, with Elliptic Curve support ("CDOC 1.1 amendment").

For working with CDOC files from the command line, use the cdoc utility.

Supported formats

  • CDOC 1.0: AES-128 CBC, RSA recipients only, XML base64 container (supported by @open-eid software)
  • CDOC 1.1 (default): AES-256 GCM, RSA and ECC recipients, XML base64 container (supported soon by @open-eid software)
  • CDOC 2.0: AES-256 GCM, RSA and ECC recipients, ZIP container (at least 30%, usually 50% smaller files compared to XML, not (yet) supported by @open-eid software)

  • Include dependency
<dependency>
    <groupId>com.github.martinpaljak</groupId>
    <artifactId>cdoc4j</artifactId>
    <version>0.0.8</version>
</dependency>

Creating CDOC files

import org.cdoc4j.CDOCBuilder;
import static org.cdoc4j.CDOC.VERSION.CDOC_V2_0;

// 0. Create the builder
CDOCBuilder builder = CDOC.builder();
// Override default CDOC 1.1 version
builder.setVersion(CDOC_V2_0);

// 1. Where to write the output
builder.setOutputStream(new FileOutputStream("output.cdoc"));

// 2. Set recipients
X509Certificate cert = ...
builder.addRecipient(cert);

// 3. For legacy XML containers, add files via any of the following methods
builder.addStream("test1.txt", new URL("http://www.example.com/test1.txt")); // or ByteArrayInputStream
builder.addFile(new File("test2.txt"));
builder.addPath(Paths.get("test3.txt"));
builder.build(); // Writes it to output stream
builder.buildToStream(new FileOutputStream("otherfile.cdoc"));

Opening CDOC files

import CDOC;

// 1. Either from a file
CDOC cdoc = CDOC.open(new File("test.cdoc"));

// 2. Or from an InputStream
InputStream input = new URL("http://example.com/sample.cdoc").openStream();
CDOC cdoc = CDOC.from(input);

// 3. Once the file has been opened, get recipients 
List<Recipient> recipients = cdoc.getRecipients();

// 4. Information in a Recipient object allows to construct the transport key for decryption
KeyPair kp = ...
SecretKey key = Decrypt.getKey(kp, recipients.get(0));

// 5. Knowing the transport key allows to access the encrypted files
Map<String, byte[]> files = cdoc.getFiles(key); // Can consume a lot of memory with large files

CDOC 2.0 and streams (Work in Progress)

CDOC 2.0 is designed to be more resource efficient and flexible than CDOC 1.x. CDOC 2.0 is a standard ODF ZIP container with an inner ZIP file, which allows to use standard Java ZipInputStream/ZipOutputStream interfaces. This way you can easily encrypt and decrypt files with sizes in several gigabytes without running out of memory.

// To open the payload as a ZipInputStream
ZipInputStream zip = cdoc.getZipInputStream(key);

// To add files via ZipOutputStream
ZipOutputStream zip = CDOC.builder(CDOC_V2_0).addRecipient(...).buildZipOutputStream();
zip.putNextEntry(new ZipEntry("test.txt"));
IOUtils.copy(new InputSream(...), zip);
zip.closeEntry();
zip.close();

Notes and caveats

  • CDOC 1.X uses XML and in-memory processing of Base64 data, which requires a lot of memory. Thus it is advisable to only encrypt small files (in the range of 1M..100M, not 100M..1G) into v1.X formats and to make sure that enough memory is available to the JVM (-Xmx8g)

Dependencies