# class Crypto::Bcrypt

- Crypto::Bcrypt
- Reference
- Object

##
Overview

Pure Crystal implementation of the Bcrypt algorithm by Niels Provos and David Mazières, as presented at USENIX in 1999.

The algorithm has a maximum password length limit of 71 characters (see this comment on stackoverflow).

Refer to `Crypto::Bcrypt::Password` for a higher level interface.

About the Cost

Bcrypt, like the PBKDF2 or scrypt ciphers, are designed to be slow, so generating rainbow tables or cracking passwords is nearly impossible. Yet, computers are always getting faster and faster, so the actual cost must be incremented every once in a while. Always use the maximum cost that is tolerable, performance wise, for your application. Be sure to test and select this based on your server, not your home computer.

Last but not least: beware of denial of services! Always protect your application using an external strategy (eg: rate limiting), otherwise endpoints that verifies bcrypt hashes will be an easy target.

NOTE To use `Bcrypt`, you must explicitly import it with `require "crypto/bcrypt"`

##
Defined in:

crypto/bcrypt.cr

##
Constant Summary

COST_RANGE = `4..31`
DEFAULT_COST = `11`
PASSWORD_RANGE = `1..72`
SALT_SIZE = `16`

##
Constructors

- .new(password : String, salt : String, cost : Int32 = DEFAULT_COST) : self

  Creates a new `Crypto::Bcrypt` object from the given password with salt and cost.

- .new(password : Bytes, salt : Bytes, cost : Int32 = DEFAULT_COST)

  Creates a new `Crypto::Bcrypt` object from the given password with salt in bytes and cost.

##
Class Method Summary

- .hash_secret(password : String, cost : Int32 = DEFAULT_COST) : String

  Hashes the password using bcrypt algorithm using salt obtained via `Random::Secure.random_bytes(SALT_SIZE)`.

##
Instance Method Summary

- #cost : Int32
- #digest : Bytes
- #inspect(io : IO) : Nil

  Appends a String representation of this object which includes its class name, its object address and the values of all instance variables.

- #password : Bytes
- #salt : Bytes
- #to_s(io : IO) : Nil

  Appends a short String representation of this object which includes its class name and its object address.

- #to_s : String

  Returns a nicely readable and concise string representation of this object, typically intended for users.

- #to_slice(*args, **options)
- #to_slice(*args, **options, &)

### Instance methods inherited from class `Reference`

==(other : self)
==(other : JSON::Any)
==(other : YAML::Any)
==(other) ==, dup dup, hash(hasher) hash, initialize initialize, inspect(io : IO) : Nil inspect, object_id : UInt64 object_id, pretty_print(pp) : Nil pretty_print, same?(other : Reference) : Bool
same?(other : Nil) same?, to_s(io : IO) : Nil to_s

### Constructor methods inherited from class `Reference`

new new, unsafe_construct(address : Pointer, *args, **opts) : self unsafe_construct

### Class methods inherited from class `Reference`

pre_initialize(address : Pointer) pre_initialize

### Instance methods inherited from class `Object`

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other) ===, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash hash, in?(collection : Object) : Bool
in?(*values : Object) : Bool in?, inspect(io : IO) : Nil
inspect : String inspect, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String to_json, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil to_pretty_json, to_s(io : IO) : Nil
to_s : String to_s, to_yaml(io : IO) : Nil
to_yaml : String to_yaml, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

### Class methods inherited from class `Object`

from_json(string_or_io : String | IO, root : String)
from_json(string_or_io : String | IO) from_json, from_yaml(string_or_io : String | IO) from_yaml

### Macros inherited from class `Object`

class_getter(*names, &block) class_getter, class_getter!(*names) class_getter!, class_getter?(*names, &block) class_getter?, class_property(*names, &block) class_property, class_property!(*names) class_property!, class_property?(*names, &block) class_property?, class_setter(*names) class_setter, def_clone def_clone, def_equals(*fields) def_equals, def_equals_and_hash(*fields) def_equals_and_hash, def_hash(*fields) def_hash, delegate(*methods, to object) delegate, forward_missing_to(delegate) forward_missing_to, getter(*names, &block) getter, getter!(*names) getter!, getter?(*names, &block) getter?, property(*names, &block) property, property!(*names) property!, property?(*names, &block) property?, setter(*names) setter

##
Constructor Detail

def self.new(password : String, salt : String, cost : Int32 = DEFAULT_COST) : self #

Creates a new `Crypto::Bcrypt` object from the given password with salt and cost.

salt must be a base64 encoded string of 16 bytes (128 bits).

    require "crypto/bcrypt"

    password = Crypto::Bcrypt.new "secret", "CJjskaIgXR32DJYjVyNPdA=="
    password.to_s # => "$2a$11$CJjskaIgXR32DJYjVyNPd./ajV3Yj6GiP0IAI6rR.fMnjRgozqqqG"

def self.new(password : Bytes, salt : Bytes, cost : Int32 = DEFAULT_COST) #

Creates a new `Crypto::Bcrypt` object from the given password with salt in bytes and cost.

    require "crypto/bcrypt"

    password = Crypto::Bcrypt.new "secret".to_slice, "salt_of_16_chars".to_slice
    password.digest

##
Class Method Detail

def self.hash_secret(password : String, cost : Int32 = DEFAULT_COST) : String #

Hashes the password using bcrypt algorithm using salt obtained via `Random::Secure.random_bytes(SALT_SIZE)`.

    require "crypto/bcrypt"

    Crypto::Bcrypt.hash_secret "secret"

##
Instance Method Detail

def cost : Int32 #
def digest : Bytes #
def inspect(io : IO) : Nil #
Description copied from class Reference

Appends a String representation of this object which includes its class name, its object address and the values of all instance variables.

    class Person
      def initialize(@name : String, @age : Int32)
      end
    end

    Person.new("John", 32).inspect # => #<Person:0x10fd31f20 @name="John", @age=32>

def password : Bytes #
def salt : Bytes #
def to_s(io : IO) : Nil #
Description copied from class Reference

Appends a short String representation of this object which includes its class name and its object address.

    class Person
      def initialize(@name : String, @age : Int32)
      end
    end

    Person.new("John", 32).to_s # => #<Person:0x10a199f20>

def to_s : String #
Description copied from class Object

Returns a nicely readable and concise string representation of this object, typically intended for users.

This method should usually not be overridden. It delegates to `#to_s(IO)` which can be overridden for custom implementations.

Also see `#inspect`.

def to_slice(*args, **options) #
def to_slice(*args, **options, &) #