OpenSSL之EVP(三)——EVP对称算法编程示例

des对称算法

源代码如下:

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

void show_hex(unsigned char * s, int len)
{
    for(int i=0; i<len; i++)
    {
        //以16进制输出,每一个字符占2位。
        printf("%02x",s[i]);
        if(19 == i % 20)
            printf("\n");
    }
    printf("\n\n");
}

int main()
{
    int ret,which=1;
    EVP_CIPHER_CTX ctx;
    const EVP_CIPHER *cipher;
    unsigned char key[24],iv[8],in[100],out[108],de[100];
    int i,len,inl,outl,total=0;
    for(i=0;i<24;i++)
    {
        memset(&key[i],i,1);
    }
    for(i=0;i<8;i++)
    {
        memset(&iv[i],i,1);
    }
    for(i=0;i<100;i++)
    {
        memset(&in[i],i+1,1);
    }
    EVP_CIPHER_CTX_init(&ctx);
    printf("please select :\n");
    printf("1: EVP_des_ede3_ofb\n");
    printf("2: EVP_des_ede3_cbc\n");
    scanf("%d",&which);
    if(which==1)
        cipher=EVP_des_ede3_ofb();
    else
        cipher=EVP_des_ede3_cbc();
    printf("原文:\n");
    show_hex(in, 100);
    ret=EVP_EncryptInit_ex(&ctx,cipher,NULL,key,iv);
    if(ret!=1)
    {
        printf("EVP_EncryptInit_ex err1!\n");
        return -1;
    }
    inl=50;
    len=0;
    EVP_EncryptUpdate(&ctx,out+len,&outl,in,inl);
    len+=outl;
    EVP_EncryptUpdate(&ctx,out+len,&outl,in+50,inl);
    len+=outl;
    EVP_EncryptFinal_ex(&ctx,out+len,&outl);
    len+=outl;
    printf("加密结果长度: %d\n",len);
    printf("加密结果:\n");
    show_hex(out, len); 
    EVP_CIPHER_CTX_cleanup(&ctx);

    /* 解密 */
    EVP_CIPHER_CTX_init(&ctx);
    ret=EVP_DecryptInit_ex(&ctx,cipher,NULL,key,iv);
    if(ret!=1)
    {
        printf("EVP_DecryptInit_ex err1!\n");
        return -1;
    }
    total=0;
    EVP_DecryptUpdate(&ctx,de+total,&outl,out,44);
    total+=outl;
    EVP_DecryptUpdate(&ctx,de+total,&outl,out+44,len-44);
    total+=outl;
    ret=EVP_DecryptFinal_ex(&ctx,de+total,&outl);
    total+=outl;
    printf("解密结果长度: %d\n",total);
    printf("解密结果:\n");
    show_hex(de, total);    
    if(ret!=1)
    {
        EVP_CIPHER_CTX_cleanup(&ctx);
        printf("EVP_DecryptFinal_ex err\n");
        return -1;
    }
    if((total!=100) || (memcmp(de,in,100)))
    {
        printf("err!\n");
        return -1;
    }
    EVP_CIPHER_CTX_cleanup(&ctx);
    printf("test ok!\n");
    return 0;
}

编译提示:

  1. 需要包含OpenSSL include 头文件目录
  2. 需要引入OpenSSL 库(libeay32.lib)。

运行结果:

这里写图片描述

这里写图片描述

注意事项

在运行EVP_des_ede3_cbc 算法时,运行结束时,会出现错误:
Run-Time Check Failure #2 - Stack around the variable 'de' was corrupted.
这里写图片描述
修复办法:
ref: http://www.cnblogs.com/flysnail/archive/2011/09/21/2184114.html

配置属性->c/c++->代码生成->基本运行时检查 为 默认值 就不会报该异常.
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenSSL中的EVP(Enveloped Data Processing)是一个高级API,提供了一种简单易用的方式来实现各种密码学算法EVP API支持对称加密、非对称加密、哈希、消息认证码(MAC)和数字签名等功能。 以下是一些使用EVP API的示例: 1. 对称加密 对称加密使用相同的密钥对数据进行加密和解密。以下代码展示了如何使用EVP API进行对称加密: ```c EVP_CIPHER_CTX *ctx; ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); EVP_EncryptUpdate(ctx, out, &outl, in, inl); EVP_EncryptFinal_ex(ctx, out + outl, &tmpl); EVP_CIPHER_CTX_free(ctx); ``` 其中,key是加密密钥,iv是初始化向量,in是输入数据,inl是输入数据长度,out是输出数据,outl是输出数据长度,tmpl是临时变量。 2. 非对称加密 非对称加密使用公钥加密数据,私钥解密数据。以下代码展示了如何使用EVP API进行非对称加密: ```c EVP_PKEY *pkey; pkey = EVP_PKEY_new(); EVP_PKEY_set1_RSA(pkey, rsa); EVP_PKEY_CTX *ctx; ctx = EVP_PKEY_CTX_new(pkey, NULL); EVP_PKEY_encrypt_init(ctx); EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING); EVP_PKEY_encrypt(ctx, out, &outl, in, inl); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); ``` 其中,rsa是RSA密钥对,in是输入数据,inl是输入数据长度,out是输出数据,outl是输出数据长度。 3. 哈希 哈希函数将任意长度的数据映射为固定长度的摘要值。以下代码展示了如何使用EVP API进行哈希: ```c EVP_MD_CTX *ctx; ctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(ctx, EVP_sha256(), NULL); EVP_DigestUpdate(ctx, in, inl); EVP_DigestFinal_ex(ctx, out, &outl); EVP_MD_CTX_free(ctx); ``` 其中,in是输入数据,inl是输入数据长度,out是输出数据,outl是输出数据长度。 4. MAC MAC是一种用于验证消息完整性和真实性的技术。以下代码展示了如何使用EVP API进行MAC: ```c EVP_MD_CTX *ctx; ctx = EVP_MD_CTX_new(); EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, pkey); EVP_DigestSignUpdate(ctx, in, inl); EVP_DigestSignFinal(ctx, out, &outl); EVP_MD_CTX_free(ctx); ``` 其中,pkey是私钥,in是输入数据,inl是输入数据长度,out是输出数据,outl是输出数据长度。 5. 数字签名 数字签名是一种用于验证消息来源和完整性的技术。以下代码展示了如何使用EVP API进行数字签名: ```c EVP_MD_CTX *ctx; ctx = EVP_MD_CTX_new(); EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, pkey); EVP_DigestSignUpdate(ctx, in, inl); EVP_DigestSignFinal(ctx, NULL, &slen); EVP_SignFinal(ctx, out, &outl, pkey); EVP_MD_CTX_free(ctx); ``` 其中,pkey是私钥,in是输入数据,inl是输入数据长度,out是输出数据,outl是输出数据长度,slen是临时变量。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值