1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
| #include <iostream> #include <cassert> #include <cmath> #include <openssl/aes.h> #include <openssl/evp.h> #include <openssl/kdf.h>
const char *key = "wandoer.com_wandoer.com_wandoer."; char iv[16] = { '_','i','v','_','m','u','s','t','_','b','e','_','1','6','B','_' }; const char *plain_text = "The EVP interface supports the ability to perform authenticated encryption and decryption, as well as the option to attach unencrypted," " associated data to the message. Such Authenticated-Encryption with Associated-Data (AEAD) schemes provide confidentiality by encrypting the data, and also" " provide authenticity assurances by creating a MAC tag over the encrypted data. The MAC tag will ensure the data is not accidentally altered or maliciously" " tampered during transmission and storage.";
template<typename CIPHER> bool encrypt(CIPHER cipher,const char* key, const char* iv, const unsigned char *in, int in_len, unsigned char *out, int *out_len) { bool ret = false;
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); int tmp = 0;
int rst = EVP_EncryptInit(ctx, cipher, reinterpret_cast<const unsigned char *>(key), reinterpret_cast<const unsigned char *>(iv)); if (rst != 1) goto RET;
rst = EVP_EncryptUpdate(ctx, out, &tmp, in, in_len); if (rst != 1) goto RET; *out_len = tmp;
rst = EVP_EncryptFinal(ctx, out + tmp, &tmp); if (rst != 1) goto RET; if (tmp > 0) { *out_len += tmp; }
ret = true;
RET: EVP_CIPHER_CTX_free(ctx); ctx = NULL; return ret; }
template<typename CIPHER> bool decrypt(CIPHER cipher, const char* key, const char* iv, const unsigned char *in, int in_len, unsigned char *out, int *out_len) { bool ret = false; EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); int tmp = 0; int rst = EVP_DecryptInit(ctx, cipher, reinterpret_cast<const unsigned char *>(key), reinterpret_cast<const unsigned char *>(iv)); if (rst != 1) goto RET;
rst = EVP_DecryptUpdate(ctx, out, &tmp, in, in_len); if (rst != 1) goto RET; *out_len = tmp;
rst = EVP_DecryptFinal(ctx, out + tmp, &tmp); if (rst != 1) goto RET; if (tmp > 0) { *out_len += tmp; }
ret = true;
RET: EVP_CIPHER_CTX_free(ctx); ctx = NULL; return ret; }
template<typename CIPHER> bool do_crypto(CIPHER cipher, const char* key, const char* iv, const unsigned char* in, int in_len, unsigned char* out, int* out_len, bool encrypt) { bool ret = false; EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); int tmp = 0; int rst = EVP_CipherInit(ctx, cipher, reinterpret_cast<const unsigned char*>(key), reinterpret_cast<const unsigned char*>(iv), encrypt ? 1 : 0); if (rst != 1) goto RET; rst = EVP_CipherUpdate(ctx, out, &tmp, in, in_len); if (rst != 1) goto RET; *out_len = tmp;
rst = EVP_CipherFinal(ctx, out + tmp, &tmp); if (rst != 1) goto RET; if (tmp > 0) { *out_len += tmp; }
ret = true;
RET: EVP_CIPHER_CTX_free(ctx); ctx = NULL; return ret; }
int main(void) {
const EVP_CIPHER *cipher = EVP_aes_256_cfb();
int out_len = ceil((float)strlen(plain_text) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; unsigned char *cipher_text = (unsigned char *)malloc(out_len); unsigned char *re_plain_text = (unsigned char *)malloc(out_len);
int enc_len = 0, dec_len = 0;
memset(cipher_text, 0, out_len); memset(re_plain_text, 0, out_len); bool encryped = encrypt(cipher,key,iv, reinterpret_cast<const unsigned char *>(plain_text), strlen(plain_text), cipher_text, &enc_len); assert(encryped);
bool decrypted = decrypt(cipher,key, iv, cipher_text, enc_len, re_plain_text, &dec_len); assert(decrypted); if (dec_len < out_len) re_plain_text[dec_len] = '\0';
int cmp = strcmp(plain_text, reinterpret_cast<char *>(re_plain_text)); assert(cmp == 0);
memset(cipher_text, 0, out_len); memset(re_plain_text, 0, out_len); encryped = do_crypto(cipher, key, iv, reinterpret_cast<const unsigned char*>(plain_text), strlen(plain_text), cipher_text, &enc_len, true); assert(encryped); decrypted = do_crypto(cipher, key, iv, cipher_text, enc_len, re_plain_text, &dec_len, false); assert(decrypted); cmp = strcmp(plain_text, reinterpret_cast<char*>(re_plain_text)); assert(cmp == 0);
free(cipher_text); free(re_plain_text);
return 0; }
|