2
$\begingroup$

I am playing around with PyNaCl to get a bit into cryptography atm.

Now I wrote two scripts to encrypt a file with a secret key and then decrypt it again using that key. The encryption part works fine but I am having trouble with decrypting the file again. I get the error nacl.exceptions.ValueError: The nonce must be exactly 24 bytes long when I execute decrypt.py. When I explicitly hand the nonce generated in decrypt.py to the decrypt() function I get the error nacl.exceptions.CryptoError: Decryption failed. Ciphertext failed verification

When I use the last three lines of decrypt.py in encrypt.py however, it works for some reason. But of course I don't want to instantly decrypt the file I just encrypted, instead I want to do that with a separate script at a later point.

Also, I am only using SCRYPT here because PyNaCl does not contain Argon2 in my installation for reasons unknown. I am also aware that I hardcoded the salt in a variable, this is just for testing purposes. Later I want to generate that with utils.random and write it to the encrypted file.

My scripts look as follows:

encrypt.py

from nacl import pwhash, secret, utils

password = b'lala'
infile = "test.mp4"
outfile = "out.crypt"

kdf = pwhash.kdf_scryptsalsa208sha256
salt = '\x1b\r\xbfxrL\xee\x83x\x0b\x83\x13O\x1dv\xbc\xd5\x13\x18w;G\xd6\x88 \xae\x8b\x96^\xbd4\xbc' 
ops = 33554432
mem = pwhash.SCRYPT_MEMLIMIT_SENSITIVE


with open(infile, "rb") as in_file:
    data = in_file.read()

derivatedKey = kdf(secret.SecretBox.KEY_SIZE, password, salt,
                 opslimit=ops, memlimit=mem)
secretBox = secret.SecretBox(derivatedKey)
nonce = utils.random(secret.SecretBox.NONCE_SIZE)
encrypted = secretBox.encrypt(data, nonce)

with open(outfile, "wb") as out_file:
        out_file.write(encrypted)

decrypt.py

from nacl import pwhash, secret, utils

password = b"lala"
infile = "out.crypt"
outfile = "decrypted.mp4"

kdf = pwhash.kdf_scryptsalsa208sha256
salt = '\x1b\r\xbfxrL\xee\x83x\x0b\x83\x13O\x1dv\xbc\xd5\x13\x18w;G\xd6\x88 \xae\x8b\x96^\xbd4\xbc'
ops = 33554432
mem = pwhash.SCRYPT_MEMLIMIT_SENSITIVE

key = kdf(secret.SecretBox.KEY_SIZE, password, salt,
               opslimit=ops, memlimit=mem)
box = secret.SecretBox(key)
nonce = utils.random(secret.SecretBox.NONCE_SIZE)
decrypted = box.decrypt(infile)

with open("outfile", "wb") as out_file:
    out_file.write(decrypted)

Any help would be greatly appreciated!

$\endgroup$
2
$\begingroup$

It's not really a cryptography question, but I think the decryption would go better if you read the data from infile first (box works on strings of data, not filenames), so

with open(infile, 'r') as in_file:
    encrypted = in_file.read()

and later:

decrypted = box.decrypt(encrypted)

where the nonce before it can go, as it is not used (the encrypted data contains the generated salt from encrypting).

Also the quotes on "outfile" can go. It's a variable.

$\endgroup$
  • $\begingroup$ Thanks a lot! That did the trick. Sorry for choosing the wrong stackexchange. I will post on stackoverflow the next time. $\endgroup$ – Marcus Aug 31 '17 at 11:27
  • $\begingroup$ @Marcus Glad I could help. stackoverflow has a cryptography tag for questions like this. $\endgroup$ – Henno Brandsma Aug 31 '17 at 21:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.