# # This module provides a framework for message digest libraries. # # You may want to look at OpenSSL::Digest as it supports more algorithms. # # A cryptographic hash function is a procedure that takes data and returns a # fixed bit string: the hash value, also known as *digest*. Hash functions are # also called one-way functions, it is easy to compute a digest from a message, # but it is infeasible to generate a message from a digest. # # ## Examples # # require 'digest' # # # Compute a complete digest # Digest::SHA256.digest 'message' #=> "\xABS\n\x13\xE4Y..." # # sha256 = Digest::SHA256.new # sha256.digest 'message' #=> "\xABS\n\x13\xE4Y..." # # # Other encoding formats # Digest::SHA256.hexdigest 'message' #=> "ab530a13e459..." # Digest::SHA256.base64digest 'message' #=> "q1MKE+RZFJgr..." # # # Compute digest by chunks # md5 = Digest::MD5.new # md5.update 'message1' # md5 << 'message2' # << is an alias for update # # md5.hexdigest #=> "94af09c09bb9..." # # # Compute digest for a file # sha256 = Digest::SHA256.file 'testfile' # sha256.hexdigest # # Additionally digests can be encoded in "bubble babble" format as a sequence of # consonants and vowels which is more recognizable and comparable than a # hexadecimal digest. # # require 'digest/bubblebabble' # # Digest::SHA256.bubblebabble 'message' #=> "xopoh-fedac-fenyh-..." # # See the bubble babble specification at # http://web.mit.edu/kenta/www/one/bubblebabble/spec/jrtrjwzi/draft-huima-01.txt # . # # ## Digest algorithms # # Different digest algorithms (or hash functions) are available: # # MD5 # : See RFC 1321 The MD5 Message-Digest Algorithm # RIPEMD-160 # : As Digest::RMD160. See # http://homes.esat.kuleuven.be/~bosselae/ripemd160.html. # SHA1 # : See FIPS 180 Secure Hash Standard. # SHA2 family # : See FIPS 180 Secure Hash Standard which defines the following algorithms: # * SHA512 # * SHA384 # * SHA256 # # # # The latest versions of the FIPS publications can be found here: # http://csrc.nist.gov/publications/PubsFIPS.html. # module Digest # # Returns a BubbleBabble encoded version of a given *string*. # def self.bubblebabble: (String) -> String def self.const_missing: (Symbol name) -> singleton(::Digest::Base) # # Generates a hex-encoded version of a given *string*. # def self.hexencode: (String) -> String private def bubblebabble: (String) -> String def hexencode: (String) -> String end # # A mutex for Digest(). # Digest::REQUIRE_MUTEX: Thread::Mutex # # This module provides instance methods for a digest implementation object to # calculate message digest values. # module Digest::Instance public # # Updates the digest using a given *string* and returns self. # # The update() method and the left-shift operator are overridden by each # implementation subclass. (One should be an alias for the other) # def <<: (String) -> self # # If a string is given, checks whether it is equal to the hex-encoded hash value # of the digest object. If another digest instance is given, checks whether # they have the same hash value. Otherwise returns false. # def ==: (::Digest::Instance | String) -> bool # # If none is given, returns the resulting hash value of the digest in a base64 # encoded form, keeping the digest's state. # # If a `string` is given, returns the hash value for the given `string` in a # base64 encoded form, resetting the digest to the initial state before and # after the process. # # In either case, the return value is properly padded with '=' and contains no # line feeds. # def base64digest: (?String? str) -> String # # Returns the resulting hash value and resets the digest to the initial state. # def base64digest!: () -> String # # Returns the block length of the digest. # # This method is overridden by each implementation subclass. # def block_length: () -> Integer # # Returns the resulting hash value in a Bubblebabble encoded form. # def bubblebabble: () -> String # # If none is given, returns the resulting hash value of the digest, keeping the # digest's state. # # If a *string* is given, returns the hash value for the given *string*, # resetting the digest to the initial state before and after the process. # def digest: (?String) -> String # # Returns the resulting hash value and resets the digest to the initial state. # def digest!: () -> String # # Returns the length of the hash value of the digest. # # This method should be overridden by each implementation subclass. If not, # digest_obj.digest().length() is returned. # def digest_length: () -> Integer # # Updates the digest with the contents of a given file *name* and returns self. # def file: (String name) -> self # # If none is given, returns the resulting hash value of the digest in a # hex-encoded form, keeping the digest's state. # # If a *string* is given, returns the hash value for the given *string* in a # hex-encoded form, resetting the digest to the initial state before and after # the process. # def hexdigest: (?String) -> String # # Returns the resulting hash value in a hex-encoded form and resets the digest # to the initial state. # def hexdigest!: () -> String # # Creates a printable version of the digest object. # def inspect: () -> String # # Returns digest_obj.digest_length(). # def length: () -> Integer # # Returns a new, initialized copy of the digest object. Equivalent to # digest_obj.clone().reset(). # def new: () -> ::Digest::Base # # Resets the digest to the initial state and returns self. # # This method is overridden by each implementation subclass. # def reset: () -> self # # Returns digest_obj.digest_length(). # def size: () -> Integer # # Returns digest_obj.hexdigest(). # def to_s: () -> String # # Updates the digest using a given *string* and returns self. # # The update() method and the left-shift operator are overridden by each # implementation subclass. (One should be an alias for the other) # def update: (String) -> self private # # Finishes the digest and returns the resulting hash value. # # This method is overridden by each implementation subclass and often made # private, because some of those subclasses may leave internal data # uninitialized. Do not call this method from outside. Use #digest!() instead, # which ensures that internal data be reset for security reasons. # def finish: () -> self end # # This module stands as a base class for digest implementation classes. # class Digest::Class include ::Digest::Instance # # Returns the base64 encoded hash value of a given *string*. The return value # is properly padded with '=' and contains no line feeds. # def self.base64digest: (String str, *untyped) -> String # # Returns the BubbleBabble encoded hash value of a given *string*. # def self.bubblebabble: (String, *untyped) -> String # # Returns the hash value of a given *string*. This is equivalent to # Digest::Class.new(*parameters).digest(string), where extra *parameters*, if # any, are passed through to the constructor and the *string* is passed to # #digest(). # def self.digest: (String, *untyped) -> String # # Creates a digest object and reads a given file, *name*. Optional arguments are # passed to the constructor of the digest class. # # p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest # # => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534" # def self.file: (String name, *untyped) -> ::Digest::Class # # Returns the hex-encoded hash value of a given *string*. This is almost # equivalent to Digest.hexencode(Digest::Class.new(*parameters).digest(string)). # def self.hexdigest: (String, *untyped) -> String private def initialize: () -> self end # # This abstract class provides a common interface to message digest # implementation classes written in C. # # ## Write a Digest subclass in C # Digest::Base provides a common interface to message digest classes written in # C. These classes must provide a struct of type rb_digest_metadata_t: # typedef int (*rb_digest_hash_init_func_t)(void *); # typedef void (*rb_digest_hash_update_func_t)(void *, unsigned char *, size_t); # typedef int (*rb_digest_hash_finish_func_t)(void *, unsigned char *); # # typedef struct { # int api_version; # size_t digest_len; # size_t block_len; # size_t ctx_size; # rb_digest_hash_init_func_t init_func; # rb_digest_hash_update_func_t update_func; # rb_digest_hash_finish_func_t finish_func; # } rb_digest_metadata_t; # # This structure must be set as an instance variable named `metadata` (without # the +@+ in front of the name). By example: # static const rb_digest_metadata_t sha1 = { # RUBY_DIGEST_API_VERSION, # SHA1_DIGEST_LENGTH, # SHA1_BLOCK_LENGTH, # sizeof(SHA1_CTX), # (rb_digest_hash_init_func_t)SHA1_Init, # (rb_digest_hash_update_func_t)SHA1_Update, # (rb_digest_hash_finish_func_t)SHA1_Finish, # }; # # rb_ivar_set(cDigest_SHA1, rb_intern("metadata"), # Data_Wrap_Struct(0, 0, 0, (void *)&sha1)); # class Digest::Base < Digest::Class public # # Update the digest using given *string* and return `self`. # def <<: (String) -> self # # Return the block length of the digest in bytes. # def block_length: () -> Integer # # Return the length of the hash value in bytes. # def digest_length: () -> Integer # # Reset the digest to its initial state and return `self`. # def reset: () -> self # # Update the digest using given *string* and return `self`. # def update: (String) -> self private def finish: () -> String def initialize_copy: (::Digest::Base) -> self end # # A class for calculating message digests using the SHA-1 Secure Hash Algorithm # by NIST (the US' National Institute of Standards and Technology), described in # FIPS PUB 180-1. # # See Digest::Instance for digest API. # # SHA-1 calculates a digest of 160 bits (20 bytes). # # ## Examples # require 'digest' # # # Compute a complete digest # Digest::SHA1.hexdigest 'abc' #=> "a9993e36..." # # # Compute digest by chunks # sha1 = Digest::SHA1.new # =># # sha1.update "ab" # sha1 << "c" # alias for #update # sha1.hexdigest # => "a9993e36..." # # # Use the same object to compute another digest # sha1.reset # sha1 << "message" # sha1.hexdigest # => "6f9b9af3..." # class Digest::SHA1 < Digest::Base end # # A class for calculating message digests using the MD5 Message-Digest Algorithm # by RSA Data Security, Inc., described in RFC1321. # # MD5 calculates a digest of 128 bits (16 bytes). # # ## Examples # require 'digest' # # # Compute a complete digest # Digest::MD5.hexdigest 'abc' #=> "90015098..." # # # Compute digest by chunks # md5 = Digest::MD5.new # =># # md5.update "ab" # md5 << "c" # alias for #update # md5.hexdigest # => "90015098..." # # # Use the same object to compute another digest # md5.reset # md5 << "message" # md5.hexdigest # => "78e73102..." # class Digest::MD5 < Digest::Base end # # A class for calculating message digests using RIPEMD-160 cryptographic hash # function, designed by Hans Dobbertin, Antoon Bosselaers, and Bart Preneel. # # RMD160 calculates a digest of 160 bits (20 bytes). # # ## Examples # require 'digest' # # # Compute a complete digest # Digest::RMD160.hexdigest 'abc' #=> "8eb208f7..." # # # Compute digest by chunks # rmd160 = Digest::RMD160.new # =># # rmd160.update "ab" # rmd160 << "c" # alias for #update # rmd160.hexdigest # => "8eb208f7..." # # # Use the same object to compute another digest # rmd160.reset # rmd160 << "message" # rmd160.hexdigest # => "1dddbe1b..." # class Digest::RMD160 < Digest::Base end class Digest::SHA256 < Digest::Base end class Digest::SHA384 < Digest::Base end class Digest::SHA512 < Digest::Base end %a{annotate:rdoc:skip} class Object # # Returns a Digest subclass by `name` in a thread-safe manner even when # on-demand loading is involved. # # require 'digest' # # Digest("MD5") # # => Digest::MD5 # # Digest(:SHA256) # # => Digest::SHA256 # # Digest(:Foo) # # => LoadError: library not found for class Digest::Foo -- digest/foo # def Digest: (String | Symbol name) -> singleton(::Digest::Base) end