# HG changeset patch # User Laman # Date 2019-07-27 19:44:01 # Node ID abd03aa8b1630cc4c853e75f363c7dedcfd7d496 # Parent 2f53bcd63dfad893cc4b7800cd2a633280d17ab6 added readme diff --git a/readme.md b/readme.md new file mode 100644 --- /dev/null +++ b/readme.md @@ -0,0 +1,27 @@ +# CryptoJS # + +Javascript implementation of the Chacha20 cipher and BLAKE2s hash function. I wrote it for my amusement. Licensed under GNU GPL. + +I trust the output messages to be secure and reliably authenticated. But it is up to the potential user to trust my skills and my honesty if he decides to use this code. For serious purposes you can find more serious software. + +## Components ## + +### Chacha20 ### +A stream cipher as documented in [RFC 8439](https://tools.ietf.org/html/rfc8439). It is used to encrypt the message. + +### BLAKE2s ### +Cryptographic hash function as documented in [RFC 7693](https://tools.ietf.org/html/rfc7693). Resistant to length extension attacks. It is used for key stretching and message authentication. + +### PBKDF2-BLAKE2s ### +PBKDF2 key derivation function as documented in [RFC 2898](https://tools.ietf.org/html/rfc2898). It aims to make brute forcing a message key ineffective. This implementation uses plain BLAKE2s (no HMAC) as the underlying hash function. It is used for the initial key stretching. + +## Encryption scheme ## +![Encryption scheme](scheme.png "Encryption scheme") + +A 32 bytes encryption key is derived from the user provided password and a 12 bytes random salt with PBKDF2 (variable number of rounds, 0.5-1 s). It is then used to encrypt the plaintext with Chacha20 and sign the message along with necessary auxilliary data with BLAKE2s. The final message consists of 30 bytes header: 1 B program version, 1 B indicating number of PBKDF rounds, 16 B signature and 12 B salt; followed by the encrypted message. + +## Discussion ## +* Using the salt in the key derivation and as the input to Chacha20 is not strictly necessary, as the cipher is already implicitly salted by the derived key. But there is no reason not to include it. +* Implementing a computation heavy function like the PBKDF in unoptimized Javascript code severly hinders its performance. Therefore its protection of weak passwords is rather limited and can't be relied upon. Then again, on my computer it achieves several thousand iterations within the alotted time, which I consider somewhat beneficial. +* It is necessary to first derive the key before the signature can be checked. Therefore it is trivial to create messages that will take impractically long to reject when injected into genuine communication (by setting a high N). Signing with the plain password to mitigate this would remove the protection of key derivation function against brute forcing. Setting the PBKDF to a fixed number of rounds would unavoidably make it unoptimal on some devices (either high performance or low performance). So I deem the current situation acceptable. +* 30 bytes header can make very short messages a lot longer. For special purposes it would be possible to remove the signature (16 B) or even the header altogether and rely just on the password (now with the implied condition of using a unique password each time). Acknowledging this, I still consider it wiser to always include the header for a general case. diff --git a/src/pbkdf2.js b/src/pbkdf2.js --- a/src/pbkdf2.js +++ b/src/pbkdf2.js @@ -1,3 +1,4 @@ +// https://tools.ietf.org/html/rfc2898 import {int322bytesBE} from "./util.js"; import {blake2s} from "./blake.js";