A robust crypto class that performs encryption, decryption, hashing, ssl key management, cipher cracking functions etc... Errors and memory management is handled carefully to avoid memory leaks and bugs during runtime and compile-time. It involves advanced concepts such as Rsa public/private key pair generation, AES(Advanced-Encryption-Standard) encryption, SHA** Hashing Algorithms, and Hash Attack Functionalities, it has been tested for memory leaks many times and the result is no memory leak happens, stay cool...
written on a Linux OS, x86_64 architecture, compiled using g++ compiler and c++20 flag.
- Usage
- Namespace
- Macros
- Structs
- Enums
- Class
- Methods
- Properties
- Pseudo-Code
Use for encryption, decryption, hashing, ssl rsa key generation operations. Just include the translation unit "viper.cpp" which is in the "include" folder within root directory, you might want to "use namespace ViperCipher" in order to omit the namespace resolution prefix.
There is only one namespace available:
namespace ViperCipher{ ... };
#define __BUFFER_MAX_SIZE__ (unsigned int)4096u
typedef struct alignas(void *) {
std::basic_string<char> plain;
std::basic_string<char> hashed;
std::basic_string<char> encrypted;
std::basic_string<char> decrypted;
std::basic_string<char> public_key_pem;
std::basic_string<char> private_key_pem;
} BlockStructure;
typedef struct alignas(void *) {
std::string raw;
std::string hash;
} CrackedCipherStructure;
typedef struct alignas(void *) {
SHA1 s1;
SHA224 s224;
SHA256 s256;
SHA384 s384;
SHA512 s512;
} ShaModeStructure;
enum class RSA_KEY_FLAG : unsigned short int { FILE_COLLECTOR = 0, SCRIPT_COLLECTOR, DEFAULT };
enum class RSA_KEY_FILE : unsigned short int { PUBLIC = 0, PRIVATE = 1 };
enum class SHA_BLOCK_SIZE : unsigned short int { SHA1 = 1, SHA224 = 224, SHA256 = 256, SHA384 = 384, SHA512 = 512 };
enum class CIPHER_ATTACK_ALGO_MODE : unsigned short int { INFER = 0, ENFORCE, SMART, DEFAULT };
class Viper{ ... };
All methods are public, except FileCollect()
Viper();
const std::basic_string_view<char> Hash(const std::string &target, const SHA_BLOCK_SIZE ShaSize) noexcept;
const std::basic_string_view<char> Encrypt(const std::string &target) noexcept;
const std::basic_string_view<char> Decrypt(const std::basic_string_view<char> &target) noexcept;
ViperCipher::Viper &GenRsaPublicKey(const std::basic_string_view<char> &KeyFileName, const ViperCipher::RSA_KEY_FLAG &Flag) noexcept;
ViperCipher::Viper &GenRsaPrivateKey(const std::basic_string_view<char> &KeyFileName, const ViperCipher::RSA_KEY_FLAG &Flag) noexcept;
const std::string getPublicKey(void) noexcept;
const std::string getPrivateKey(void) noexcept;
void RevokeKeyIv(void) noexcept;
ViperCipher::Viper &CipherAttack(const std::initializer_list<std::basic_string<char>> &cipher_target_list, const std::basic_string_view<char> &target_file, const SHA_BLOCK_SIZE use_sha_mode,
const CIPHER_ATTACK_ALGO_MODE algo_cipher_mode, const unsigned long int crack_speed_ms) noexcept;
ViperCipher::Viper &CipherAttackDetached(const std::initializer_list<std::basic_string<char>> &cipher_target_list, const std::basic_string_view<char> &target_file, const SHA_BLOCK_SIZE
use_sha_mode, const CIPHER_ATTACK_ALGO_MODE algo_cipher_mode, const unsigned long int crack_speed_ms) noexcept;
void ThreadWait(void) noexcept;
const std::vector<CrackedCipherStructure> get_cracked_block() noexcept;
const void FileCollect(const std::basic_string_view<char> &KeyFileName, const RSA_KEY_FILE Flag) noexcept;
~Viper();
All properties are private.
BlockStructure Blocks;
std::vector<CrackedCipherStructure> CrackRegister;
AutoSeededRandomPool SystemEntropy;
SecByteBlock use_key;
SecByteBlock use_iv;
ShaModeStructure ShaMode;
bool is_cracker_running = false;
std::vector<std::string> crack_deck;
unsigned short int cipher_crack_entries = 0;
Symmetric Encryption/Decryption using AES/CBC encryption methods, the function requires a single string as argument, it will encrypt that string using AES encryption and return its encrypted version as string_view.
NOTE: You must use the same viper instance when you're encrypting and decrypting a source, becuase Viper instances hold different key and Init Vector Values. So using a Viper1 for encryption and Viper2 for decryption will result in error.
#include "lib/viper.cpp"
using namespace std;
using namespace ViperCipher;
int main(int argc, char **argv)
{
string plain = "something to encrypt";
Viper *viper = new Viper();
string_view enc = viper->Encrypt(plain);
string_view dec = viper->Decrypt(enc);
std::cout << "Encrypted: " << enc << std::endl;
std::cout << "Decrypted: " << dec << std::endl;
delete viper;
return EXIT_SUCCESS;
};
Hash strings, by default the hashing algorithm is SHA256, as standard, it can be set to another value by providing its value as second argument. The function requires just one argument as target, and an optional algorithm as second argument.
#include "lib/viper.cpp"
using namespace std;
using namespace ViperCipher;
int main(int argc, char **argv) {
string plain = "sucker";
Viper *viper = new Viper();
string_view hashed = viper->Hash(plain);
delete viper;
return 0;
};
Available Flags:
- SHA_BLOCK_SIZE::SHA1 hash using sha1
- SHA_BLOCK_SIZE::SHA224 hash using sha224
- SHA_BLOCK_SIZE::SHA256 hash using sha256
- SHA_BLOCK_SIZE::SHA384 hash using sha384
- SHA_BLOCK_SIZE::SHA512 hash using sha512
#include "lib/viper.cpp"
using namespace std;
using namespace ViperCipher;
int main(int argc, char **argv) {
string plain = "sucker";
Viper *viper = new Viper();
string_view hash_sha1 = viper->Hash(plain, ViperCipher::SHA_BLOCK_SIZE::SHA1);
string_view hash_sha224 = viper->Hash(plain, ViperCipher::SHA_BLOCK_SIZE::SHA224);
string_view hash_sha256 = viper->Hash(plain, ViperCipher::SHA_BLOCK_SIZE::SHA256);
string_view hash_sha384 = viper->Hash(plain, ViperCipher::SHA_BLOCK_SIZE::SHA384);
string_view hash_sha512 = viper->Hash(plain, ViperCipher::SHA_BLOCK_SIZE::SHA512);
delete viper;
return 0;
};
Generate a public key using RSA standard, this will generate a public key for you and store it either within the code or in a local file if specified, by default the key is stored within the code for usage, the key is generated using GenRsaPublicKey() and retrieved using .getPublicKey() either as chain execution block or on a different line providing a collector.
#include "lib/viper.cpp"
using namespace std;
using namespace ViperCipher;
int main(int argc, char **argv) {
Viper *viper = new Viper();
viper->GenRsaPublicKey(); // gen key
string get_key = viper->getPublicKey(); // export key
/**************** OR *****************/
string get_key = viper->GenRsaPublicKey().getPublicKey();
delete viper;
return 0;
};
Just as the public key generator, but this one generates a Private key, argument list and execution style are the same.
#include "lib/viper.cpp"
using namespace std;
using namespace ViperCipher;
int main(int argc, char **argv) {
Viper *viper = new Viper();
viper->GenRsaPrivateKey(); // gen key
string get_key = viper->getPrivateKey(); // export key
/**************** OR *****************/
string get_key = viper->GenRsaPrivateKey().getPrivateKey();
return 0;
};
Provide a path for the file to store key into as first argument, as second argument a Flag describing the operation mode, if save the key/s to a file/s or not, The default behavior(RSA_KEY_FLAG::SCRIPT_COLLECTOR) is to store the key locally within the code, to store a key within a file then just set RSA_KEY_FLAG::FILE_COLLECTOR as 2nd argument.
Available Flags
- RSA_KEY_FLAG::SCRIPT_COLLECTOR -- no file will be written to
- RSA_KEY_FLAG::FILE_COLLECTOR -- a file will be used to store the key
- RSA_KEY_FLAG::DEFAULT -- defaults to SCRIPT_COLLECTOR
#include "lib/viper.cpp"
using namespace std;
using namespace ViperCipher;
int main(int argc, char **argv) {
Viper *viper = new Viper();
viper->GenRsaPrivateKey("private.pem", ViperCipher::RSA_KEY_FLAG::FILE_COLLECTOR); // gen key
string_view get_key = viper->getPrivateKey(); // export key
/**************** OR *****************/
string get_key = viper->GenRsaPrivateKey("private.pem", ViperCipher::RSA_KEY_FLAG::FILE_COLLECTOR).getPrivateKey();
delete viper;
return 0;
};
Revoke the current key/iv used for crypto operations, this makes sure to refresh the key and initialization vector for new operations.
#include "lib/viper.cpp"
using namespace std;
using namespace ViperCipher;
int main(int argc, char **argv) {
Viper *viper = new Viper();
viper->RevokeKeyIv();
delete viper;
return 0;
};
Crack hash computed values, this function uses a table of records(human readable words) to crack a list of hashed values you provide as argument, the list must contain a valid set of hash-[Algo] records in order to de-cipher, the attack fails if any of the records are corrupted or altered, you can provide how many records you need within the list, but the file of records to be scanned must contain at least 1 entry. You need to specify an algorithm as well for the attack, such as SHA1, SHA256, etc... and finally provide the loop execution speed used to suspand the operation for an X mcs in order to allow proper operation output.
#include "lib/viper.cpp"
using namespace std;
using namespace ViperCipher;
int main(int argc, char **argv) {
Viper *viper = new Viper();
string_view pipe_file = "attack_table.txt"; // <-- dictionary table source file(supposing is in current dir)
/**
* Using 5 pre-computed hash values for the demo purpose, those can be how many you want, but the hash algorithm must be the same for all.
* For the following records i've used a sha256 bit function algorithm, possible algorithm are (SHA1, SHA224, SHA256, SHA384, SHA512)
**/
string sha256_cipher_target1 = "FB5597D8647D451ABA9CE78B8CEDC238E3F0EAE6D7D4900C7DEA9D82CEC872C0"; // <-- hashed "agony" with 256 bit block size
string sha256_cipher_target2 = "BCC649CFDB8CC557053DA67DF7E7FCB740DCF7F721CEBE1F2082597AD0D5E7D8"; // <-- hashed "found" with 256 bit block size
string sha256_cipher_target3 = "5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8"; // <-- hashed "password" with 256 bit block size
string sha256_cipher_target4 = "921A320AA9782C475560FF5136A8CC0B25F3ADF0DE751D918C9D78B105D2E368"; // <-- hashed "conspire" with 256 bit block size
string sha256_cipher_target5 = "D90EE9CCF6BEA1D2942A7B21319338198DEC2A746F8A0D0771621F00DA2E0864"; // <-- hashed "drop" with 256 bit block size
const uint64_t operation_speed = 5000UL; // <-- loop execution speed in microseconds format, 1 second = 1000000 microseconds
/**
* ----------- PARAMETER LIST ------------
* @param initializer_list<string> -> Mandatory -> the list of records to attack
* @param string_view -> Mandatory -> the file name to scan
* @param SHA_BLOCK_SIZE -> Optional -> the hash algorithm to use / Default =SHA_BLOCK_SIZE::SHA256
* @param CIPHER_ATTACK_ALGO_MODE -> Optional -> the algorithm deduction mode / Default = CIPHER_ATTACK_ALGO_MODE::DEFAULT
* @param uint64_t -> Optional -> the loop execution speed in microseconds format / Default = 10000
*/
viper->CipherAttack( { sha256_cipher_target5, sha256_cipher_target4, sha256_cipher_target3, sha256_cipher_target2, sha256_cipher_target1 },
pipe_file,
ViperCipher::SHA_BLOCK_SIZE::SHA256,
CIPHER_ATTACK_ALGO_MODE::DEFAULT,
operation_speed );
return 0;
};
Same as CipherAttack() but uses a detached thread for attacking operations.
#include "lib/viper.cpp"
using namespace std;
using namespace ViperCipher;
int main(int argc, char **argv) {
Viper *viper = new Viper();
string_view pipe_file = "attack_table.txt"; // <-- dictionary table source file(supposing is in current dir)
/**
* Using 5 pre-computed hash values for the demo purpose, those can be how many you want, but the hash algorithm must be the same for all.
* For the following records i've used a sha256 bit function algorithm, possible algorithm are (SHA1, SHA224, SHA256, SHA384, SHA512)
**/
string sha256_cipher_target1 = "FB5597D8647D451ABA9CE78B8CEDC238E3F0EAE6D7D4900C7DEA9D82CEC872C0"; // <-- hashed "agony" with 256 bit block size
string sha256_cipher_target2 = "BCC649CFDB8CC557053DA67DF7E7FCB740DCF7F721CEBE1F2082597AD0D5E7D8"; // <-- hashed "found" with 256 bit block size
string sha256_cipher_target3 = "5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8"; // <-- hashed "password" with 256 bit block size
string sha256_cipher_target4 = "921A320AA9782C475560FF5136A8CC0B25F3ADF0DE751D918C9D78B105D2E368"; // <-- hashed "conspire" with 256 bit block size
string sha256_cipher_target5 = "D90EE9CCF6BEA1D2942A7B21319338198DEC2A746F8A0D0771621F00DA2E0864"; // <-- hashed "drop" with 256 bit block size
const uint64_t operation_speed = 5000UL; // <-- loop execution speed in microseconds format, 1 second = 1000000 microseconds
/**
* ----------- PARAMETER LIST ------------
* @param initializer_list<string> -> Mandatory -> the list of records to attack
* @param string_view -> Mandatory -> the file name to scan
* @param SHA_BLOCK_SIZE -> Optional -> the hash algorithm to use / Default =SHA_BLOCK_SIZE::SHA256
* @param CIPHER_ATTACK_ALGO_MODE -> Optional -> the algorithm deduction mode / Default = CIPHER_ATTACK_ALGO_MODE::DEFAULT
* @param uint64_t -> Optional -> the loop execution speed in microseconds format / Default = 10000
*/
viper->CipherAttackDetached( { sha256_cipher_target5, sha256_cipher_target4, sha256_cipher_target3, sha256_cipher_target2, sha256_cipher_target1 },
pipe_file,
ViperCipher::SHA_BLOCK_SIZE::SHA256,
CIPHER_ATTACK_ALGO_MODE::DEFAULT,
operation_speed );
viper->ThreadWait(); // wait for the termination signal dispatched by CipherAttack() on operation execution done.
// This functoin call can also be chained with CipherAttack().ThreadWait()
return 0;
};
The library facilitates encryption, decryption, hashing, and reverse cracking (SHA[x] Reverse Ciphers) functionalities through a lightweight class called "Viper." You need to create an instance of the "Viper" class to utilize these functionalities.
- Developed and tested on Linux x86_64 OS.
- Developed using g++20 compiler.
- Compiler required flags: "-lcryptopp"
- Dependencies include Crypto++ and standard C++ libraries.
If you don't have crypto++ installed on your system, assuming you are on debian, ubuntu etc... run the following command within a console to install crypto++ so you can use it...
$ sudo apt install libcrypto++-dev
- Tested for memory safety using g++ address-sanitizer flag, with no reported memory leaks.
- Encourages users to compile the library locally and check for memory leaks using the provided shell script.
- ViperCipher
- none
- Viper
- BlockStructure
- CrackedCipherStructure
- ShaModeStructure
- RSA_KEY_FLAG
- RSA_KEY_FILE
- SHA_BLOCK_SIZE
- CIPHER_ATTACK_ALGO_MODE
- Constructor(Viper)
- Hash
- Encrypt
- Decrypt
- GenRsaPublicKey
- GenRsaPrivateKey
- getPublicKey
- getPrivateKey
- RevokeKeyIv
- CipherAttack
- CipherAttackDetached
- ThreadWait
- Destructor(~Viper)
- FileCollect
- none
- none
- Blocks
- CrackRegister
- SystemEntropy
- use_key
- use_iv
- sha_mode
- is_cracker_running
- crack_deck
- cipher_crack_entries
- none