bcrypt.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
3 //
4 // MIT License
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in all
14 // copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 // SOFTWARE.
23 //---------------------------------------------------------------------------//
24 
25 #ifndef CRYPTO3_PASSHASH_BCRYPT_HPP
26 #define CRYPTO3_PASSHASH_BCRYPT_HPP
27 
29 
30 #include <nil/crypto3/utilities/types.hpp>
31 
32 #include <string>
33 
34 namespace nil {
35  namespace crypto3 {
36  namespace block {
37  class blowfish;
38  }
39  namespace passhash {
67  template<typename BlockCipher = block::blowfish>
68  class bcrypt {
70 
71  public:
73 
109  static void generate(const std::string &pass, const std::vector<uint8_t> &salt, uint16_t work_factor) {
110  // Include the trailing NULL byte, so we need c_str() not data()
111  blowfish.eks_key_schedule(cast_char_ptr_to_uint8(pass.c_str()), pass.length() + 1, salt.data(),
112  work_factor);
113 
114  std::vector<uint8_t> ctext(BCRYPT_MAGIC, BCRYPT_MAGIC + 8 * 3);
115 
116  for (size_t i = 0; i != 64; ++i) {
117  blowfish.encrypt_n(ctext.data(), ctext.data(), 3);
118  }
119 
120  std::string salt_b64 = bcrypt_base64_encode(salt.data(), salt.size());
121 
122  std::string work_factor_str = std::to_string(work_factor);
123  if (work_factor_str.length() == 1) {
124  work_factor_str = "0" + work_factor_str;
125  }
126 
127  return "$2a$" + work_factor_str + "$" + salt_b64.substr(0, 22)
128  + bcrypt_base64_encode(ctext.data(), ctext.size() - 1);
129  }
130 
138  static bool check(const std::string &pass, const std::string &hash) const {
139  if (hash.size() != 60 || hash[0] != '$' || hash[1] != '2' || hash[2] != 'a' || hash[3] != '$'
140  || hash[6] != '$') {
141  return false;
142  }
143 
144  const uint16_t workfactor = to_uint16(hash.substr(4, 2));
145 
146  const std::vector<uint8_t> salt = bcrypt_base64_decode(hash.substr(7, 22));
147  if (salt.size() != 16) {
148  return false;
149  }
150 
151  const std::string compare = generate(pass, salt, workfactor);
152 
153  return same_mem(hash.data(), compare.data(), compare.size());
154  }
155  };
156  } // namespace passhash
157 
166  template<typename UniformRandomGenerator>
167  std::string generate_bcrypt(const std::string &password, UniformRandomGenerator &rng,
168  uint16_t work_factor = 10) {
169  return make_bcrypt(password, unlock(rng.random_vec(16)), work_factor);
170  }
171 
177  bool check_bcrypt(const std::string &password, const std::string &hash);
178  } // namespace crypto3
179 } // namespace nil
180 
181 #endif
Bcrypt is a password hashing scheme originally designed for use in OpenBSD, but numerous other implem...
Definition: bcrypt.hpp:68
policy_type::cipher_type cipher_type
Definition: bcrypt.hpp:72
static void generate(const std::string &pass, const std::vector< uint8_t > &salt, uint16_t work_factor)
Takes the password to hash, a rng, and a work factor. The resulting password hash is returned as a st...
Definition: bcrypt.hpp:109
static bool check(const std::string &pass, const std::string &hash) const
Takes a password and a bcrypt output and returns true if the password is the same as the one that was...
Definition: bcrypt.hpp:138
std::enable_if<!boost::accumulators::detail::is_accumulator_set< OutputIterator >::value, OutputIterator >::type hash(InputIterator first, InputIterator last, OutputIterator out)
Definition: algorithm/hash.hpp:78
boost::mpl::apply< AccumulatorSet, tag::block< Mode > >::type::result_type block(const AccumulatorSet &acc)
Definition: accumulators/block.hpp:259
boost::mpl::apply< AccumulatorSet, tag::passhash< Hash > >::type::result_type passhash(const AccumulatorSet &acc)
Definition: accumulators/passhash.hpp:121
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: memory_operations.hpp:205
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: memory_operations.hpp:229
std::string generate_bcrypt(const std::string &password, UniformRandomGenerator &rng, uint16_t work_factor=10)
Definition: bcrypt.hpp:167
bool check_bcrypt(const std::string &password, const std::string &hash)
Definition: pair.hpp:31
Definition: bcrypt_functions.hpp:37
policy_type::cipher_type cipher_type
Definition: bcrypt_functions.hpp:40