美文网首页
有关AesGCM算法的一些总结

有关AesGCM算法的一些总结

作者: 秦砖 | 来源:发表于2020-08-21 15:52 被阅读0次

AesGCM是微信底层通信协议中使用的一种最为重要的加解密算法,在尝试使用OpenSSL库实现这套算法的过程中,遇到了以下几个值得注意的点:

无补位

在ECB/CCB模式下,补位信息是算法实现必须考虑的一个维度。但在GCM模式下,补位信息是完全不需要考虑的,明文与密文有着相同的长度。

不同维度

在普通的Aes加解密算法中,需要从key/iv/padding/mode这四个维度来考虑算法的实现。而AesGcm算法中却需要从下面这几个维度来实现算法:

  • Key,加解密Key
  • IV,初始化向量
  • aad,具体含义与作用不甚了了,但此维度无法忽略
  • tag,可选维度,微信实现中,该数据为16个字节,被拼接到了密文的后面

java加密OpenSSL解密

微信底层通信协议中,服务端下发的密文数据总是比明文数据长了16个字节,导致这种现象的主要原因是微信实现时将加密使用的tag信息拼接到了密文数据中,客户端使用JAVA接口解密时,在接口的内部能够自动的截取tag信息后再解密出明文数据。我并不能确认这种方式是BouncyCastle的固有实现还是微信自己的独有实现。关于拼接这块的逻辑,可以参见这里

当使用OpenSSL实现解密微信下发的密文数据时,如果不知道拼接tag这层逻辑时,是不可能成功解密出明文数据的。

最终代码

int encryptAesGcm(unsigned char* plaintext, int plaintextLen, unsigned char* add, int addLen, unsigned char* key, unsigned char* iv, int ivLen, unsigned char* ciphertext, unsigned char* tag)
{
    int len = 0;
    int ciphertextLen = 0;
    int ret = 0;
    
    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
    do{
        ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
        if (ret != 1) {
            break;
        }
        EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivLen, NULL);
        ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv);
        if (ret != 1) {
            break;
        }
        
        ret = EVP_EncryptUpdate(ctx, NULL, &len, add, addLen);
        if (ret != 1) {
            break;
        }
        ret = EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintextLen);
        if (ret != 1) {
            break;
        }
        ciphertextLen = len;
        ret = EVP_EncryptFinal_ex(ctx, ciphertext + len, &len);
        if (ret != 1) {
            ciphertextLen = 0;
            break;
        }else{
            ciphertextLen += len;
        }
        EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag);
    }while (0);
    
    EVP_CIPHER_CTX_free(ctx);
    return ciphertextLen;
}

int decryptAesGcm(unsigned char* ciphertext, int ciphertextLen, unsigned char* add, int addLen, unsigned char* key, unsigned char* iv, int ivLen, unsigned char* tag, int tagLen, unsigned char* plaintext)
{
    int length = 0;
    int tempLen = 0;
    int ret = 0;
    EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
    do{
        ret = EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
        if (ret != 1) {
            break;
        }
        ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivLen, NULL);
        if (ret != 1) {
            break;
        }
        
        ret = EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv);
        if (ret != 1) {
            break;
        }

        ret = EVP_DecryptUpdate(ctx, NULL, &tempLen, add, addLen);
        if (ret != 1) {
            break;
        }
        ret = EVP_DecryptUpdate(ctx, plaintext, &tempLen, ciphertext, ciphertextLen);
        if (ret != 1) {
            break;
        }
        length = tempLen;
        
        EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag);
        ret = EVP_DecryptFinal_ex(ctx, plaintext + tempLen, &tempLen);
        if (ret != 1) {
            length = 0;
            break;
        }else{
            length += tempLen;
        }
    }while (0);
    EVP_CIPHER_CTX_free(ctx);
    return length;
}

相关文章

  • 有关AesGCM算法的一些总结

    AesGCM是微信底层通信协议中使用的一种最为重要的加解密算法,在尝试使用OpenSSL库实现这套算法的过程中,遇...

  • 常用算法及其伪代码

    因为准备有关于算法分析与设计的考试,所以对一些经典的算法问题做了总结。 一、分治策略 分(Divide)将规模为n...

  • 基础查找算法分析

    在之前学习了一些排序算法,得出了基础排序算法的总结。之后学习了一些查找算法,今天来对于基础的一些查找算法进行总结。...

  • 一些有关算法的

    字符串模式匹配算法 字符串的KMP算法详解部分匹配表(即)向右移一位就可以得到next数组。字符串模式匹配算法 R...

  • 数据结构—树

    应用本身就是算法和数据结构和集合,做一段时间应用开发,最近有时间总结一些有关数据结构和算法的知识,希望提供自己开发...

  • 2019-03-04

    总结一些机器学习算法步骤:

  • C++编写算法(一)——排序问题

    学习《算法》的心得总结,一些观点通过阅读书目自行总结,如有雷同,纯属巧合。另一些观点摘自《算法》一书。 一、选择排...

  • 浅谈排序算法

    排序算法有很多种,今天先谈谈一些简单的排序算法。包括桶排序、冒泡排序和快速排序算法。后期总结各种排序算法。 桶排序...

  • 程序员常见算法的那些事

    面试的时候经常会被问算法的事情,今天就这个问题查找了一些算法的总结! 算法一:快速排序算法 快速排序是由东尼·霍尔...

  • 常见数据结构与算法整理总结(下)

    这篇文章是常见数据结构与算法整理总结的下篇,上一篇主要是对常见的数据结构进行集中总结,这篇主要是总结一些常见的算法...

网友评论

      本文标题:有关AesGCM算法的一些总结

      本文链接:https://www.haomeiwen.com/subject/kvnujktx.html