From 35a2bb7919159d5672c46e831d69b4fdbd33c955 Mon Sep 17 00:00:00 2001 From: Doug Alcorn Date: Mon, 22 Jul 2013 21:36:01 -0400 Subject: [PATCH] Parameterize the PBKDF2 algorithm in application config http://meta.discourse.org/t/sso-between-discourse-and-xmpp/8567/5 --- app/models/user.rb | 3 +-- config/application.rb | 1 + lib/pbkdf2.rb | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 59e84962f1b..c8b7f1e9f86 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -542,7 +542,7 @@ class User < ActiveRecord::Base end def hash_password(password, salt) - Pbkdf2.hash_password(password, salt, Rails.configuration.pbkdf2_iterations) + Pbkdf2.hash_password(password, salt, Rails.configuration.pbkdf2_iterations, Rails.configuration.pbkdf2_algorithm) end def add_trust_level @@ -674,4 +674,3 @@ end # index_users_on_username (username) UNIQUE # index_users_on_username_lower (username_lower) UNIQUE # - diff --git a/config/application.rb b/config/application.rb index 676f7bcf65e..4aa0a2f1b21 100644 --- a/config/application.rb +++ b/config/application.rb @@ -89,6 +89,7 @@ module Discourse # per https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet config.pbkdf2_iterations = 64000 + config.pbkdf2_algorithm = "sha256" # dumping rack lock cause the message bus does not work with it (throw :async, it catches Exception) # see: https://github.com/sporkrb/spork/issues/66 diff --git a/lib/pbkdf2.rb b/lib/pbkdf2.rb index 553841ef1b3..d080bb05a73 100644 --- a/lib/pbkdf2.rb +++ b/lib/pbkdf2.rb @@ -2,32 +2,32 @@ # # Also PBKDF2 monkey patches string ... don't like that at all # -# Happy to move back to PBKDF2 ruby gem provided: +# Happy to move back to PBKDF2 ruby gem provided: # # 1. It works on Ruby 2.0 -# 2. It works on 1.9.3 +# 2. It works on 1.9.3 # 3. It does not monkey patch string require 'openssl' require 'xor' class Pbkdf2 - - def self.hash_password(password, salt, iterations) - h = OpenSSL::Digest::Digest.new("sha256") - + def self.hash_password(password, salt, iterations, algorithm = "sha256") + + h = OpenSSL::Digest::Digest.new(algorithm) + u = ret = prf(h, password, salt + [1].pack("N")) - 2.upto(iterations) do + 2.upto(iterations) do u = prf(h, password, u) - ret.xor!(u) + ret.xor!(u) end ret.bytes.map{|b| ("0" + b.to_s(16))[-2..-1]}.join("") end - protected + protected # fallback xor in case we need it for jruby ... way slower def self.xor(x,y)