Practical Cryptography for Developers
master-zh
master-zh
  • Welcome
  • 前言
  • 密码学——概述
  • 哈希函数
    • 加密哈希和碰撞
    • 哈希函数:应用场景
    • 安全哈希算法
    • 哈希函数——示例
    • 练习:计算哈希值
    • 工作量证明(Proof-of-Work)哈希函数
  • MAC 和密钥派生
    • HMAC 与密钥派生
    • HMAC 计算——示例
    • 练习:计算 HMAC
    • KDF: Deriving Key from Password
    • PBKDF2
    • Modern Key Derivation Functions
    • Scrypt
    • Bcrypt
    • Linux crypt()
    • Argon2
    • Secure Password Storage
    • Exercises: Password Encryption
  • Secure Random Generators
    • Pseudo-Random Numbers - Examples
    • Secure Random Generators (CSPRNG)
    • Exercises: Pseudo-Random Generator
  • Key Exchange and DHKE
    • Diffie–Hellman Key Exchange
    • DHKE - Examples
    • Exercises: DHKE Key Exchange
  • Encryption: Symmetric and Asymmetric
  • Symmetric Key Ciphers
    • Cipher Block Modes
    • Popular Symmetric Algorithms
    • The AES Cipher - Concepts
    • AES Encrypt / Decrypt - Examples
    • Ethereum Wallet Encryption
    • Exercises: AES Encrypt / Decrypt
    • ChaCha20-Poly1305
    • Exercises: ChaCha20-Poly1305
  • Asymmetric Key Ciphers
    • The RSA Cryptosystem - Concepts
    • RSA Encrypt / Decrypt - Examples
    • Exercises: RSA Encrypt / Decrypt
    • Elliptic Curve Cryptography (ECC)
    • ECDH Key Exchange
    • ECDH Key Exchange - Examples
    • Exercises: ECDH Key Exchange
    • ECC Encryption / Decryption
    • ECIES Hybrid Encryption Scheme
    • ECIES Encryption - Example
    • Exercises: ECIES Encrypt / Decrypt
  • Digital Signatures
    • RSA Signatures
    • RSA: Sign / Verify - Examples
    • Exercises: RSA Sign and Verify
    • ECDSA: Elliptic Curve Signatures
    • ECDSA: Sign / Verify - Examples
    • Exercises: ECDSA Sign and Verify
    • EdDSA and Ed25519
    • EdDSA: Sign / Verify - Examples
    • Exercises: EdDSA Sign and Verify
  • Quantum-Safe Cryptography
    • Quantum-Safe Signatures - Example
    • Quantum-Safe Key Exchange - Example
    • Quantum-Safe Asymmetric Encryption - Example
  • More Cryptographic Concepts
    • Digital Certificates - Example
    • TLS - Example
    • One-Time Passwords (OTP) - Example
  • Crypto Libraries for Developers
    • JavaScript Crypto Libraries
    • Python Crypto Libraries
    • C# Crypto Libraries
    • Java Crypto Libraries
  • Conclusion
Powered by GitBook
On this page
  • Scrypt Parameters
  • Scrypt - Example
  • Scrypt Calculation in Python - Example
  • Storing Algorithm Settings + Salt + Hash Together
  • When to Use Scrypt?

Was this helpful?

  1. MAC 和密钥派生

Scrypt

PreviousModern Key Derivation FunctionsNextBcrypt

Last updated 5 years ago

Was this helpful?

() is a strong cryptographic key-derivation function (KDF). It is memory-intensive, designed to prevent GPU, ASIC and FPGA attacks (highly efficient password cracking hardware).

The Scrypt algorithm takes several input parameters and produces the derived key as output:

key = Scrypt(password, salt, N, r, p, derived-key-len)

Scrypt Parameters

The Scrypt config parameters are:

  • N – iterations count (affects memory and CPU usage), e.g. 16384 or 2048

  • r – block size (affects memory and CPU usage), e.g. 8

  • p – parallelism factor (threads to run in parallel - affects the memory, CPU usage), usually 1

  • password– the input password (8-10 chars minimal length is recommended)

  • salt – securely-generated random bytes (64 bits minimum, 128 bits recommended)

  • derived-key-length - how many bytes to generate as output, e.g. 32 bytes (256 bits)

The memory in Scrypt is accessed in strongly dependent order at each step, so the memory access speed is the algorithm's bottleneck. The memory required to compute Scrypt key derivation is calculated as follows:

Memory required = 128 * N * r * p bytes

Example: e.g. 128 * N * r * p = 128 * 16384 * 8 * 1 = 16 MB (or 128 * N * r * p = 128 * 2048 * 8 * 1 = 2 MB)

Choosing parameters depends on how much you want to wait and what level of security (password cracking resistance) do you want to achieve:

  • Sample parameters for interactive login: N=16384, r=8, p=1 (RAM = 2 MB). For interactive login you most probably do not want to wait more than a 0.5 seconds, so the computations should be very slow. Also at the server side, it is usual that many users can login in the same time, so slow Scrypt computation will slow down the entire system.

  • Sample parameters for file encryption: N=1048576, r=8, p=1 (RAM = 1 GB). When you encrypt your hard drive, you will unlock the encrypted data in rare cases, usually not more than 2-3 times per day, so you may want to wait for 2-3 seconds to increase the security.

You can perform tests and choose the Scrypt parameters yourself during the design and development of your app or system. Always try to use the fastest possible implementation of Scrypt for your language and platform, because crackers will definitely use it. Some implementations (e.g. in Python) may be 100 times slower than the fastest ones!

In the MyEtherWallet crypto wallet, the default Scrypt parameters are N=8192, r=8, p=1. These settings are not strong enough for crypto wallets, but this is how it works. The solution is to use long and complex password to avoid password cracking attacks.

Scrypt - Example

Scrypt Calculation in Python - Example

Now, we shall write some code in Python to derive a key from a password using the Scrypt algorithm.

First, install the Python package scrypt using the command:

pip install scrypt

Note that the scrypt package depends on OpenSSL, so first install it in its default location (e.g. in C:\OpenSSL-Win64 in Windows), then install the scrypt Python package.

Now, after the scrypt package is successfully installed, write the Python code to calculate a Scrypt hash: (Note, we have chosen smaller number for iterations count. We did that just to increase the following example execution speed. In common usage, a higher iterations count is recommended, e.g. 16384 - see above.)

import pyscrypt

salt = b'aa1f2d3f4d23ac44e9c5a6c3d8f9ee8c'
passwd = b'p@$Sw0rD~7'
key = pyscrypt.hash(passwd, salt, 2048, 8, 1, 32)
print("Derived key:", key.hex())

The Scrypt calculation function takes several input parameters: the password (bytes sequence), the salt (bytes sequence), iterations count, block size for each iteration, parallelism factor and the output key length (number of bytes for the derived key).

The output from the above code execution is the following:

Derived key: b'e813a6f6ccc4e9110193bf9efb7c0a489d76655f9e36629dccbeaf2a73bc0c6f'

Try to change the number of iterations or the block size and see how they affect the execution time. Have in mind that the above Python implementation is not very fast. You may find fast Scrypt implementation in Internet.

Storing Algorithm Settings + Salt + Hash Together

In many applications, frameworks and tools, Scrypt encrypted passwords are stored together with the algorithm settings and salt, into a single string (in certain format), consisting of several parts, separated by $ character. For example, the password p@ss~123 can be stored in the Scrypt standard format like this (several examples are given, to make the pattern apparent):

16384$8$1$kytG1MHY1KU=$afc338d494dc89be40e317788e3cd9166d066709db0e6481f0801bd918710f46
16384$8$1$5gFGlElztY0=$560f6229356c281a525fad4e2fc4c209bb55c21dec789381335a32bb84888a5a
32768$8$4$VGhlIHF1aWo=$54d657cec8b3aaca675b407e790bccf1dddb0a23665cd5f994820a736d4b58ba

When to Use Scrypt?

When configured properly Scrypt is considered a highly secure KDF function, so you can use it as general purpose password to key derivation algorithm, e.g. when encrypting wallets, files or app passwords.

You can play with Scrypt key derivation online here: .

Run the above code example: .

Scrypt
RFC 7914
https://8gwifi.org/scrypt.jsp
https://repl.it/@nakov/Scrypt-in-Python