linux c openssl aes 加解密

1.OpenSSL提供了AES加解密算法的API

const char *AES_options(void);

AES算法状态,是所有支持或者是部分支持。

返回值:“aes(full)” 或者"aes(partial)"

 

int AES_set_encrypt_key(const unsigned char *userKey, const int bits,AES_KEY *key);

设定加密用的Key;

userKey: 密钥数值。

bits:密钥长度,以bit为单位。假设密钥数字是16个字节,则此參数值应为128。

key: AES_KEY对象指针;

返回值: 0 成功, -1 userkey,key为空, -2: 密钥长度不是128。192。256;

 

int AES_set_decrypt_key(const unsigned char *userKey, const int bits,  AES_KEY *key);

设定解密用的Key;

userKey: 密钥数值;

bits:密钥长度,以bit为单位,假设密钥数字是16个字节。则此參数值应为128;

key: AES_KEY对象指针;

返回值: 0 成功, -1 userkey。key为空。 -2: 密钥长度不是128。192,256。

 

void AES_encrypt(const unsigned char *in, unsigned char *out,const AES_KEY *key);

AES 加密。加密单个数据块。in,out能够是同一内存区;

in: 须要加密的数据;

out: 加密后的数据。

key:AES 密钥。

 

void AES_decrypt(const unsigned char *in, unsigned char *out,const AES_KEY *key);

AES 解密。解密单个数据块,in。out能够是同一内存区;

in: 须要解密的数据。

out: 解密后的数据;

key:AES 密钥。

 

void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,    const AES_KEY *key, const int enc);

AES加密/解密单个数据块,ECB模式

in: 须要加密/解密的数据;

out: 计算后输出的数据。

key:密钥

enc: AES_ENCRYPT 代表加密, AES_DECRYPT代表解密。

 

void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,   size_t length, const AES_KEY *key,    unsigned char *ivec, const int enc);

AES加密/解密单个数据块,CBC模式

in: 须要加密/解密的数据;

out: 计算后输出的数据。

length: 数据长度

key:密钥

ivec: 初始向量

enc: AES_ENCRYPT 代表加密, AES_DECRYPT代表解密;

 

void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
    size_t length, const AES_KEY *key,
    unsigned char *ivec, int *num, const int enc);

AES CFB128位模式加密/解密。输入输出数据区能够重叠。
in: 须要加密/解密的数据。
out: 计算后输出的数据;
length: 数据长度;
key: 密钥;
ivec: 初始化向量
num: 输出參数。计算状态。多少个CFB数据块
enc: 计算模式。 加密: AES_ENCRYPT 。 解密: AES_DECRYPT
    

void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
    size_t length, const AES_KEY *key,
    unsigned char *ivec, int *num, const int enc);

AES CFB1位模式加密/解密。输入输出数据区能够重叠;
in: 须要加密/解密的数据;
out: 计算后输出的数据;
length: 数据长度;
key: 密钥;
ivec: 初始化向量
num: 输出參数,计算状态,多少个CFB数据块
enc: 计算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT
    
    
void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
    size_t length, const AES_KEY *key,
    unsigned char *ivec, int *num, const int enc);

AES CFB8位模式加密/解密。输入输出数据区能够重叠;
in: 须要加密/解密的数据;
out: 计算后输出的数据;
length: 数据长度;
key: 密钥;
ivec: 初始化向量
num: 输出參数,计算状态,多少个CFB数据块
enc: 计算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT

    
void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
    size_t length, const AES_KEY *key,
    unsigned char *ivec, int *num);

AES OFB128位模式加密/解密,输入输出数据区能够重叠;
in: 须要加密/解密的数据;
out: 计算后输出的数据。
length: 数据长度;
key: 密钥。
ivec: 初始化向量
num: 输出參数,计算状态,多少个CFB数据块
enc: 计算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT

        
    
void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
    size_t length, const AES_KEY *key,
    unsigned char ivec[AES_BLOCK_SIZE],
    unsigned char ecount_buf[AES_BLOCK_SIZE],
    unsigned int *num);

AES CTR128位模式加密/解密,输入输出数据区能够重叠;
in: 须要加密/解密的数据。
out: 计算后输出的数据;
length: 数据长度;
key: 密钥。
ivec: 初始化向量
ecount_buf: 输出參加,加密的次数,在第一次调用此函数时,须要初始化为0
num: 输出參数,计算状态,多少个CFB数据块,在第一次调用此函数时,须要初始化为0
enc: 计算模式。 加密: AES_ENCRYPT , 解密: AES_DECRYPT



void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
             size_t length, const AES_KEY *key,
             unsigned char *ivec, const int enc);

AES 加密/解密,输入输出数据区能够重叠,初始化向量是加密数据块的2倍,加密前用前半部分做一次异或。加密后用后半部分做一次异或;
in: 须要加密/解密的数据;
out: 计算后输出的数据。
length: 数据长度;
key: 密钥;
ivec: 初始化向量
enc: 计算模式。 加密: AES_ENCRYPT , 解密: AES_DECRYPT
    
                 

void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
            size_t length, const AES_KEY *key,
            const AES_KEY *key2, const unsigned char *ivec,
            const int enc);

AES 加密/解密。输入输出数据区能够重叠。初始化向量是加密数据块的4倍,加密前用第一部分做一次异或。加密后用第二部分做一次异或;
最后一个加密数据块,加密前用第三部分异或,加密后用第四部分异或;
in: 须要加密/解密的数据;
out: 计算后输出的数据;
length: 数据长度。
key: 密钥。
ivec: 初始化向量
enc: 计算模式, 加密: AES_ENCRYPT , 解密: AES_DECRYPT            
 

int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
        unsigned char *out,
        const unsigned char *in, unsigned int inlen)

用AES算法对明文key数据加密

key: AES Key,用于加密密钥数据

iv: 初始化向量

out: 加密后的密钥数据

in: 密钥数据

inlen: 密钥数据长度

返回值: 1: 成功。 0: 失败

 

int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
        unsigned char *out,
        const unsigned char *in, unsigned int inlen)

用AES算法对明文key数据加密

key: AES Key,用于加密密钥数据

iv: 初始化向量

out: 加密后的密钥数据

in: 密钥数据

inlen: 密钥数据长度

返回值: 1: 成功, 0: 失败

 

2.C实例分析

首先要了解AES加密是什么。以及几种加密模式的差别。之后才是编程。

ECB模式 

  长处: 

  1.简单; 

  2.有利于并行计算。 

  3.误差不会被传送。 

  缺点: 

  1.不能隐藏明文的模式; 

  2.可能对明文进行主动攻击; 

CBC模式: 

  长处: 

  1.不easy主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。 

  缺点: 

  1.不利于并行计算。 

  2.误差传递。 

  3.须要初始化向量IV 

CFB模式: 

  长处: 

  1.隐藏了明文模式; 

  2.分组password转化为流模式; 

  3.能够及时加密传送小于分组的数据; 

  缺点: 

  1.不利于并行计算; 

  2.误差传送:一个明文单元损坏影响多个单元; 

  3.唯一的IV; 

ofb模式: 

  长处: 

  1.隐藏了明文模式; 

  2.分组password转化为流模式; 

  3.能够及时加密传送小于分组的数据; 

  缺点: 

  1.不利于并行计算; 

  2.对明文的主动攻击是可能的; 

  3.误差传送:一个明文单元损坏影响多个单元; 

了解这些加密模式之后,再看openssl提供的接口就好理解了。

aes.c 源代如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <openssl/aes.h>


// out的内存大小需要注意 后边有 out += AES_BLOCK_SIZE 
// 所以out 内存最小不能小于 AES_BLOCK_SIZE 
int aes_encrypt(char* in, char* key, char* out)
{
    if (!in || !key || !out)
    {
        return 0;
    }

    AES_KEY aes;
    if (AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return 0;
    }

    int len = strlen(in), en_len = 0;

    //输入输出字符串够长。而且是AES_BLOCK_SIZE的整数倍,须要严格限制
    while (en_len < len)
    {
        AES_encrypt((unsigned char*)in, (unsigned char*)out, &aes);
        in	+= AES_BLOCK_SIZE;
        out += AES_BLOCK_SIZE;
        en_len += AES_BLOCK_SIZE;
    }

    return 1;
}

int aes_decrypt(char* in, char* key, char* out)
{
    if (!in || !key || !out)
    {
        return 0;
    }

    AES_KEY aes;
    if (AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return 0;
    }

    int len = strlen(in), en_len = 0;
    while (en_len < len)
    {
        AES_decrypt((unsigned char*)in, (unsigned char*)out, &aes);
        in	+= AES_BLOCK_SIZE;
        out += AES_BLOCK_SIZE;
        en_len += AES_BLOCK_SIZE;
    }

    return 1;
}

int main(int argc, char**argv)
{
    char *data, *key = "1111222", encrypt_buffer[100] = {0}, decrypt_buffer[100] = {0};
    size_t len;

    if (argc != 2)
    {
        printf("请输入待加密的明文。\n");
        return -1;
    }

    data = argv[1];
    printf("原始数据:%s\n", data);

    len = strlen(data);
    printf("明文长度:%d\n", len);

    aes_encrypt(data, key, encrypt_buffer);
    printf("加密结果:%s\n", encrypt_buffer);

    aes_decrypt(encrypt_buffer, key, decrypt_buffer);
    printf("解密结果:%s\n", decrypt_buffer);
}

编译:

 gcc aes.c -lssl -lcrypto

运行效果:

 

 

 

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值