c程序下openssl aes-cbc 加密解密

CBC(密码分组链接的缩写)

在CBC模式中,每个明文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有明文块。同时,为了保证每条消息的唯一性,在第一个块中需要使用初始化向量。

CBC模式原理图讲解的很详细的网站链接:

https://www.cnblogs.com/eleven-elv/p/7289579.html

https://blog.csdn.net/chengqiuming/article/details/82288851

https://www.jianshu.com/p/79a225c2650e

https://blog.csdn.net/duanxingheng/article/details/11730617

代码均是copy于如下stackoverflow上的链接,亲测可行。

https://stackoverflow.com/questions/18152913/aes-aes-cbc-128-aes-cbc-192-aes-cbc-256-encryption-decryption-with-openssl-c

使用静态数组方式可以使用文件aes_cbc.c测试:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>

// a simple hex-print routine. could be modified to print 16 bytes-per-line
static void hex_print(const void* pv, size_t len)
{
    const unsigned char * p = (const unsigned char*)pv;
    if (NULL == pv) {
        printf("NULL");
    }
    else {
        size_t i = 0;
        for (; i<len;++i) {
            printf("%02X ", *p++);
        }
    }
    printf("\n");
}

// main entrypoint
int main(int argc, char **argv)
{
    int keylength;
    printf("Give a key length [only 128 or 192 or 256!]:\n");
    scanf("%d", &keylength);

    /* generate a key with a given length */
    unsigned char aes_key[keylength/8];
    memset(aes_key, 0, keylength/8);
    if (!RAND_bytes(aes_key, keylength/8)) {
        exit(-1);
    }

    size_t inputslength = 0;
    printf("Give an input's length:\n");
    scanf("%lu", &inputslength);

    /* generate input with a given length */
    unsigned char aes_input[inputslength];
    memset(aes_input, 'X', inputslength);

    /* init vector */
    unsigned char iv_enc[AES_BLOCK_SIZE], iv_dec[AES_BLOCK_SIZE];
    RAND_bytes(iv_enc, AES_BLOCK_SIZE);
    memcpy(iv_dec, iv_enc, AES_BLOCK_SIZE);

    // buffers for encryption and decryption
    const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
    unsigned char enc_out[encslength];
    unsigned char dec_out[inputslength];
    memset(enc_out, 0, sizeof(enc_out));
    memset(dec_out, 0, sizeof(dec_out));

    // so i can do with this aes-cbc-128 aes-cbc-192 aes-cbc-256
    AES_KEY enc_key, dec_key;
    AES_set_encrypt_key(aes_key, keylength, &enc_key);
    AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT);

    AES_set_decrypt_key(aes_key, keylength, &dec_key);
    AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT);

    printf("original:\t");
    hex_print(aes_input, sizeof(aes_input));

    printf("encrypt:\t");
    hex_print(enc_out, sizeof(enc_out));

    printf("decrypt:\t");
    hex_print(dec_out, sizeof(dec_out));

    return 0;
}

执行命令编译可执行文件aes_cbc :

gcc -Wall aes_cbc.c -o aes_cbc -lssl -lcrypto

运行可执行文件aes_cbc:

./aes_cbc

运行效果:

Give a key length [only 128 or 192 or 256!]:
128
Give an input's length:
16
original:    58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58
encrypt:    3D CA C2 0C B9 B7 E9 07 26 94 85 A8 2D 54 17 4A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
decrypt:    58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58

 

使用动态数组时可以使用文件new_aes_cbc.c测试:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>

// a simple hex-print routine. could be modified to print 16 bytes-per-line
static void hex_print(const void* pv, size_t len)
{
    const unsigned char * p = (const unsigned char*)pv;
    if (NULL == pv) {
        printf("NULL");
    }
    else {
        size_t i = 0;
        for (; i<len;++i) {
            printf("%02X ", *p++);
        }
    }
    printf("\n");
}

// main entrypoint
int main(int argc, char **argv)
{
    int keylength;
    printf("Give a key length [only 128 or 192 or 256!]:\n");
    scanf("%d", &keylength);

    /* generate a key with a given length */
    unsigned char *aes_key = (unsigned char*)malloc(sizeof(unsigned char) * (keylength/8));
    memset(aes_key, 0, keylength/8);
    if (!RAND_bytes(aes_key, keylength/8)) {
        exit(-1);
    }

    size_t inputslength = 0;
    printf("Give an input's length:\n");
    scanf("%lu", &inputslength);

    /* generate input with a given length */
    unsigned char *aes_input = (unsigned char*)malloc(sizeof(unsigned char) *inputslength);
    memset(aes_input, 'X', inputslength);

    /* init vector */
    unsigned char *iv_enc = (unsigned char*)malloc(sizeof(unsigned char) *AES_BLOCK_SIZE), *iv_dec = (unsigned char*)malloc(sizeof(unsigned char) *AES_BLOCK_SIZE);
    RAND_bytes(iv_enc, AES_BLOCK_SIZE);
    memcpy(iv_dec, iv_enc, AES_BLOCK_SIZE);

    // buffers for encryption and decryption
    const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
    unsigned char *enc_out = (unsigned char*)malloc(sizeof(unsigned char) *encslength);
    unsigned char *dec_out = (unsigned char*)malloc(sizeof(unsigned char) *inputslength);
    memset(enc_out, 0, sizeof(enc_out));
    memset(dec_out, 0, sizeof(dec_out));

    // so i can do with this aes-cbc-128 aes-cbc-192 aes-cbc-256
    AES_KEY enc_key, dec_key;
    AES_set_encrypt_key(aes_key, keylength, &enc_key);
    AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT);

    AES_set_decrypt_key(aes_key, keylength, &dec_key);
    AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT);

    printf("original:\t");
    hex_print(aes_input, inputslength);

    printf("encrypt:\t");
    hex_print(enc_out, encslength);

    printf("decrypt:\t");
    hex_print(dec_out, inputslength);

    free(aes_key);
    aes_key = NULL;
    free(aes_input);
    aes_input = NULL;
    free(iv_enc);
    iv_enc = NULL;
    free(iv_dec);
    iv_dec = NULL;
    free(enc_out);
    enc_out = NULL;
    free(dec_out);
    dec_out = NULL;

    return 0;
}

 

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值