Skip to content

Instantly share code, notes, and snippets.

@kkAyataka
Last active March 8, 2020 12:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kkAyataka/a7af83fc9d421ca65611 to your computer and use it in GitHub Desktop.
Save kkAyataka/a7af83fc9d421ca65611 to your computer and use it in GitHub Desktop.
OpenSSL Encryption
#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