Autor: Police Terror Data: A: libbitcoin Assumpte: Re: [Libbitcoin] Encrypting a wallet with AES
OK, thank you!
William Swanson: > Oh, good point. I didn't realize that the salt would be redundant with
> the extended nonce. In that case, you can get away with the following
> simplified plan:
>
> * Generate 192 bits of random data (24 bytes)
> * Use the first 128 bits (16 bytes) as the salt for Argon2.
> * Use the next 64 bits (8 bytes) as the nonce for ChaCha20-Poly1305
> * Store both values in plaintext alongside the encrypted data
>
> This scheme should give you all the security you need.
>
> For reference, here is the semi-overkill idea I originally had:
>
> * Generate 320 bits of random data (40 bytes)
> * Use the first 128 bits (16 bytes) for the password salt
> * Mix the next 128 bits (16 bytes) with the derived key using
> crypto_core_hchacha20
> * Use the last 64 bits (8 bytes) for the nonce
> * Store all three values in plaintext alongside the encrypted data
>
> Step 3 isn't really needed, since step 2 already provides all the
> needed entropy.
>
> -William
>
> On Tue, Oct 18, 2016 at 1:54 AM, Police Terror <PoliceTerror@???> wrote:
>> So the ChaCha20-Poly1305 nonce is 12 bytes, and crypto_pwhash wants a
>> salt of 16 bytes.
>>
>> What you're saying I should do is generate 24 bytes of random data
>> everytime I want to encrypt.
>>
>> Then use the first 8 bytes (64 bits) as the nonce for ChaCha20-Poly1305
>> encryption, and mix the remaining 16 bytes with the key using the
>> function: crypto_core_hchacha20()
>>
>> Where should I get the 16 bytes for the salt from, and what should I do
>> with this? Simply store the <nonce, salt> alongside the encrypted data?
>>
>> Should I bother with the incrementing nonce, or just generate a new
>> random nonce and salt everytime I want to re-encrypt the wallet?
>>
>> William Swanson:
>>> For password hashing, you are using the wrong function. You want
>>> `crypto_pwhash`, not `crytpo_pwhash_str`. The `crytpo_pwhash_str` will
>>> return a different result every time you call it, since it uses a
>>> random-number generator to automatically handle salting. The
>>> `crypto_pwhash` function is designed for key generation, and allows
>>> you to specify the length explicitly. You also need to provide your
>>> own salt for this function. Whatever salt you pick (a random number)
>>> should be stored in plaintext alongside the encrypted data. That way,
>>> when the user re-enters their password to decrypt the data, you can
>>> supply the same salt again to derive the same key.
>>>
>>> For the nonce, `randombytes_buf` could work, but I don't recommend
>>> using it directly. The nonces used in ChaCha20-Poly1305 are too short
>>> for randomness to be safe. There is a scary-high probability that the
>>> same random number will appear twice, revealing the secret key. The
>>> algorithm is *really* designed to be used with session keys and a
>>> message counter, as it would be in SSL. It's a bad fit for storing
>>> data on disk, but there is a workaround:
>>> https://download.libsodium.org/doc/key_derivation/#nonce-extension >>>
>>> The basic strategy is to generate a 192-bit random number, then use
>>> the first 64 bits as the nonce, and mix the other 128 bits with the
>>> key. A 192-bit nonce is just long enough to be "safe" against birthday
>>> attacks, so this approach will give you the security you need. The
>>> 192-bit nonce should be stored on-disk in plaintext, yes.
>>>
>>> -William
>>>