Releases: openpgpjs/openpgpjs
v4.10.0
- All signatures using MD5 or RIPEMD are now rejected by default (#1043)
Setopenpgp.config.reject_hash_algorithms.add(openpgp.enums.hash.sha1);
to add SHA1 to this list, for extra security. This may break compatiblity with encrypting to old public keys, which may still use SHA1 for their self-signatures. We may add SHA1 to this list by default in the future. - Message signatures using MD5, RIPEMD or SHA1 are now rejected by default
Setopenpgp.config.reject_message_hash_algorithms.delete(openpgp.enums.hash.sha1);
to remove SHA1 from this list, in order to maintain increased compatibility with very old signatures. await signatures[*].verified
afterconst { signatures } = await openpgp.decrypt/verify()
now throws rather than returningfalse
for all signature verification failures (it already threw for some errors)- (When not streaming)
signatures[*].valid
is nowfalse
for all signature verification failures (it used to benull
for some errors; now it's onlynull
if the signing public key was unavailable or invalid) Key.prototype.validate
now throws if the private key parameters don't match the public key parametersKey.prototype.verifyPrimaryKey
now throws if the primary key is invalidKey.prototype.getPrimaryUser
now throws if there is no valid primary userKey.prototype.getSigningKey
andKey.prototype.getEncryptionKey
now throw if there is no valid signing/encryption keyKey.prototype.getRevocationCertificate
now throws if there is no valid revocation certificateSubKey.prototype.verify
now throws if the subkey is invalidUser.prototype.verify
now throws if there are no valid self certificatesUser.prototype.verifyCertificate
now throws if the user certificate is invalid- Optimize reading and writing armored messages (#1043)
- Fix error message for legacy encrypted private keys
v4.9.1
- Binary signatures on text messages: sign and verify text as UTF-8 instead of UTF-16
- Add inline sourceMap in minified files in
grunt build --dev
- Fix typo in symmetric encryption example in README.md (#1042)
Note: this release might change signature verification results in rare cases if you verify detached signatures on binary documents by doing something like:
const message = await openpgp.message.fromText(binaryString);
const result = await openpgp.verify({ message, signature, publicKeys });
Instead, you should do:
const message = await openpgp.message.fromBinary(openpgp.util.str_to_Uint8Array(binaryString));
const result = await openpgp.verify({ message, signature, publicKeys });
v4.9.0
- Fix Blowfish encryption and decryption (#1041)
- Fix streaming non-AES encryption and decryption
- Use native Node crypto for non-AES encryption and decryption
- Don't use Node symmetric crypto when
openpgp.config.use_native == false
- Clean up README.md (#1040)
- Update setup instructions
- Add example code for piping unarmored encrypted data on Node.js
Note: if you previously used OpenPGP.js to encrypt messages using a public key that specified Blowfish as its preferred symmetric algorithm, or if you set openpgp.config.encryption_cipher = openpgp.enums.symmetric.blowfish
, those messages would have been broken and undecryptable by any OpenPGP library other than OpenPGP.js. From this version, OpenPGP.js won't be able to decrypt such messages anymore either, since Blowfish encryption and decryption has been fixed to match the specification. If you have to decrypt such messages anyway, see dc9660f for a code example (but note that this breaks encryption again, too).
v4.8.1
- Don't keep entire decrypted message in memory while streaming (#1033)
(When config.allow_unauthenticated_stream is set or the message is AEAD-encrypted.) - Test loading OpenPGP.js from a Worker in the application (#1032)
- Properly detect and use Web Crypto when using OpenPGP.js from a Worker in the application.
- Terminate workers in
openpgp.destroyWorker()
(#1031) - Allow calling clearPrivateParams on decrypted keys
(Calling it on unencrypted keys was already allowed, so this safety check didn't do much.) - Zero out private key parameters in
clearPrivateParams
- Implement
Key.prototype.clearPrivateParams
- Implement
openpgp.getWorker().clearKeyCache()
- Clear worker key caches in
openpgp.destroyWorker()
- Switch code coverage reporter to nyc (#1005)
Note: openpgp.destroyWorker()
now returns a Promise (to indicate when the worker's key caches have been cleared and the workers have been terminated) but it still immediately stops OpenPGP.js from using the worker, thus should be backwards compatible in that respect.
However, this release is backwards incompatible if you were relying on the fact that openpgp.destroyWorker()
didn't terminate the workers, for example by using streaming encryption / decryption with a worker active and then continuing to read from a stream of data that was returned by openpgp.encrypt
/decrypt
after calling openpgp.destroyWorker()
.
v4.8.0
- Cache key objects in Workers by armor (#1030)
This improves performance when repeatedly using the same private/public keys with a Worker (usingopenpgp.initWorker
). Note: this may pose a security risk since private keys are cached in memory indefinitely (as long as the application is open). If your threat model includes an attacker inspecting memory, be sure to clear keys from memory manually. - Remove support for legacy encrypted private keys (#1029)
Note: this may be backwards-incompatible if you store very old encrypted private keys (e.g. created with GPG <1.0.7 or >=1.0.7 with--simple-sk-checksum
). If this is the case for you, shoot us a message on gitter to ask about migration options. - Implement
key.validate()
(#1028)
Calling this function after decryption is required if the encrypted private key was stored on an untrusted medium, and trust is derived from being able to decrypt the private key with your own password, and you use the private key for encrypting or verifying (rather than, or in addition to, decrypting or signing) data.
Note that this function doesn't work for GNU-dummy keys, currently (as is more or less expected, as trust can't be derived from a GNU-dummy private key packet since the private key parameters are missing). - Update asmcrypto.js (#1023)
This should fix certain issues with TypeScript declarations. - Comment typo fixes (#1022)
v4.7.2
v4.7.1
v4.7.0 - Lightweight Build & Performance Improvements
Lightweight Build
This release adds a lightweight build that can lazily load indutny/elliptic
on demand if needed (#956).
indutny/elliptic
is a large dependency of this library that adds support for certain ECC curves. It is not required if you only use RSA (currently the default for keys generated using OpenPGP.js), curve25519, or the NIST curves (with certain exceptions - see the list below). So, when using OpenPGP.js in a web app, a lot of bandwidth can be saved by not including it by default and only loading it when necessary. Currently, the lightweight build is more than 79kB smaller (32kB smaller when comparing gzipped sizes), and we hope to make it even smaller in future releases!
To use the lightweight build, simply use dist/lightweight/openpgp.js
instead of dist/openpgp.js
, and additionally copy elliptic.min.js
from that directory. OpenPGP.js will then automatically load elliptic.min.js
when encrypting, decrypting, signing or verifying a message using a (sub)key that uses one of the following curves:
- brainpoolP256r1
- brainpoolP384r1 (Note: this curve is non-standard)
- brainpoolP512r1
- secp256k1 (Note: this curve is non-standard)
- NIST P-521, when using Safari
- NIST P-256, NIST P-384 or NIST P-521, in an environment where Web Crypto and Node crypto are not available (e.g., on a non-HTTPS web page)
curve25519 is always supported, regardless of Web Crypto or Node crypto availability. Even when not using the lightweight build, we recommend only using curve25519 or one of the NIST curves, if possible, as indutny/elliptic
's implementation of the other curves is not constant time (#720).
If you don't need support for other curves, you can also set openpgp.config.use_indutny_elliptic = false
, and then you don't have to copy elliptic.min.js
when using the lightweight build. Note: in environments where Web Crypto and Node crypto are not available (e.g., on a non-HTTPS web page), this may cause things to break, as it makes OpenPGP.js non-compliant with the spec, which requires support for NIST P-256.
There are two other config options to configure how to load indutny/elliptic
: indutny_elliptic_path
and indutny_elliptic_fetch_options
.
Note: if your web app usually does use one of the curves listed above, it's best not to use the lightweight build, as loading both the lightweight build and elliptic.min.js
currently actually adds almost 17kB over just using the normal build. We're planning to reduce this gap in future releases.
Backwards-Incompatible Changes
-
Rename
numBits
andbits
torsaBits
(#970)Keep supporting the old names as well though in
openpgp.generateKey
andgetAlgorithmInfo
, but not inopenpgp.key.generate
(as it is recommended that developers useopenpgp.generateKey
instead, and it now throws when usingnumBits
instead ofrsaBits
, so there's no risk of silent key security downgrade).The old names are now deprecated, and might be removed in v5.
New features
- Implement
Key.prototype.addSubkey
(#963)
Performance Improvements
-
Optimize encrypting and decrypting keys using iterated S2K (#1002)
-
Use Web Crypto & Node crypto for RSA signing and verifying (#999)
Also, when generating RSA keys using Web Crypto or Node crypto, swap the generated p and q around, so that we don't have to recompute the generated u coefficient.
-
Verify NIST signatures using Web Crypto instead of
indutny/elliptic
when not streaming -
Use tweetnacl.js instead of
indutny/elliptic
for curve25519 key generation -
Don't initialize indutny's curve25519, improving performance when using that curve
-
Use serialized EdDSA public key when signing instead of deriving it
Bugfixes
-
Only store newly created signatures as valid in the non-streaming case
-
Fix
openpgp.revokeKey().publicKey
when using the Worker -
Don't return lone
\r
characters inutil.Uint8Array_to_b64
-
AEAD: Fix high water mark calculation based on chunk size
-
Fix queued bytes calculation for AEAD concurrency
-
Fix
crypto.random.getRandomBytes
when loading OpenPGP.js inside a Worker (#997) -
Fix handling of private keys with leading zeros for certain curves
-
Iterated S2K: always hash the full salt+password at least once
-
Fix encrypting keys that were previously encrypted using a non-AES algorithm
-
Always encrypt keys using AES, even if they were previously encrypted using a non-AES algorithm
-
When generating RSA keys in JS, generate them with p < q, as per the spec
Also, when generating RSA keys using Web Crypto or Node crypto, swap the generated p and q around, so that they will satisfy p < q in most browsers (but not old Microsoft Edge, 50% of the time).
Test Suite Changes
-
Switch from Sauce Labs to Browserstack (#965)
-
Fix key preferences test when using Worker and
use_native=false
-
Fix test failing on high-core-count systems due to AEAD concurrency
Refactorings
-
Split up key.js (#972)
-
Move KeyPair.sign/verify to ecdsa.js
-
Move KeyPair.derive to ecdh.js
-
Move keyFromPrivate and keyFromPublic to a new indutnyKey.js file
-
Switch back to using upstream email-address library (#998)
-
Refactor S2K function
Release Script
-
Remove browserify caches when releasing, to prevent broken builds
-
Don't use sed to edit gitignore in release.sh, as
sed -i
is not cross-platform
v4.6.2
v4.6.1
- Use native Node crypto for RSA key generation (#947)
- Throw when trying to encrypt a key that's already encrypted (#950)
- Fix intermittent Brainpool sign/verify bug (#948)
- Style fixes; add spaces around all infix operators, remove use of
new Buffer
(#954) - Fix generating signing subkeys (#967)
- Fix decrypting newly generated key object when using the Worker