X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=doc%2Fsrc%2Fpassword_encryption.txt;h=f618378d3e2349e8b277053f7bcfa8d3f1e0c0ae;hp=4709f557da4946768b2d62f0aa6ccbfeb6a9adc5;hb=a7f0d049b6a7f1df5fe4e6487ddbb140c22370e0;hpb=ffd418aaa7b4bdf401193a96194346ff7e403b9e diff --git a/doc/src/password_encryption.txt b/doc/src/password_encryption.txt index 4709f557d..f618378d3 100644 --- a/doc/src/password_encryption.txt +++ b/doc/src/password_encryption.txt @@ -2,28 +2,37 @@ Unless --with-password-encryption=old is active, account passwords are stored encrypted using AES-256-CBC, using following scheme: ---------------------------------------------------------------------- -Encryption/decryption key is either PASSCRYPT_KEY, or user-selected master passphrase. - -We take the digest of the key using SHA-512, which gives us a 64 bytes -long hash. - -The first half of the hash is XORed with the second (1st byte with -33rd, 2nd with 34th, etc.). This is gives us 32 bytes, which is -the exact length required for AES-256-CBC. +Encryption/decryption key is derived from either PASSCRYPT_KEY, or +user-selected master passphrase, using PBKDF2, using salt from +'master_passphrase_salt', and number of rounds (iterations) from +'master_passphrase_pbkdf2_rounds'. -IV for the cipher is filled with random bytes. +IV (initialization vector) for the cipher is filled with random bytes. Encryption ---------- -We prepare a buffer 128+blocksize bytes long, with one block of random -data at the beginning, followed by the password we want to encrypt, -rest is padded with zero bytes. - -We encrypt the buffer. +We prepare a buffer long enough to fit the NULL-terminated password string +plus one cipher block in it, with one block of random data at the beginning, +followed by the password we want to encrypt (in UTF-8), rest is padded +with zero bytes. + +The minimal buffer size is 128+blocksize, and if the password (including +the trailing NULL byte) is longer than 128 bytes, the size is increased by +another 128 bytes until it is long enough to fit the password plus one +cipher block. This is to make it harder to guess the password length from +length of the encrypted string. So for example, if the password (again, +including the trailing NULL byte) is 129 characters long, our buffer will +be 256+blocksize bytes long. + +We encrypt the buffer using the encryption key and IV mentioned above, +resulting in ciphertext of the same length as the buffer. We base64-encode the ciphertext, and store it as: -"{algorithm}encodedciphertext" +"{algorithm,rounds}encodedciphertext" + +"rounds" is an integer value set to number of PBKDF2 rounds used to +generate the key derivation used as encryption key. Decryption @@ -31,10 +40,11 @@ Decryption We strip the "{algorithm}" (after verifying that it matches what we expect) and base64-decode the remaining ciphertext. -We decrypt the ciphertext. +We decrypt the ciphertext using decryption key and IV mentioned above, +resulting in plaintext of the same length as the ciphertext. -We discard the first block, and the rest is a zero-terminated string -with our password. +We discard the first block from plaintext, and the rest is a +zero-terminated string with our password in UTF-8. Why the random block at the beginning?