Method: OpenSSL::KDF.scrypt
- Defined in:
- ossl_kdf.c
.scrypt(pass, salt: , N: ,r:, p: , length: ) ⇒ aString
Derives a key from pass using given parameters with the scrypt password-based key derivation function. The result can be used for password storage.
scrypt is designed to be memory-hard and more secure against brute-force attacks using custom hardwares than alternative KDFs such as PBKDF2 or bcrypt.
The keyword arguments N, r and p can be used to tune scrypt. RFC 7914 (published on 2016-08, www.rfc-editor.org/rfc/rfc7914#section-2) states that using values r=8 and p=1 appears to yield good results.
See RFC 7914 (www.rfc-editor.org/rfc/rfc7914) for more information.
Parameters
- pass
-
Passphrase.
- salt
-
Salt.
- N
-
CPU/memory cost parameter. This must be a power of 2.
- r
-
Block size parameter.
- p
-
Parallelization parameter.
- length
-
Length in octets of the derived key.
Example
pass = "password"
salt = SecureRandom.random_bytes(16)
dk = OpenSSL::KDF.scrypt(pass, salt: salt, N: 2**14, r: 8, p: 1, length: 32)
p dk #=> "\xDA\xE4\xE2...\x7F\xA1\x01T"
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'ossl_kdf.c', line 103
static VALUE
kdf_scrypt(int argc, VALUE *argv, VALUE self)
{
VALUE pass, salt, opts, kwargs[5], str;
static ID kwargs_ids[5];
size_t len;
uint64_t N, r, p, maxmem;
if (!kwargs_ids[0]) {
kwargs_ids[0] = rb_intern_const("salt");
kwargs_ids[1] = rb_intern_const("N");
kwargs_ids[2] = rb_intern_const("r");
kwargs_ids[3] = rb_intern_const("p");
kwargs_ids[4] = rb_intern_const("length");
}
rb_scan_args(argc, argv, "1:", &pass, &opts);
rb_get_kwargs(opts, kwargs_ids, 5, 0, kwargs);
StringValue(pass);
salt = StringValue(kwargs[0]);
N = NUM2UINT64T(kwargs[1]);
r = NUM2UINT64T(kwargs[2]);
p = NUM2UINT64T(kwargs[3]);
len = NUM2LONG(kwargs[4]);
/*
* OpenSSL uses 32MB by default (if zero is specified), which is too small.
* Let's not limit memory consumption but just let malloc() fail inside
* OpenSSL. The amount is controllable by other parameters.
*/
maxmem = SIZE_MAX;
str = rb_str_new(0, len);
if (!EVP_PBE_scrypt(RSTRING_PTR(pass), RSTRING_LEN(pass),
(unsigned char *)RSTRING_PTR(salt), RSTRING_LEN(salt),
N, r, p, maxmem, (unsigned char *)RSTRING_PTR(str), len))
ossl_raise(eKDF, "EVP_PBE_scrypt");
return str;
}
|