Openssl中chacha20-poly1305的使用

原理简述

chacha20-poly1305 是带有关联数据的认证加密(AEAD)AEAD是一种能够同时保证数据的保密性、 完整性和真实性的一种加密模式。
通常使用除了明文以外,会把包头的地址和端口等信息放进去一起做完整性校验。

chacha20 是流加密算法。
poly1305 是完整性校验是算法,即根据输入(加密数据和关联数据)输出16字节的认证标签。

使用方法

加密

输入项:

输入项长度(Bytes)说明
key32共享秘钥
iv12干扰项,每次不同
AADN关联数据
plaintextN待加密数据明文

输出项:

输出项长度(Bytes)说明
ciphertextN加密后的密文,长度与原始明文一致
TAG16认证标签

通常将TAG接在ciphertext密文之后。

解密

输入项:

输入项长度(Bytes)说明
key32共享秘钥
iv12干扰项,每次不同
AADN关联数据
ciphertextN待加密数据明文
TAG16认证标签

输出项:

输出项长度(Bytes)说明
plaintextN原始明文
result1完整性检查结果(1成功,0失败)

参数关联

key + iv + plaintext ===> ciphertext
ciphertext + AAD ===> TAG

AAD只参与完整性验证,不参与加密。

代码实例

代码刚验证完,没整理,凑合看,嘻嘻。

int chachapoly_test(void)
{
	/*  Key 共享秘钥 */
    unsigned char skey2[32] = {
    0x2e,0xff,0xe4,0x85,0x1e,0x23,0x72,0xef,
    0x5c,0x44,0x14,0x75,0x61,0xd8,0xf0,0xa3,
    0xde,0x91,0x09,0x00,0x24,0x03,0x51,0x3c,
    0xf2,0xf6,0x6d,0x16,0xbd,0x78,0xd2,0x63};

    int ret = 0;
    EVP_CIPHER_CTX* ctx = NULL;
    EVP_CIPHER_CTX* dctx = NULL;
	/*  干扰项 iv */
    unsigned char iv[12] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b
    };
	/*  外部关联数据 AAD */
    unsigned char aad[128] = 
    {0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,
     0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
     0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,
     0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
     0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,
     0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
     0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,
     0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26};
    unsigned char ciphertext[1024] = {0};
    unsigned char res[1024] = {0};
    
    /* 原始明文 plaintext */
    unsigned char msg[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    ctx = EVP_CIPHER_CTX_new();

    ret = EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, skey2, iv);
    printf("EncryptInit ret: %d\n", ret);

    int outlen, finallen, reslen;
	/* 加密输入 ADD */
    ret = EVP_EncryptUpdate(ctx, NULL, &outlen, aad, 32);
    ret = EVP_EncryptUpdate(ctx, NULL, &outlen, aad+64, 32);
    printf("Ret: %d Update AAD len: %d\n", ret, outlen);
	/* 加密原始数据 */
    ret = EVP_EncryptUpdate(ctx, ciphertext, &outlen, msg, 37);
    printf("Ret: %d Update len: %u\n", ret, outlen);
    print_strhex(ciphertext, outlen);
    
    ret = EVP_EncryptFinal(ctx, ciphertext, &finallen);
    printf("Ret: %d Final len: %u\n", ret, finallen);
    outlen += finallen;
    //print_strhex(ciphertext, outlen);

    /* 生成认证标签TAG */
    unsigned char* tag_data = ciphertext + outlen;
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, tag_data);
    outlen += 16;
    print_strhex(ciphertext, outlen);



    dctx = EVP_CIPHER_CTX_new();
    //iv[0] = 0x0f;
    //skey2[0] = 0xff;
    //tag_data[0] = 0x01;
    //aad[0] = 0x01;
    ret = EVP_DecryptInit_ex(dctx, EVP_chacha20_poly1305(), NULL, skey2, iv);
    printf("DecryptInit ret: %d\n", ret);

    ret = EVP_CIPHER_CTX_ctrl(dctx, EVP_CTRL_GCM_SET_TAG, 16, tag_data);
    printf("Ret: %d CTX set TAG\n", ret);
    
    ret = EVP_DecryptUpdate(dctx, NULL, &reslen, aad, 32);
    ret = EVP_DecryptUpdate(dctx, NULL, &reslen, aad+64, 32);
    printf("Ret: %d Update AAD len: %d\n", ret, reslen);

    ret = EVP_DecryptUpdate(dctx, res, &reslen, ciphertext, outlen - 16);
    printf("Ret: %d DecryUpdate once len: %u\n", ret, reslen);
    int totallen = reslen;

    ret = EVP_DecryptFinal(dctx, res, &reslen);
    printf("Ret: %d DecryptFinal len: %u\n", ret, reslen);
    //reslen += finallen;

    //print_strhex(res, totallen);
    printf("%s\n", res);
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值