hwsecurity-openpgp / de.cotech.hw.openpgp.util

Package de.cotech.hw.openpgp.util


Name Summary

open class DecryptingFileInputStream :InputStream

An InputStream that decrypts data with a ByteSecret. See DecryptingFileInputStream.


open class EncryptingFileOutputStream :OutputStream

An OutputStream that encrypts data with a ByteSecret.

ByteSecret secret = SecretGenerator.getInstance().createRandom(32);
  EncryptingFileOutputStream efos = new EncryptingFileOutputStream(new File("filename.encrypted"), secret);
  try {
  } finally {
  BufferedReader reader = new BufferedReader(new DecryptingFileOutputStream(new File("filename.encrypted"), secret));
  try {
      String line = reader.readLine();
      assertEquals("hello!\n", line);
  } finally {

Internally, this uses AES-GCM for authenticated encryption. The randomly generated nonce is stored as part of the file.


open class ParcelFileDescriptorUtil

Utility class for loading streamed data into a seekable ParcelFileDescriptor.

This covers the use case of passing streaming data via an ACTION_SEND or similar Intent, without caching to a file. This is especially useful for encrypted files, e.g. from a DecryptingFileInputStream.

Unlike ParcelFileDescriptors obtained from a ParcelFileDescriptor#createPipe(), this method returns a seekable ParcelFileDescriptor. In practice, virtually all receivers of Intents with streamed data require seekable file descriptors. android.content.ContentProvider

ParcelFileDescriptor openFile(Uri uri, String mode) {
      try {
          File file = database.getEncryptedFilenameForUri(uri);
          int plaintextLength = getPlaintextLengthForUri(uri);
          return parcelFileDescriptorCompat.loadToParcelFileDescriptor(file, plaintextLength);
      } catch (e: IOException) {
          throw new FileNotFoundException(e.getMessage());

Internally, this uses one of two mechanisms:

  • On Android O (sdk 26) or higher, it uses a android.os.ProxyFileDescriptorCallback backed by a reference-counted android.os.MemoryFile.
  • On earlier Android versions, it falls back to a mechanism based on ephemeral file descriptors. To this end, it creates a file on storage that is deleted immediately after opening a couple of file descriptors. These file descriptors are cached and used for any subsequent access. Note that this method does not keep data strictly in-memory, but it’s as close as we could get.

Note: in our tests, the technique of extracting the internal file descriptor of a MemoryFile using reflection did not actually yield a seekable ParcelFileDescriptor that worked as intended.

RsaEncryptionUtil open class RsaEncryptionUtil