[Haskell-cafe] Encrypting streamed data

Viktor Dukhovni ietf-dane at dukhovni.org
Tue Jul 11 22:33:24 UTC 2017


On Tue, Jul 11, 2017 at 03:35:56PM +0100, David Turner wrote:

> I can't think of a terribly good way to achieve GPG/PGP-compatibility
> without simply using GPG/PGP, since the file format is quite involved.
> 
> That said, here is how to implement a CBC-mode block cipher encryption
> using Conduit, which is suitable for something like AES256 encryption. It
> is almost certainly vulnerable to side-channel attacks (timing,
> cache-poisoning, etc) but as a pure function from input to output it is
> equivalent to `openssl aes-256-cbc -e -K <KEY-IN-HEX> -iv <IV-IN-HEX> -in
> data/plain-text.txt` which I should hope would be standard enough for
> analysis.

Just straight CBC lacks integrity protection.  A MAC is still
required, and usually one wants asymmetric key exchange, rather
than a shared symmetric key.  So in practice one wants something
like CMS (successor to S/MIME).

The OpenSSL cms(1) command can do clear signing, encryption, or
both (in either order) by piping the output of one to the other.
In many applications it is safer to encrypt then sign, rather than
sign and then encrypt.

Packetizing large input streams is well worth it, but while each
"packet" can use any of a number of standar formats, some standards
(notably CMS AFAIK) may lack support for packetizing large input
streams.

The OpenPGP standard does support breaking streams into "packets",
so for large streams that may be optimal, you just need an OpenPGP
library implementation that supports sensible packet sizes, and
perhaps an FFI interface for Haskell.

Alternatively, just a pipe to a CLI will do, bug the "gpg" CLI does
not appear to support creating streams with more than one packet
(Unless this happens implicitly for "large-enough" streams).

-- 
	Viktor.


More information about the Haskell-Cafe mailing list