Last active
March 8, 2020 12:08
-
-
Save kkAyataka/a7af83fc9d421ca65611 to your computer and use it in GitHub Desktop.
OpenSSL Encryption
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <openssl/evp.h> | |
#include <openssl/ossl_typ.h> | |
// OpenSSL v1.1.1d | |
// https://www.openssl.org/docs/man1.1.1/man7/crypto.html | |
// https://www.openssl.org/docs/man1.1.1/man3/EVP_CIPHER_CTX_new.html | |
bool Encrypt(const unsigned char * key, | |
const unsigned char (*iv)[16], | |
const unsigned char *data, const unsigned int data_size, | |
unsigned char *encrypted, const unsigned int encrypted_size) { | |
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); | |
EVP_CIPHER_CTX_init(ctx); | |
// 暗号化の設定で、EVP_aes_128_ecb等いろいろ | |
if (EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, *iv) == 0) { | |
EVP_CIPHER_CTX_cleanup(ctx); | |
return false; | |
} | |
// ブロックサイズで割り切れる部分の処理 | |
int outl = 0; | |
if (EVP_EncryptUpdate(ctx, encrypted, &outl, data, data_size) == 0) { | |
EVP_CIPHER_CTX_cleanup(ctx); | |
return false; | |
} | |
// 最後のブロックの処理で、PKCSパディングされる。 | |
int pad = 0; | |
if (EVP_EncryptFinal_ex(ctx, encrypted + outl, &pad) == 0) { | |
EVP_CIPHER_CTX_cleanup(ctx); | |
return false; | |
} | |
EVP_CIPHER_CTX_cleanup(ctx); | |
EVP_CIPHER_CTX_free(ctx); | |
return true; | |
} | |
bool Decrypt(const unsigned char * key, | |
const unsigned char (*iv)[16], | |
const unsigned char *data, const unsigned int data_size, | |
unsigned char *decrypted, const unsigned int decrypted_size) { | |
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); | |
EVP_CIPHER_CTX_init(ctx); | |
// 暗号化の設定 | |
if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, *iv) == 0) { | |
EVP_CIPHER_CTX_cleanup(ctx); | |
return false; | |
} | |
// ブロックサイズで割り切れる部分の処理 | |
int outl = 0; | |
if (EVP_DecryptUpdate(ctx, decrypted, &outl, data, data_size) == 0) { | |
EVP_CIPHER_CTX_cleanup(ctx); | |
return false; | |
} | |
// 最後のブロックの処理で、PKCSパディングのサイズを返す | |
// パディングのデータは処理されないので、後処理は自分で行う | |
int last = 0; | |
if (EVP_DecryptFinal_ex(ctx, decrypted + outl, &last) == 0) { | |
EVP_CIPHER_CTX_cleanup(ctx); | |
return false; | |
} | |
memset(decrypted + outl + last, 0, decrypted_size - outl - last); // remove padding | |
EVP_CIPHER_CTX_cleanup(ctx); | |
EVP_CIPHER_CTX_free(ctx); | |
return true; | |
} | |
int main(int argc, const char * argv[]) { | |
const std::string data = "1z2y3x"; | |
const unsigned char iv[16] = {0x01, 0x02, 0x03, 0xAA, 0xBB, 0x05, 0x11, 0x21, 0x88, 0x92, 0xA9, 0x62, 0x77, 0x5B, 0x4F, 0x44}; | |
const char * key = "0123456789ABCDEF"; | |
std::vector<unsigned char> encrypted(data.size() + (16 - data.size() % 16)); | |
Encrypt((unsigned char*)key, &iv, (unsigned char*)data.data(), data.size(), &encrypted[0], encrypted.size()); | |
printf("Encrypted:\n"); | |
for (int i = 0; i < encrypted.size(); ++i) { | |
printf("0x%02X, ", encrypted[i]); | |
} | |
printf("\n\n"); | |
std::vector<unsigned char> decrypted(encrypted.size()); | |
Decrypt((unsigned char*)key, &iv, encrypted.data(), encrypted.size(), &decrypted[0], decrypted.size()); | |
decrypted.push_back(0); | |
printf("Decrypted:\n"); | |
std::cout << (char*)&decrypted[0] << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment