1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/openssl/ossl_pkcs5.c: add note on timing attacks and general

documentation.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33495 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
emboss 2011-10-20 13:48:21 +00:00
parent 67db3f8177
commit 98490d1f71
2 changed files with 100 additions and 7 deletions

View file

@ -1,3 +1,8 @@
Thu Oct 20 22:38:53 2011 Martin Bosslet <Martin.Bosslet@googlemail.com>
* ext/openssl/ossl_pkcs5.c: add note on timing attacks and general
documentation.
Thu Oct 20 21:19:15 2011 Naohisa Goto <ngotogenome@gmail.com>
* vm_eval.c (check_funcall): set array elements one-by-one to fix
@ -9,7 +14,7 @@ Thu Oct 20 13:09:35 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
* include/ruby/defines.h (flush_register_windows): use software
trap on Debian Sparc 32-bit userspace. [Bug #5244]
Thu Oct 20 14:28:22 2011 Martin Bosslet <Martin.Bosslet@googlemail.com>
Thu Oct 20 12:28:22 2011 Martin Bosslet <Martin.Bosslet@googlemail.com>
* test/openssl/test_pkcs5.rb: add RFC 6070 tests for PBKDF2 with
HMAC-SHA1

View file

@ -14,12 +14,12 @@ VALUE ePKCS5;
*
* === Parameters
* * +pass+ - string
* * +salt+ - string
* * +iter+ - integer - should be greater than 1000. 2000 is better.
* * +salt+ - string - should be at least 8 bytes long.
* * +iter+ - integer - should be greater than 1000. 20000 is better.
* * +keylen+ - integer
* * +digest+ - a string or OpenSSL::Digest object.
*
* Available in OpenSSL 0.9.9?.
* Available in OpenSSL 0.9.4.
*
* Digests other than SHA1 may not be supported by other cryptography libraries.
*/
@ -56,11 +56,11 @@ ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE key
*
* === Parameters
* * +pass+ - string
* * +salt+ - string
* * +iter+ - integer - should be greater than 1000. 2000 is better.
* * +salt+ - string - should be at least 8 bytes long.
* * +iter+ - integer - should be greater than 1000. 20000 is better.
* * +keylen+ - integer
*
* This method is available almost any version OpenSSL.
* This method is available in almost any version of OpenSSL.
*
* Conforms to rfc2898.
*/
@ -93,7 +93,95 @@ Init_ossl_pkcs5()
* Password-based Encryption
*
*/
#if 0
mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
#endif
/* Document-class: OpenSSL::PKCS5
*
* Provides password-based encryption functionality based on PKCS#5.
* Typically used for securely deriving arbitrary length symmetric keys
* to be used with an OpenSSL::Cipher from passwords. Another use case
* is for storing passwords: Due to the ability to tweak the effort of
* computation by increasing the iteration count, computation can be
* slowed down artificially in order to render possible attacks infeasible.
*
* PKCS5 offers support for PBKDF2 with an OpenSSL::Digest::SHA1-based
* HMAC, or an arbitrary Digest if the underlying version of OpenSSL
* already supports it (>= 0.9.4).
*
* === Parameters
* ==== Password
* Typically an arbitrary String that represents the password to be used
* for deriving a key.
* ==== Salt
* Prevents attacks based on dictionaries of common passwords. It is a
* public value that can be safely stored along with the password (e.g.
* if PBKDF2 is used for password storage). For maximum security, a fresh,
* random salt should be generated for each stored password. According
* to PKCS#5, a salt should be at least 8 bytes long.
* ==== Iteration Count
* Allows to tweak the length that the actual computation will take. The
* larger the iteration count, the longer it will take.
* ==== Key Length
* Specifies the length in bytes of the output that will be generated.
* Typically, the key length should be larger than or equal to the output
* length of the underlying digest function, otherwise an attacker could
* simply try to brute-force the key. According to PKCS#5, security is
* limited by the output length of the underlying digest function, i.e.
* security is not improved if a key length strictly larger than the
* digest output length is chosen. Therefore, when using PKCS5 for
* password storage, it suffices to store values equal to the digest
* output length, nothing is gained by storing larger values.
*
* == Examples
* === Generating a 128 bit key for a Cipher (e.g. AES)
* pass = "secret"
* salt = OpenSSL::Random.random_bytes(16)
* iter = 20000
* key_len = 16
* key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, key_len)
*
* === Storing Passwords
* pass = "secret"
* salt = OpenSSL::Random.random_bytes(16) #store this with the generated value
* iter = 20000
* digest = OpenSSL::Digest::SHA256.new
* len = digest.digest_length
* #the final value to be stored
* value = OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, iter, len, digest)
*
* === Important Note on Checking Passwords
* When comparing passwords provided by the user with previously stored
* values, a common mistake made is comparing the two values using "==".
* Typically, "==" short-circuits on evaluation, and is therefore
* vulnerable to timing attacks. The proper way is to use a method that
* always takes the same amount of time when comparing two values, thus
* not leaking any information to potential attackers. To compare two
* values, the following could be used:
* def eql_time_cmp(a, b)
* unless a.length == b.length
* return false
* end
* cmp = b.bytes.to_a
* result = 0
* a.bytes.each_with_index {|c,i|
* result |= c ^ cmp[i]
* }
* result == 0
* end
* Please note that the premature return in case of differing lengths
* typically does not leak valuable information - when using PKCS#5, the
* length of the values to be compared is of fixed size.
*/
mPKCS5 = rb_define_module_under(mOSSL, "PKCS5");
/* Document-class: OpenSSL::PKCS5::PKCS5Error
*
* Generic Exception class that is raised if an error occurs during a
* computation.
*/
ePKCS5 = rb_define_class_under(mPKCS5, "PKCS5Error", eOSSLError);
rb_define_module_function(mPKCS5, "pbkdf2_hmac", ossl_pkcs5_pbkdf2_hmac, 5);