diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index fcf500f..66c1c34 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -21,3 +21,4 @@ else() endif() install(TARGETS server RUNTIME DESTINATION bin) + diff --git a/server/src/crypto/base64.cpp b/server/src/crypto/base64.cpp index 2db79f5..2d2ff8b 100644 --- a/server/src/crypto/base64.cpp +++ b/server/src/crypto/base64.cpp @@ -4,7 +4,7 @@ #define B64_PADDING 0xFF std::string sosc::cgc::base64_encode(const std::string& data, bool unix) { - return base64_encode(data.c_str(), data.length()); + return base64_encode(data.c_str(), data.length(), unix); } std::string sosc::cgc::base64_encode @@ -18,7 +18,7 @@ std::string sosc::cgc::base64_encode std::string encoded; for(size_t i = 0; i < length; i += 3) { - if(i > 0 && ((i / 3) * 4) % 76 == 0) + if(i > 0 && ((i / 3) * 4) % 76 == 0 && !unix) encoded += "\r\n"; int index = 0, padding = 0; diff --git a/server/src/crypto/bcrypt.cpp b/server/src/crypto/bcrypt.cpp index 618010a..aceb736 100644 --- a/server/src/crypto/bcrypt.cpp +++ b/server/src/crypto/bcrypt.cpp @@ -1,15 +1,41 @@ #include "bcrypt.hpp" +static const uint32_t bcrypt_ciphertext[6] = { + 0x4f727068, 0x65616e42, 0x65686f6c, + 0x64657253, 0x63727944, 0x6f756274 +}; + std::string sosc::cgc::bcrypt_hash(const std::string& input) { std::string salt = csprng::next_bytes(16), input_t = input.substr(0, 72); + + uint32_t ctext[6]; + std::memcpy(ctext, bcrypt_ciphertext, 6 * sizeof(uint32_t)); Blowfish bfish; + bfish.SetEksKey(salt, input); + for(int i = 0; i < BCRYPT_COST; ++i) { + bfish.SetKey(input.c_str(), input.length()); + bfish.SetKey(salt.c_str(), salt.length()); + } + + for(int i = 0; i < 64; ++i) + for(int j = 0; j < 6; j += 2) + bfish.EncryptBlock(&ctext[j], &ctext[j + 1]); + std::string ct_hash(24, 0); + for(int i = 0; i < 6; ++i) { + for(int j = 0; j < 4; ++j) { + ct_hash[i * 4 + j] = ctext[i] & 0xFF; + ctext[i] >>= 8; + } + } + std::stringstream stream; - stream << "$2b$" << BCRYPT_COST << "$" - << base64_encode(salt, true) - << "b"; + stream << "$2b$" + << (BCRYPT_COST < 10 ? "0" : "") << BCRYPT_COST + << "$" << base64_encode(salt, true) + << base64_encode(ct_hash, true); return stream.str(); } diff --git a/server/src/crypto/bcrypt.hpp b/server/src/crypto/bcrypt.hpp index 0a74bdc..789421c 100644 --- a/server/src/crypto/bcrypt.hpp +++ b/server/src/crypto/bcrypt.hpp @@ -2,6 +2,7 @@ #define SOSC_CRYPTO_BCRYPT_H #include +#include #include #include "base64.hpp" #include "bfish.hpp" diff --git a/server/src/crypto/bfish.cpp b/server/src/crypto/bfish.cpp index a634564..b15536d 100644 --- a/server/src/crypto/bfish.cpp +++ b/server/src/crypto/bfish.cpp @@ -190,7 +190,17 @@ static void swap(uint32_t& a, uint32_t& b) { b = temp; } -static void pack_bytes +static uint32_t pack_word + (const std::string& data, std::string::size_type i) +{ + uint32_t word; + for(int j = 0; j < 4; ++j) + word = (word << 8) | data[(i + j) % data.length()]; + + return word; +} + +static void pack_block (const std::string& data, std::string::size_type i, uint32_t& left, uint32_t& right) { @@ -203,36 +213,33 @@ static void pack_bytes } } -static void unpack_bytes +static void unpack_block (std::string& data, std::string::size_type i, uint32_t left, uint32_t right) { for(int j = 0; j < 8; ++j) { if(j < 4) { - data[i + (3 - j)] = left & 0xFF; + data[(i + (3 - j)) % data.length()] = left & 0xFF; left >>= 8; } else { - data[i + (7 - j + 4)] = right & 0xFF; + data[(i + (7 - j + 4)) % data.length()] = right & 0xFF; right >>= 8; } } } -sosc::cgc::Blowfish::Blowfish(const std::string& key) { +sosc::cgc::Blowfish::Blowfish() { std::memcpy(this->parr, init_parr, sizeof(init_parr)); std::memcpy(this->sbox, init_sbox, sizeof(init_sbox)); - +} + +sosc::cgc::Blowfish::Blowfish(const std::string& key) : Blowfish() { this->SetKey(key.c_str(), key.length()); } void sosc::cgc::Blowfish::SetKey(const char* key, size_t length) { - for(int i = 0; i < 18; ++i) { - uint32_t data = 0; - for(int j = 0; j < 4; ++j) - data = (data << 8) | key[(i * 4 + j) % length]; - - this->parr[i] ^= data; - } + for(int i = 0; i < 18; ++i) + this->parr[i] ^= pack_word(key, i * 4); uint32_t left = 0, right = 0; for(int i = 0; i < 18; i += 2) { @@ -253,16 +260,32 @@ void sosc::cgc::Blowfish::SetKey(const char* key, size_t length) { void sosc::cgc::Blowfish::SetEksKey (const std::string& data, const std::string& key) { - for(int i = 0; i < 18; ++i) { - uint32_t pack = 0; - for(int j = 0; j < 4; ++j) - pack = (pack << 8) | key[(i * 4 + j) % key.length()]; - - this->parr[i] ^= pack; + for(int i = 0; i < 18; ++i) + this->parr[i] ^= pack_word(key, i * 4); + + uint32_t left, right, ptr = 0; + for(int i = 0; i < 18; i += 2) { + left = pack_word(data, ptr); + right = pack_word(data, ptr + 4); + + this->EncryptBlock(&left, &right); + + this->parr[i] = left; + this->parr[i + 1] = right; + ptr += 8; } - for(int i = 0; i < 18; i += 2) { - + for(int i = 0; i < 4; ++i) { + for(int j = 0; j < 256; j += 2) { + left = pack_word(data, ptr); + right = pack_word(data, ptr + 4); + + this->EncryptBlock(&left, &right); + + this->sbox[i][j] = left; + this->sbox[i][j + 1] = right; + ptr += 8; + } } } @@ -276,9 +299,9 @@ std::string sosc::cgc::Blowfish::Encrypt(std::string data) const { for(std::string::size_type i = 0; i < data.size(); i += 8) { uint32_t left, right; - pack_bytes(data, i, left, right); + pack_block(data, i, left, right); this->EncryptBlock(&left, &right); - unpack_bytes(data, i, left, right); + unpack_block(data, i, left, right); } return data; @@ -291,9 +314,9 @@ std::string sosc::cgc::Blowfish::Decrypt(std::string data) const { for(std::string::size_type i = 0; i < data.size(); i += 8) { uint32_t left, right; - pack_bytes(data, i, left, right); + pack_block(data, i, left, right); this->DecryptBlock(&left, &right); - unpack_bytes(data, i, left, right); + unpack_block(data, i, left, right); } int i = 0; diff --git a/server/src/main.cpp b/server/src/main.cpp index 6b65119..9d9f72f 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -9,6 +9,7 @@ #include "crypto/base64.hpp" #include "crypto/bfish.hpp" #include "utils/csprng.hpp" +#include "crypto/bcrypt.hpp" int main(int argc, char **argv) { //auto sock = sosc::TcpClient(); @@ -34,12 +35,16 @@ int main(int argc, char **argv) { //std::string a = sosc::cgc::sha1("test", true); - sosc::cgc::Blowfish fish(""); + /*sosc::cgc::Blowfish fish("TESTKEY"); std::string test = fish.Encrypt("imagine a test"); std::string testd = fish.Decrypt(test); uint32_t teest = sosc::csprng::next(); + std::cout << std::hex << teest;*/ + + std::string hash = sosc::cgc::bcrypt_hash("test pwd"); + std::cout << hash; return 0; }