简体   繁体   中英

Can someone give an encryption/decryption example with OpenSSL AES CCM?

I'm looking for an example of using OpenSSL's AES CCM encryption. Apparently, this is one of the two 'custom' cipher modes that require additional setup beyond EVP_CipherInit_ex(). Any suggestions would be appreciated.

In short:

// Tell the alg we will encrypt Psize bytes
int outl = 0;
EVP_EncryptUpdate(ctx, 0, &outl, 0, Psize);

// Add the AAD
EVP_EncryptUpdate(ctx, 0, &outl, A, Asize);

// Now we encrypt the data in P, placing the output in CT
EVP_EncryptUpdate(ctx, CT, &outl, P, Psize);

For more details, please see my blog post on this, http://www.fredriks.se/?p=23 .

To look at a complete simple AES CCM encrypt/decrypt example that uses some NIST data I strongly suggest to visit the OpenSSL Github Demos repository, here:

https://github.com/openssl/openssl/blob/master/demos/evp/aesccm.c

The example is working well, with comments and debugging output.

Here is an example for encryption and decryption with OpenSSL CCM-AES-128

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>

void str2hex(char *, char*, int);
void printBytes(unsigned char *, size_t );


int main() {

    unsigned char *aad, *pt, *key, *nonce;
    int Klen, Alen, Nlen, Plen, Tlen, Clen;
    int outl = 0;

    key = "5a33980e71e7d67fd6cf171454dc96e5";
    aad = "eca622a37570df619e10ebb18bebadb2f2b49c4d2b2ff715873bb672e30fc0ff";
    nonce = "33ae68ebb8010c6b3da6b9cb29";
    pt = "a34dfa24847c365291ce1b54bcf8d9a75d861e5133cc3a74";

    Klen = strlen(key) / 2;
    Alen = strlen(aad) / 2;
    Nlen = strlen(nonce) / 2;
    Plen = strlen(pt) / 2;
    Tlen = 16;
    Clen = Plen + Tlen;

    unsigned char keyy[Klen], aadd[Alen], noncee[Nlen], ptt[Plen];
    unsigned char ct[Clen], dt[Plen];

    str2hex(key, keyy, Klen);
    str2hex(pt, ptt, Plen);
    str2hex(aad, aadd, Alen);
    str2hex(nonce, noncee, Nlen);

    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);
    EVP_EncryptInit(ctx, EVP_aes_128_ccm(), 0, 0);
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0);
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, Tlen, 0);
    EVP_EncryptInit(ctx, 0, keyy, noncee);
    EVP_EncryptUpdate(ctx, 0, &outl, 0, Plen);
    EVP_EncryptUpdate(ctx, 0, &outl, aadd, Alen);
    EVP_EncryptUpdate(ctx, ct, &outl, ptt, Plen);
    EVP_EncryptFinal(ctx, &ct[outl], &outl);
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, Tlen, ct + Plen);

    printf("plaintext' = %s", pt);
    // printf("\nciphertext' = 7a60fa7ee8859e283cce378fb6b95522ab8b70efcdb0265f7c4b4fa597666b86dd1353e400f28864");
    printf("\n");

    printf("\nciphertext : ");
    printBytes(ct, Clen);

    EVP_DecryptInit(ctx, EVP_aes_128_ccm(), 0, 0);
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0);
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, Tlen, ct + Plen);
    EVP_DecryptInit(ctx, 0, keyy, noncee);
    EVP_DecryptUpdate(ctx, 0, &outl, 0, Plen);
    EVP_DecryptUpdate(ctx, 0, &outl, aadd, Alen);
    EVP_DecryptUpdate(ctx, dt, &outl, ct, Plen);
    EVP_DecryptFinal(ctx, &dt[outl], &outl);
    printf("plaintext : ");
    printBytes(dt, Plen);

    return 0;
}

void str2hex(char *str, char *hex, int len) {
    int tt, ss;
    unsigned char temp[4];
    for (tt = 0, ss = 0; tt < len, ss < 2 * len; tt++, ss += 2) {
        temp[0] = '0';
        temp[1] = 'x';
        temp[2] = str[ss];
        temp[3] = str[ss + 1];

        hex[tt] = (int) strtol(temp, NULL, 0);
    }
}

void printBytes(unsigned char *buf, size_t len) {
    int i;
    for (i = 0; i < len; i++) {
        printf("%02x", buf[i]);
    }
    printf("\n");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM