Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*!
- * Simple AES
- * Brendan Long
- * March 29, 2010
- *
- * Simplified encryption and decryption using OpenSSL's AES library.
- * Remember to compile with -lcrypto and link against the library
- * g++ (your stuff) -lcrypto simpleAes.cpp (or simpleAes.o)
- *
- * Implementation note: Using the default ivec (0) is not secure. For
- * the full security that AES offers, use a different
- * ivec each time (it does not need to be secret,
- * just different.
- *
- * This code is released into the public domain. Yada yada..
- * Read this for details: http://creativecommons.org/licenses/publicdomain/
- *
- * If for some reason public domain isn't good enough, you may use, alter,
- * distribute or do anything else you want with this code with no restrictions.
- */
- #include <openssl/aes.h>
- #include <openssl/evp.h>
- #include <iostream>
- #include <string.h>
- // On Linux, we'll seed openssl with /dev/urandom, on others we use the time
- #ifdef __unix__
- #include <fstream>
- #elif _win32
- #include <Wincrypt.h>
- #endif
- /*!
- * Generates 16 random numbers for the initialization vector.
- * On Linux, this uses /dev/urandom, on other platforms, it uses c's rand() function
- * \param ivec An unsigned char[16] to fill with random numbers
- * \return True on success, false otherwise
- */
- bool getRandomIvec(unsigned char* ivec){
- #ifdef __unix__
- // Read 16 bytes from /dev/urandom
- std::ifstream fin("/dev/urandom", std::ios_base::in | std::ios_base::binary);
- if(!fin.fail()){
- fin.read((char*)ivec, 16);
- }
- else{
- fin.open("/dev/urandom", std::ios_base::in | std::ios_base::binary);
- if(!fin.fail()){
- fin.read((char*)ivec, 16);
- }
- else return false;
- }
- fin.close();
- return true;
- #elif _win32
- // I don't have a clue if this works..
- HCRYPTPROV hCryptProv;
- CryptAcquireContext( &hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)
- if(CryptGenRandom(hCryptProv, 16, (BYTE*) ivec)){
- printf("Random sequence generated. \n");
- }
- else{
- std::cout << "ERROR: CryptGenRandom failed." << std::endl;
- return NULL;
- }
- #else
- // uhh...
- #endif
- }
- /*!
- * Encrypts a string using AES 256
- * Note: If the key is less than 32 bytes, it will be null padded.
- * If the key is greater than 32 bytes, it will be truncated
- * \param in The string to encrypt
- * \param key The key to encrypt with
- * \return The encrypted data
- */
- std::string aes_encrypt(std::string in, std::string key){
- unsigned char ivec[16];
- getRandomIvec(ivec);
- std::string ivecString((char*) ivec, 16); // Save this for later
- // Always pad the key to 32 bits.. because we can
- if(key.length() < 32){
- key.append(32 - key.length(), '\0');
- }
- // Get some space ready for the output
- unsigned char *output = new unsigned char[in.length() + AES_BLOCK_SIZE];
- // Encrypt the data
- int length, finalLength = 0;
- EVP_CIPHER_CTX *encryptHandle = new EVP_CIPHER_CTX;
- EVP_CIPHER_CTX_init(encryptHandle);
- EVP_EncryptInit_ex(encryptHandle, EVP_aes_256_cbc(), NULL, (unsigned char*) key.c_str(), ivec);
- EVP_EncryptUpdate(encryptHandle, output, &length, (unsigned char*)in.c_str(), in.length());
- finalLength += length;
- EVP_EncryptFinal_ex(encryptHandle, output + length, &length);
- finalLength += length;
- // Make the data into a string
- std::string ret((char*) output, finalLength);
- // clean up
- delete output;
- EVP_CIPHER_CTX_cleanup(encryptHandle);
- delete encryptHandle;
- return ivecString + ret;
- }
- /*!
- * Decrypts a string using AES 256
- * Note: If the key is less than 32 bytes, it will be null padded.
- * If the key is greater than 32 bytes, it will be truncated
- * \param in The string to decrypt
- * \param key The key to decrypt with
- * \return The decrypted data
- */
- std::string aes_decrypt(std::string in, std::string key){
- // Get the ivec from the front
- unsigned char ivec[16];
- strncpy((char*)ivec, in.c_str(), 16);
- in = in.substr(16);
- // Always pad the key to 32 bits.. because we can
- if(key.length() < 32){
- key.append(32 - key.length(), '\0');
- }
- // Create some space for output
- unsigned char *output = new unsigned char[in.length()];
- int length, finalLength = 0;
- // Decrypt the string
- EVP_CIPHER_CTX *encryptHandle = new EVP_CIPHER_CTX;
- EVP_CIPHER_CTX_init(encryptHandle);
- EVP_DecryptInit_ex(encryptHandle, EVP_aes_256_cbc(), NULL, (unsigned char*) key.c_str(), ivec);
- EVP_DecryptUpdate(encryptHandle, output, &length, (unsigned char*)in.c_str(), in.length());
- finalLength += length;
- EVP_DecryptFinal_ex(encryptHandle, output + length, &length);
- finalLength += length;
- std::cout << finalLength << std::endl;
- // Make the output into a string
- std::string ret((char*) output, finalLength);
- // Clean up
- delete output;
- EVP_CIPHER_CTX_cleanup(encryptHandle);
- delete encryptHandle;
- return ret;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement