github openpgpjs/openpgpjs v3.0.9
V5 Keys, AEAD support

latest releases: v6.0.0-beta.0, v5.11.1, v6.0.0-alpha.1...
6 years ago

Native AES-EAX
Native Web Crypto and Node Crypto do not support AES-EAX, but they do support AES-CTR, which AES-EAX is built upon. Therefore, I've implemented EAX in a way that is agnostic to the underlying CTR implementation, and automatically selects native CTR whenever available.

Similarly, EAX also makes use of CMAC, which in turn makes use of CBC, which is supported by Web and Node Crypto, so I've made use of that as well.

EAX mode itself (as opposed to AES-EAX) does not require AES and is flexible enough to be used with any block cipher, but RFC4880bis-04 only mandates support for AES-128. We support AES-{128, 192, 256} (although AES-192 is not supported by Web Crypto in Chrome).

A note on implementing a draft specification
RFC4880bis-04 is a work in progress and may change at any time, and any implementation of it should be considered as such as well. The OpenPGP.js documentation already did a good job of making users aware that enabling AEAD may break compatibility with other implementations, but I have now also added a warning that future versions of OpenPGP.js may break compatibility with it, as well.

Backwards compatibility
Unfortunately, RFC4880bis-04 is already incompatible with our current implementation of the previous draft: for example, the AEAD Encrypted Data Packet has gained fields for the cipher algorithm, AEAD algorithm, and chunk size.

A look at GitHub code search reveals that aead_protect is actually used quite a lot, even in apps that store encrypted PGP messages on disk or present them to the user (luckily no large projects seem to do this). This is probably because our first example of setting up OpenPGP.js includes it (which is modified now).

Therefore, we have decided to maintain support for the previous version, and only enable support for the new version when setting openpgp.config.aead_protect_version = 4.

AEAD Support Feature Flags
The new draft adds feature flags for AEAD support in public keys. We add those flags when support for the new draft is enabled. When encrypting using a public key, we only use AEAD when the target key claims support for it. (This only applies for the new draft — the old draft didn't support feature flags so we don't look for them.)

GCM in the new draft
Because GCM is faster than EAX and OCB using Web Crypto (although EAX doesn't lag too far behind, it's not 100% native as GCM is, and so still a bit slower), we have implemented it in the new draft as well, as a "private/experimental algorithm" (with algorithm ID 100). Since GCM is not defined by the spec, we had to decide on a few implementation details ourselves, most notably the computation of the nonce from the IV and chunk counter. A future version of the standard may define GCM mode differently, hopefully under a different ID (e.g. ID 3) so that we can maintain backwards compatibility.

You can enable GCM by setting openpgp.config.aead_mode = openpgp.enums.aead.gcm.

Preferred AEAD Algorithms
The new draft also adds a packet containing the AEAD algorithms that the user of the public key prefers. When encrypting using a public key, those preferences have precedence over the aead_mode setting. When generating a public key, we claim preference for EAX over OCB, since EAX is for a large part implemented using native crypto.

The aead_mode setting currently does not influence the generated preferences, causing it to have no effect when solely using public-key cryptography. This restriction also applies to the other algorithm options (prefer_hash_algorithm, encryption_cipher and compression) and could be fixed together with those in the future.

Version 5 Keys
The draft also specifies V5 Public/Private Key packets and V5 Symmetric-Key Encrypted Session Key packets. The main difference with their V4 counterparts is that they encrypt their contents with an AEAD algorithm. We generate these V5 packets when support for this draft version is enabled.

V5 Public/Private Keys also have some other minor improvements. As per the spec:

The version 5 format is similar to the version 4 format except for the addition of a count for the key material. This count helps parsing secret key packets (which are an extension of the public key packet format) in the case of an unknown algoritm. In addition, fingerprints of version 5 keys are calculated differently from version 4 keys.

Don't miss a new openpgpjs release

NewReleases is sending notifications on new releases.