IOCipher: Virtual Encrypted Disks


alberti cipher disk


IOCipher provides a virtual encrypted disk for Android apps without requiring the device to be rooted. It uses a clone of the standard java.io API for working with files, so developers already know how to use it. Only password handling, and opening the virtual disk are what stand between the developer and working encrypted file storage. It is based on and SQLCipher, and designed to work with CacheWord for handling the keys and passwords.

IOCipher is ultimately based on transactions in SQLite, which means that it does not require being mounted in the normal sense. There is no open state once a transaction is complete. Each read or write operation is a self-contained SQLite transaction, so if the file system is forcably quit, SQLite’s transactions prevent the whole file system from being corrupted. This is important in Android since an Activity or Service can be killed at any moment without warning.

IOCipher is a cousin to SQLCipher-for-Android since it is also based on SQLCipher and uses the same approach of repurposing an API that developers already know well. It is built on top of libsqlfs, a filesystem implemented in SQL that exposes a FUSE API.

Features

  • Secure transparent app-level virtual encrypted disk
  • No root required
  • Only three new methods to learn: VirtualFileSystem.get(), VirtualFileSystem.mount(dbFile, password), and VirtualFileSystem.unmount()
  • Supports Android versions 2.3 and above
  • Licensed under the LGPL v3+

Adding IOCipher to your App

Here are the things you need to do in your code to make it use IOCipher encrypted storage for all of your app’s file storage:

  1. manage the password using Cacheword or whatever works for you
  2. get the VFS singleton using VirtualFileSystem.get()
  3. on first run, create the container file with a password using VirtualFileSystem.createNewContainer(dbFile, password)
  4. mount the container file with a password using VirtualFileSystem.mount(dbFile, password)
  5. replace the relevant java.io import statements with info.guardianproject.iocipher, e.g.:
    import info.guardianproject.iocipher.File;
    import info.guardianproject.iocipher.FileOutputStream;
    import info.guardianproject.iocipher.FileReader;
    import info.guardianproject.iocipher.IOCipherFileChannel;
    import info.guardianproject.iocipher.VirtualFileSystem;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.nio.channels.Channels;
    import java.nio.channels.ReadableByteChannel;
    

For more detailed examples, see IOCipherExample, IOCipherThreadTest, and IOCipherTests. To start from scratch, follow the instructions on starting with SQLCipher-for-Android, then download IOCipher and add it to the libs/ folder of that new project.

Downloads

For gradle projects, use one of these lines. The quickest way to get started is to use the standalone package that includes SQLCipher in it.

    implementation 'info.guardianproject.iocipher:IOCipherStandalone:0.5@aar'

If your project already includes SQLCipher, then use the release that contains only IOCipher.

    implementation 'info.guardianproject.iocipher:IOCipher:0.5@aar'
    implementation 'net.zetetic:android-database-sqlcipher:4.2.0@aar'

Otherwise, the files can also be downloaded directly from jcenter, including the PGP signatures:

Source Code

optional:

Usage notes

  • only one active mount per-app is supported
  • single thread/sequential access is the preferred way of using IOCipher
  • multi-threaded access possible (potentially unstable under extremely high write load)
  • VFS now has beginTransaction and completeTransaction to optimize performance
  • parts of java.io not currently supported: vectored I/O, memory-mapped files

Reporting Bugs

Please report any bugs or issues that you have with this library! We want to hear from you. Help us improve this software by filing bug reports about any problem that you encounter. Feature requests and patches are also welcome!

Known Issues

  • files cannot currently be larger than 4GB (#3624)
  • no users, groups, or permissions implemented
  • crashes possible under extremely heavy, concurrent load (#522)
  • View all open issues