Sha256: 87c538a5e5d879546213d39b97dd49bbe254093d12e4c3e2679b30b935bf483e

Contents?: true

Size: 1.86 KB

Versions: 5

Compression:

Stored size: 1.86 KB

Contents

module OpenToken
  class PasswordKeyGenerator
    SHA1_DIGEST = OpenSSL::Digest::Digest.new('sha1')

    class << self
      def generate(password, cipher)
        salt = 0.chr * 8
        generate_impl(password, cipher, salt, 1000)
      end

      private
      def generate_block(password, salt, count, index)
        mac = salt
        mac += [index].pack("N")
      
        result = OpenSSL::HMAC.digest(SHA1_DIGEST, password, mac)
        cur = result
      
        i_count = 1
        while i_count < count
          i_count +=1
        
          cur = OpenSSL::HMAC.digest(SHA1_DIGEST, password, cur)
        
          20.times do |i|
            if RUBY_VERSION < "1.9"
              result[i] = result[i] ^ cur[i]
            else
              result[i] = (result[i].chr.ord ^ cur[i].chr.ord).chr
            end
          end
        end

        return result
      end
    
      def generate_impl(password, cipher, salt, iterations)
        return unless cipher.algorithm

        key_size = cipher.key_length / 8
        numblocks = key_size / 20
        numblocks += 1 if (key_size % 20) > 0
      
        # Generate the appropriate number of blocks and write their output to
        # the key bytes; note that it's important to start from 1 (vs. 0) as the
        # initial block number affects the hash. It's not clear that this fact
        # is stated explicitly anywhere, but without this approach, the generated
        # keys will not match up with test cases defined in RFC 3962.
        key_buffer_index = 0
        key = ""
      
        numblocks.times do |i|
          i+=1 # Previously zero based, needs to be 1 based
          block = generate_block(password, salt, iterations, i)
          len = [20, (key_size - key_buffer_index)].min
          key += block[0, len]
          key_buffer_index += len
        end
      
        return key
      end
    end

    end
end

Version data entries

5 entries across 5 versions & 2 rubygems

Version Path
opentoken-1.2.3 lib/opentoken/password_key_generator.rb
opentoken-newrelic-rails23-1.2.2 lib/opentoken-newrelic-rails23/password_key_generator.rb
opentoken-1.2.2 lib/opentoken/password_key_generator.rb
opentoken-1.2.1 lib/opentoken/password_key_generator.rb
opentoken-1.2.0 lib/opentoken/password_key_generator.rb