c++代码实现tea加密算法的实例详解

 更新时间:2020年04月11日 09:23:11   作者:飞刀又见飞刀  
这篇文章主要介绍了c++代码实现tea加密算法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

通过c++来实现tea加密算法,最终编译成so文件,以JNI的方式提供给客户端调用,主要需要解决以下三个问题:

  • 实现tea算法,这都有开源的代码可以实现;
  • 解决padding问题;
  • 密钥做一个混淆,防止编译生成的库文件方便的被逆向拿到;

对于tea的加密算法,有成熟的各语言代码可以借鉴,下面是C++的实现:

static void tea_encrypt(uint32_t *v, uint32_t *k) {
 uint32_t v0 = v[0], v1 = v[1], sum = 0, i;
 uint32_t delta = 0x9e3779b9;
 uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];

 for (i = 0; i < tea_round; i++) {
 sum += delta;
 v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
 v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
 }

 v[0] = v0;
 v[1] = v1;
}

static void tea_decrypt(uint32_t *v, uint32_t *k) {
 uint32_t v0 = v[0], v1 = v[1], sum, i;
 sum = (tea_round == 16) ? 0xE3779B90 : 0xC6EF3720;

 uint32_t delta = 0x9e3779b9;
 uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
 for (i = 0; i < tea_round; i++) {
 v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
 v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
 sum -= delta;
 }

 v[0] = v0;
 v[1] = v1;
}

生成密钥,并对密钥做一定的混淆

static uint32_t tea_key[4] = {
 0x34561234, 0x111f3423, 0x34d57910, 0x00989034
};

static uint32_t salt = 0x12031243;
static int tea_round = 16;

//做简单的混淆
static void confuse_key(uint32_t *key) {
 for (int i = 4; i > 0; i--) {
 key[4 - i] = tea_key[i - 1] ^ salt;
 }
}

最后要实现加密算法的padding,首先思考一个问题,为什么要padding呢?

因为Tea是块加密算法,8个字节为一个块。而在现实的场景中,不会所有的要加密的数据都8的倍数。比如我要加密15,35等字节该怎么办?那么这里需要涉及到两个操作:

  • 加密的时在不足8个字节的部分进行填充,直至待加密数据为8的倍数;
  • 加密时将填充的部分去掉;

那么,填充的数据是必须要有一定规则的,解密的人才知道这部分数据是填充的,而非真实的原始数据。填充部分必须有包含有表示填充长度的字段。目前比较常用的是PKCS#7填充法;即:

末尾填充的每个字节均为填充长度

比如填充一个字节就是: 0x01

填充5个字节就是: 0x05,0x05,0x05,0x05,0x05;

还有一个问题:

如果加密的字段正好为8的倍数,需不需要padding呢?

答案是也需要的,因为如果没有padding,解密者可能会把原始数据当做padding来解析(如果此时原始数据的最后几位恰好与某种padding编码相同),那么就解密出错了。

bool encrypt(const void *input, int input_len, DataBuffer &out) {
 if (input == NULL || input_len <= 0)
 return false;

 unsigned int rest_len = input_len % TEA_BLOCK_SIZE;
 //padding是必须带的,即便是TEA_BLOCK_SIZE的整数倍,也要加panding;
 //如果input_len % TEA_BLOCK_SIZE = 0, 正好是8的倍数,那么rest_len = 0; padding_len = TEA_BLOCK_SIZE 补8个字节;
 unsigned int padding_len = TEA_BLOCK_SIZE - rest_len;

 int blocks = (input_len + padding_len) / TEA_BLOCK_SIZE;
 out.expand(blocks * TEA_BLOCK_SIZE);
 out.writeBytes((const void *) input, input_len);

 //放入padding
 for (int i = 0; i < padding_len; i++) {
 out.writeInt8(padding_len);
 }

 uint32_t key[4];
 confuse_key(key);

 uint32_t *data = (uint32_t *) out.getData();
 for (int i = 0; i < blocks; i++) {
 tea_encrypt((uint32_t *) (data + 2 * i), key);
 }

 return true;
}

bool decrypt(const void *input, int input_len, DataBuffer &out) {
 if (input == NULL || input_len < 8)
 return false;

 int blocks = input_len / 8;
 out.expand(blocks * 8);
 out.writeBytes((const void *) input, blocks * 8);

 uint32_t key[4];
 confuse_key(key);

 uint32_t *data = (uint32_t *) out.getData();
 for (int i = 0; i < blocks; i++) {
 tea_decrypt((uint32_t *) (data + 2 * i), key);
 if (i == blocks - 1) {
  //最后一个block,必定包含padding,需要把padding拿出来;
  uint8_t padding_len = ((uint8_t *) (data + 2 * i))[TEA_BLOCK_SIZE - 1];
  out.stripData(padding_len);
 }
 }

 return true;
}

完整的代码已经放到github上。https://github.com/kumustone/...

总结

到此这篇关于c++代码实现tea加密算法的实例详解的文章就介绍到这了,更多相关TEA加密算法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ Boost MultiArray简化使用多维数组库

    C++ Boost MultiArray简化使用多维数组库

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • C语言strtod()函数案例详解

    C语言strtod()函数案例详解

    这篇文章主要介绍了C语言strtod()函数案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++ 程序抛出异常后执行顺序说明

    C++ 程序抛出异常后执行顺序说明

    这篇文章主要介绍了C++ 程序抛出异常后执行顺序说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • C++用mysql自带的头文件连接数据库

    C++用mysql自带的头文件连接数据库

    现在正做一个接口,通过不同的连接字符串操作不同的数据库。要用到mysql数据库。通过网上的一些资料和自己的摸索,大致清楚了C++连接mysql的方法。可以通过2种方法实现。第一种方法是利用ADO连接,第二种方法是利用mysql自己的api函数进行连接。今天主要来讲解下使用API
    2016-07-07
  • c++动态内存管理与智能指针的相关知识点

    c++动态内存管理与智能指针的相关知识点

    为了更容易同时也更安全地使用动态内存,新的标准库提供了两种智能指针(smart pointer)类型来管理对象,下面这篇文章主要给大家介绍了关于c++动态内存管理与智能指针的相关知识点,需要的朋友可以参考下
    2022-03-03
  • c++虚函数与虚函数表原理

    c++虚函数与虚函数表原理

    这篇文章主要介绍了c++虚函数与虚函数表原理,用virtual 修饰的成员函数叫虚函数,下面围绕c++虚函数与虚函数得相关资料展开内容,需要的朋友可以参考一下
    2021-12-12
  • C语言实现简单扫雷小游戏

    C语言实现简单扫雷小游戏

    这篇文章主要为大家详细介绍了C语言实现简单扫雷小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • C语言入门篇--变量的左值和右值

    C语言入门篇--变量的左值和右值

    本篇文章是基础篇,适合c语言刚入门的朋友,本文对初识c语言的指针和指针变量做了简单的分析,帮助大家快速入门c语言的世界,更好的理解c语言
    2021-08-08
  • C语言中二维数组作为函数参数来传递的三种方法

    C语言中二维数组作为函数参数来传递的三种方法

    这篇文章主要给大家介绍了关于C语言中二维数组作为函数参数来传递的三种方法,文中通过示例代码介绍的非常详细,对大家学习或者使用C语言有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • C语言学习之指针的使用详解

    C语言学习之指针的使用详解

    想突破C语言的学习,对指针的掌握是非常重要的,本文为大家总结了C语言中指针的相关知识点,文中的示例代码讲解详细,感兴趣的小伙伴可以学习一下
    2022-10-10

最新评论