2011-11-01 38 views
4

我正在尋找使用OpenSSL的AES CCM加密的示例。顯然,這是需要EVP_CipherInit_ex()之外的其他設置的兩種「自定義」加密模式之一。任何建議,將不勝感激。有人可以使用OpenSSL AES CCM提供加密/解密示例嗎?

+0

我不知道的OpenSSL加密和解密的例子,但我認爲你主要是需要設置初始化向量。 –

+1

初始化矢量始終是EVP_CipherInit_ex()的參數,因此已經存在。看起來我可以使用EVP_CIPHER_CTX_ctrl()設置特殊參數,但它們沒有任何作用。 –

+0

[官方手冊頁](http://www.openssl.org/docs/crypto/EVP_EncryptInit.html)表示「EVP_CIPHER_CTX_ctrl()允許確定和設置各種特定於密碼的參數,目前只有RC2有效密鑰長度和可以設置RC5的輪數。「儘管如此,它沒有提到有關CCM(CTR + CBC-MAC)的任何信息。 –

回答

2

簡而言之:

// 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); 

欲瞭解更多詳情,請參閱本上我的博客文章,http://www.fredriks.se/?p=23

+0

這可以在1.0.1中使用嗎?還是僅在1.1.0版本中才能使用? –

+0

這在1.0.1中可用,請參閱evp.h. –

0

這裏是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"); 
}