require 'digest'puts Digest::MD5.hexdigest 'P@ssw0rd'
require 'digest'puts Digest::SHA1.hexdigest 'P@ssw0rd'
In SHA2 you have 2 ways to do it.
Way #1: By creating a new SHA2 hash object with a given bit length.
require 'digest'​# 1sha2_256 = Digest::SHA2.new(bitlen = 256) # bitlen could be 256, 384, 512sha2_256.hexdigest 'P@ssw0rd'​# 2Digest::SHA2.new(bitlen = 256).hexdigest 'P@ssw0rd'
Way #2: By Using the class directly
require 'digest'puts Digest::SHA256.hexdigest 'P@ssw0rd'puts Digest::SHA384.hexdigest 'P@ssw0rd'puts Digest::SHA512.hexdigest 'P@ssw0rd'
Bonus: Generate Linux-like Shadow password
require 'digest/sha2'password = 'P@ssw0rd'salt = rand(36**8).to_s(36)shadow_hash = password.crypt("$6$" + salt)
require 'openssl'​def split7(str)str.scan(/.{1,7}/)end​def gen_keys(str)split7(str).map do |str7|​bits = split7(str7.unpack("B*")[0]).inject('') do |ret, tkn|ret += tkn + (tkn.gsub('1', '').size % 2).to_send​[bits].pack("B*")endend​def apply_des(plain, keys)dec = OpenSSL::Cipher::DES.newkeys.map {|k|dec.key = kdec.encrypt.update(plain)}end​LM_MAGIC = "KGS!@\#$%"def lm_hash(password)keys = gen_keys password.upcase.ljust(14, "\0")apply_des(LM_MAGIC, keys).joinend​puts lm_hash "P@ssw0rd"
​Source | RubyNTLM​
require 'openssl'ntlmv1 = OpenSSL::Digest::MD4.hexdigest "P@ssw0rd".encode('UTF-16LE')puts ntlmv1
require 'openssl'ntlmv1 = OpenSSL::Digest::MD4.hexdigest "P@ssw0rd".encode('UTF-16LE')userdomain = "administrator".encode('UTF-16LE')ntlmv2 = OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmv1, userdomain)puts ntlmv2
puts "*" + Digest::SHA1.hexdigest(Digest::SHA1.digest('P@ssw0rd')).upcase
PostgreSQL hashes combined password and username then adds md5 in front of the hash
require 'digest/md5'puts 'md5' + Digest::MD5.hexdigest('P@ssw0rd' + 'admin')
To list all supported algorithms
require 'openssl'puts OpenSSL::Cipher.ciphers
To unserdatand the cipher naming (eg. AES-128-CBC
), it devided to 3 parts seperated by hyphen <Name>-<Key_length>-<Mode>
Symmetric encrption algorithms modes need 3 import data in order to work
Key (password)
Initial Vector (iv)
Data to encrypt (plain text)
require "openssl"​data = 'Rubyfu Secret Mission: Go Hack The World!'​# Setup the ciphercipher = OpenSSL::Cipher::AES.new('256-CBC') # Or use: OpenSSL::Cipher.new('AES-256-CBC')cipher.encrypt # Initializes the Cipher for encryption. (Must be called before key, iv, random_key, random_iv)key = cipher.random_key # If hard coded key, it must be 265-bits lengthiv = cipher.random_iv # Generate ivencrypted = cipher.update(data) + cipher.final # Finalize the encryption
decipher = OpenSSL::Cipher::AES.new('256-CBC') # Or use: OpenSSL::Cipher::Cipher.new('AES-256-CBC')decipher.decrypt # Initializes the Cipher for dencryption. (Must be called before key, iv, random_key, random_iv)decipher.key = key # Or generate secure random key: cipher.random_keydecipher.iv = iv # Generate ivplain = decipher.update(encrypted) + decipher.final # Finalize the dencryption
Resources
​OpenSSL::Cipher docs​
Caesar cipher is one of the oldest known encryption methods. It is very simple - it is just shifting an alphabet. Transformation is termed ROTN, where N is shift value and ROT is from "ROTATE" because this is a cyclic shift.
In Ruby, array rotation is mutter of using rotate() method. So all what we need is to have array of all alphabets rotate it and map it with the original given string.
#!/usb/bin/env ruby## Caesar cipher#​def caesar_cipher(string, shift=1)lowercase, uppercase = ('a'..'z').to_a, ('A'..'Z').to_alower = lowercase.zip(lowercase.rotate(shift)).to_hupper = uppercase.zip(uppercase.rotate(shift)).to_h​# One-liner: encrypter = ([*('a'..'z')].zip([*('a'..'z')].rotate(shift)) + [*('A'..'Z')].zip([*('A'..'Z')].rotate(shift))).to_hencrypter = lower.merge(upper)string.chars.map{|c| encrypter.fetch(c, c)}end​string = ARGV[0]1.upto(30) do |r|puts "ROT#{r}) " + caesar_cipher(string, r).joinend
result
$-> ruby caesar-cypher.rb FipmtiROT1) GjqnujROT2) HkrovkROT3) IlspwlROT4) JmtqxmROT5) KnurynROT6) LovszoROT7) MpwtapROT8) NqxubqROT9) OryvcrROT10) PszwdsROT11) QtaxetROT12) Rubyfu <--ROT13) SvczgvROT14) TwdahwROT15) UxebixROT16) VyfcjyROT17) WzgdkzROT18) XahelaROT19) YbifmbROT20) ZcjgncROT21) AdkhodROT22) BelipeROT23) CfmjqfROT24) DgnkrgROT25) EholshROT26) FipmtiROT27) GjqnujROT28) HkrovkROT29) IlspwlROT30) Jmtqxm
Sources:
​ |
Figure 1. Enigma machine diagram |
Plugboard = Hash[*('A'..'Z').to_a.shuffle.first(20)]Plugboard.merge!(Plugboard.invert)Plugboard.default_proc = proc { |hash, key| key }​def build_a_rotorHash[('A'..'Z').zip(('A'..'Z').to_a.shuffle)]end​Rotor_1, Rotor_2, Rotor_3 = build_a_rotor, build_a_rotor, build_a_rotor​Reflector = Hash[*('A'..'Z').to_a.shuffle]Reflector.merge!(Reflector.invert)​def input(string)rotor_1, rotor_2, rotor_3 = Rotor_1.dup, Rotor_2.dup, Rotor_3.dup​string.chars.each_with_index.map do |char, index|rotor_1 = rotate_rotor rotor_1rotor_2 = rotate_rotor rotor_2 if index % 25 == 0rotor_3 = rotate_rotor rotor_3 if index % 25*25 == 0​char = Plugboard[char]​char = rotor_1[char]char = rotor_2[char]char = rotor_3[char]​char = Reflector[char]​char = rotor_3.invert[char]char = rotor_2.invert[char]char = rotor_1.invert[char]​Plugboard[char]end.joinend​def rotate_rotor(rotor)Hash[rotor.map { |k,v| [k == 'Z' ? 'A' : k.next, v] }]end​plain_text = 'IHAVETAKENMOREOUTOFALCOHOLTHANALCOHOLHASTAKENOUTOFME'puts "Encrypted '#{plain_text}' to '#{encrypted = input(plain_text)}'"puts "Decrypted '#{encrypted}' to '#{decrypted = input(encrypted)}'"puts 'Success!' if plain_text == decrypted
​Source | Understanding the Enigma machine with 30 lines of Ruby​