How to use scrypt to generate a hash for password and salt in Python

I would like to use scrypt to create a hash for the passwords and salts of my users. I found two links , but there are things that I do. I don’t understand about them.

They use encryption and decryption functions. One encrypts a random string, and the other encrypts the salt (which looks wrong, since only the password is used for decryption, not the salt). It seems that the decryption function is used to check the password / salt as a side effect of decryption.

Based on what I understand, what I want is a key derivation function (KDF), not encryption / decryption, and that KDF is most likely generated and used by scrypt to encrypt / decrypt. Actual KDF is used behind the scenes, and I am concerned that blindly following these examples will lead to an error. If the encryption / decryption functions are used to generate and verify the password, I do not understand the role of the encrypted string. Does its content or length know?

+8
python password-encryption scrypt
Nov 30 '12 at 23:06
source share
2 answers

You are right - the scrypt functions these two links work with are a scrypt file encryption utility, not a basic kdf. I was slowly working on creating a standalone encryption-based password for python and I ran into this problem myself.

The scrypt file utility does the following: selects the scrypt n / r / p parameters specific to your system and the "min time" parameter. Then it generates 32 bytes of salt, and then calls scrypt(n,r,p,salt,pwd) to create a key of 64 bytes. The binary string returned by the tool consists of: 1) a header containing the values ​​of n, r, p and the salt encoded in binary format; 2) checksum sha256 header; and 3) a signed copy of the hmac-sha256 checksum using the first 32 bytes of the key. After that, it uses the remaining 32 bytes of the key to encrypt the AES input.

There are several consequences of this that I see:

  • the input is meaningless, since it actually does not affect the salt used and encrypts () every time it generates a new salt.

  • you cannot configure the n, r, p workload manually or in any other way than the inconvenient min-time parameter. it is unsafe, but it is a rather inconvenient way to control the working factor.

  • after the decrypted call regenerates the key and compares it with hmac, it will reject everything there if your password is incorrect, but if it is correct, it will also continue to decrypt the data packet. This is a lot of additional work that an attacker should not do - they do not even need to output 64 bytes, but only 32, which are necessary to verify the signature. This problem does not make it unreliable, but doing work that your attacker does not is never desirable.

  • There is no way to adjust the salt key, size of the derivative key, etc. current values ​​are not so bad, but still not perfect.

  • the “maximum time” decryption limit is not true for password hashing — each time decryption is called, it evaluates the speed of your system and makes some guesses as to whether it can calculate the key for the maximum time — which is more overhead, your attacker doesn’t should do (see No. 3), but it also means that decryption can begin to reject passwords during heavy system boot.

  • I'm not sure why Colin Percival did not make part of the kdf code and parameter, choosing the part of the public api, but it introduces the explicitly marked "private" inside the source code, not even exported for binding. It makes me hesitate to just access it directly without much study.

In general, you need a good hash format that can store a screenshot and implementation, which provides a basic algorithm for choosing kdf and parameters. I am currently working on this for passlib , but he did not see much attention :(

Only on the bottom line, though - these instructions on the site are “good”, I would just use an empty line as the contents of the file and be aware of the extra overhead and problems.

+9
Dec 01 '12 at 20:17
source share

Both of these links were completely wrong. Do not worry with encrypt and decrypt : just use hash

KDF is not displayed directly, but hash is close enough. (Actually, it seems even better to me because it mixes the filling of the PBKDF2 sandwich.)

This sample code works with both python2.7 and python3.2. It uses PyCrypto, passlib and py-scrypt, but only requires py-scrypt.

You want to use a runtime comparison function, such as passlib.utils.consteq , to reduce temporary attacks.

You will also want to carefully select options. By default, logN = 14, r = 8, p = 1 means 1 "round" using 16 MB of memory. On the server, you probably want something more than 10.8.8 - less RAM, more CPU. You owe it to your equipment under the expected load.

+4
Sep 26 '13 at 14:26
source share



All Articles