Created
October 17, 2019 04:06
-
-
Save yukithm/5a850e12fa0138fbf2cfdbbaaadbc7e4 to your computer and use it in GitHub Desktop.
[ruby] LDAP password utility
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
require 'digest/md5' | |
require 'digest/sha1' | |
require 'base64' | |
module Example | |
class LDAP | |
# LDAPパスワード生成クラス | |
class Password | |
# LDAP用にハッシュ化されたパスワードを生成する | |
# | |
# @param [Symbol] type 種類(:cleartext, :crypt, :md5, :smd5, :sha, :ssha) | |
# @param [String] str 平文パスワード | |
# @param [String] salt salt | |
# @return [String] ハッシュ化されたパスワード | |
# @raise [RuntimeError] typeがサポートされていない種類の場合 | |
# @see Net::LDAP::Password.generate | |
def self.generate(type, str, salt = nil) | |
unless salt | |
srand | |
salt = (rand * 1000).to_i.to_s | |
end | |
case type | |
when nil, :cleartext | |
attribute_value = str | |
when :crypt | |
attribute_value = '{CRYPT}' + str.crypt(salt) | |
when :md5 | |
attribute_value = '{MD5}' + Base64.encode64(Digest::MD5.digest(str)).chomp! | |
when :smd5 | |
attribute_value = '{SMD5}' + Base64.encode64(Digest::MD5.digest(str + salt) + salt).chomp! | |
when :sha | |
attribute_value = '{SHA}' + Base64.encode64(Digest::SHA1.digest(str)).chomp! | |
when :ssha | |
attribute_value = '{SSHA}' + Base64.encode64(Digest::SHA1.digest(str + salt) + salt).chomp! | |
else | |
fail "Unsupported password-hash type (#{type})" | |
end | |
attribute_value | |
end | |
# パスワードを照合する | |
# | |
# @param [String] password 平文パスワード | |
# @param [String] スキーム付きのハッシュ化されたパスワード | |
# @return [Boolean] | |
def self.verify(password, hash_with_scheme) | |
scheme, _, salt = split_hash(hash_with_scheme) | |
hash_with_scheme == generate(scheme, password, salt) | |
end | |
private | |
# スキーム付きのハッシュをスキーム、ハッシュ値、saltに分解する | |
def self.split_hash(hash_with_scheme) | |
if /\A\{([^}]+)\}(.*)\z/ =~ hash_with_scheme | |
scheme = Regexp.last_match[1].downcase.to_sym | |
scheme = nil if scheme == :cleartext | |
hash = Regexp.last_match[2] | |
salt = nil | |
case scheme | |
when :smd5 | |
hash, salt = Base64.decode64(hash).unpack('a16a*') | |
when :ssha | |
hash, salt = Base64.decode64(hash).unpack('a20a*') | |
when :crypt | |
hash, salt = hash, hash | |
end | |
[scheme, hash, salt] | |
else | |
[nil, hash, nil] | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment