[前][次][番号順一覧][スレッド一覧]

ruby-changes:21446

From: emboss <ko1@a...>
Date: Thu, 20 Oct 2011 22:49:27 +0900 (JST)
Subject: [ruby-changes:21446] emboss:r33495 (trunk): * ext/openssl/ossl_pkcs5.c: add note on timing attacks and general

emboss	2011-10-20 22:48:21 +0900 (Thu, 20 Oct 2011)

  New Revision: 33495

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33495

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

  Modified files:
    trunk/ChangeLog
    trunk/ext/openssl/ossl_pkcs5.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 33494)
+++ ChangeLog	(revision 33495)
@@ -1,3 +1,8 @@
+Thu Oct 20 22:38:53 2011  Martin Bosslet  <Martin.Bosslet@g...>
+
+	* ext/openssl/ossl_pkcs5.c: add note on timing attacks and general
+	  documentation.
+
 Thu Oct 20 21:19:15 2011  Naohisa Goto  <ngotogenome@g...>
 
 	* vm_eval.c (check_funcall): set array elements one-by-one to fix
@@ -9,7 +14,7 @@
 	* 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@g...>
+Thu Oct 20 12:28:22 2011  Martin Bosslet  <Martin.Bosslet@g...>
 
 	* test/openssl/test_pkcs5.rb: add RFC 6070 tests for PBKDF2 with
 	  HMAC-SHA1
Index: ext/openssl/ossl_pkcs5.c
===================================================================
--- ext/openssl/ossl_pkcs5.c	(revision 33494)
+++ ext/openssl/ossl_pkcs5.c	(revision 33495)
@@ -14,12 +14,12 @@
  *
  * === 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 @@
  *
  * === 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 @@
      * 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);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]