使用 libTomCrypt 实现 AES、HMAC、HKDF 运算
2017-12-07 18:37
246 查看
使用 libTomCrypt 实现 AES、HMAC、HKDF 运算
Qidi 2017.11.06 (Markdown & Haroopad)[b]1、libTomCrypt 简介[/b]
libTomCrypt 是一个使用 C 语言编写的开源加解密算法库,使用 WTF 协议进行授权,支持 AES、HMAC、HKDF、RSA、PRNG、BASE64 等常用加解密算法。
[b]2、基础文件[/b]
我们在使用 libTomCrypt 时会发现,调用某一类算法时总是要依赖几个特定头文件和源文件。我称这些头文件/源文件为该类算法的基础文件。
对于 AES 算法来说,这些基础文件是:
tomcrypt.h tomcrypt_argchk.h tomcrypt_cipher.h aes.c aes_tab.c compare_testvector.c crypt_argchk.c crypt_cipher_descriptor.c crypt_cipher_is_valid.c crypt_find_cipher.c crypt_register_cipher.c crypt_unregister_cipher.c zeromem.c
对于 HMAC 和 HKDF 算法来说,这些基础文件是:
tomcrypt.h tomcrypt_argchk.h tomcrypt_cipher.h aes.c aes_tab.c compare_testvector.c crypt_argchk.c crypt_hash_descriptor.c crypt_hash_is_valid.c crypt_find_hash.c crypt_register_hash.c crypt_unregister_hash.c zeromem.c
[b]3、AES 算法调用流程[/b]
使用 AES 算法时一般可以分为以下几个步骤:
注册算法描述符:
register_cipher(&aes_desc);
获取算法描述符:
idx = find_cipher("aes");
初始化算法结构体:
XXX_start(idx, IV, key, key_len, num_rounds, symmetric_XXX *XXX);
加密:
XXX_encrypt(*plain_text, *crypted_text, len, symmetric_XXX *XXX);
解密:
XXX_decrypt(*crypted_text, *plain_text, len, symmetric_XXX *XXX);
结束运算:
XXX_done(symmetric_XXX *XXX);
释放资源:
zeromem(key, sizeof(key)); zeromem(XXX, sizeof(XXX));
[b]3.1、实现 AES-128-ECB 加解密[/b]
要实现
aes-128-ecb加解密,除了要包含(#include)和引用(Makefile 中添加)第 2 节中提到的文件外,还要引用几个
ecb相关的源文件,如下:
ecb_decrypt.c ecb_done.c ecb_encrypt.c ecb_start.c
工程中截取的代码片段如下:
...
symmetric_ECB ecb;
unsigned char key[MAXBLOCKSIZE] = "1234567890abcdef" \
"1234567890abcdef" \
"1234567890abcdef" \
"1234567890abcdef" \
"1234567890abcdef" \
"1234567890abcdef" \
"1234567890abcdef" \
"1234567890abcde";
unsigned char pt[4096] = "Keep it simple and stupid."; // plain text for encrypting, place your own content here
unsigned char ct[4096];
if (register_cipher(&aes_desc) < 0) {
ALOGE("register_cipher() failed!\n");
goto exit1;
}
intidx = find_cipher("aes");
if (idx == -1) {
ALOGE("find_cipher() failed!\n");
goto exit1;
}
if (CRYPT_OK != ecb_start(idx, key, cipher_descriptor[idx].min_key_length, 0, &ecb)) {
ALOGE("ecb_start() failed!\n");
goto exit1;
}
if (CRYPT_OK != ecb_encrypt(pt, ct, sizeof(pt), &ecb)) {
ALOGE("ecb_encrypt() failed!\n");
goto exit1;
}
#if SHOW_DECRYPT
if (CRYPT_OK != ecb_decrypt(ct, at, sizeof(at), &ecb)) {
LOG("ecb_decrypt() failed!\n");
goto exit1;
}
#endif
if (CRYPT_OK != ecb_done(&ecb)) {
LOG("ecb_done() failed!\n");
goto exit1;
}
...
exit1:
...
[b]3.2、实现 AES-128-CTR 加解密[/b]
要实现
aes-128-ctr加解密,除了要包含(#include)和引用(Makefile 中添加)第 2 节中提到的文件外,还要引用几个
ctr相关的源文件,如下:
ctr_decrypt.c ctr_done.c ctr_encrypt.c ctr_start.c
工程中截取的代码片段如下:
... if (register_cipher(&aes_desc) < 0) { ALOGE("Qidi - aes-128-ctr register_cipher() failed!\n"); goto error; } idx = find_cipher("aes"); if (idx == -1) { ALOGE("Qidi - aes-128-ctr find_cipher() failed!\n"); goto error; } err = ctr_start(idx, session_iv, session_key, 16, 0, CTR_COUNTER_BIG_ENDIAN, &ctr); if (err != CRYPT_OK) { ALOGE("Qidi - ctr_start() failed!\n"); goto error; } err = ctr_encrypt((unsigned char*)input_raw, buf, 16, &ctr); if (err != CRYPT_OK) { ALOGE("Qidi - ctr_encrypt() failed!\n"); goto error; } // ctr 解密前需要再 start 初始化一次 err = ctr_start(idx, session_iv, session_key, 16, 0, CTR_COUNTER_BIG_ENDIAN, &ctr); if (err != CRYPT_OK) { ALOGE("Qidi - ctr_start() failed!\n"); goto error; } memset(input_raw, 0, 16); err = ctr_decrypt((unsigned char *)output_raw, (unsigned char *)input_raw, 16, &ctr); if (err != CRYPT_OK) { ALOGE("Qidi - ERROR: ctr_decrypt() failed!\n"); goto error; } ctr_done(&ctr); ... error: ...
[b]4、HASH 算法一般调用流程[/b]
使用 HASH 算法时,一般可以分为以下几个步骤:
注册算法描述符:
register_hash(&aes_desc);
获取算法描述符:
idx = find_hash("aes");
初始化算法结构体:
XXX_start(idx, IV, key, key_len, num_rounds, symmetric_XXX *XXX);
加密:
XXX_encrypt(*plain_text, *crypted_text, len, symmetric_XXX *XXX);
解密:
XXX_decrypt(*crypted_text, *plain_text, len, symmetric_XXX *XXX);
结束运算:
XXX_done(symmetric_XXX *XXX);
释放资源:
zeromem(key, sizeof(key)); zeromem(XXX, sizeof(XXX));
[b]4.1、实现 HMAC 运算[/b]
要实现
hmac加解密,除了要包含(#include)和引用(Makefile 中添加)第 2 节中提到的文件外,还要引用几个
hmac相关的源文件,如下:
hmac_init.c hmac_process.c hmac_memory.c hash_memory.c hmac_done.c sha256.c
工程中截取的代码片段如下:
... if (register_hash(&sha256_desc) < 0) { ALOGE("Qidi - ERROR: verify fw_resp register_hash(&sha256_desc) failed!\n"); goto error; } int idx = find_hash("sha256"); if (idx < 0) { ALOGE("Qidi - ERROR: verify fw_resp find_hash(sha256) failed!\n"); goto error; } if (CRYPT_OK != hmac_memory(idx, (unsigned char*)pre_key, 32, (unsigned char*)in_data, 36, (unsigned char*)fw_resp, &fw_resp_len)) { ALOGE("ERROR: verify fw_resp hmac_memory() failed!\n"); goto error; } ... error: ...
其中
hmac_memory()函数实际上是对
hmac_init()、
hmac_process、
hmac_done()的封装。
[b]4.2、实现 HKDF 运算[/b]
要实现
hkdf加解密,除了要包含(#include)和引用(Makefile 中添加)第 2 节中提到的文件外,还要引用几个
hkdf相关的源文件,如下:
hkdf.c sha256.c
工程中截取的代码片段如下:
... register_hash(&sha256_desc); int idx = find_hash("sha256"); ret = hkdf(idx, (unsigned char*)salt, 20, (unsigned char*)info, 20, (unsigned char*)in_data, 18, session_key_iv, 32); ...
其中
hkdf()函数实际上是对
hkdf_extract()和
hkdf_expand()的封装。
相关文章推荐
- 如何用vs2015编译与使用libtomcrypt
- VS2008下LibTomCrypt 1.17的编译和使用
- 使用libtomcrypt时候出现无法找到rijndael_enc_desc问题解决方法
- VS2008下LibTomCrypt 1.17的编译和使用
- 使用Libtomcrypt RSA/ECC等加密算法到项目中
- libtomcrypt使用
- PHP Array -- 使用数组实现矩阵的数学运算 -- PHP Matrix Math Functions
- 使用ICSharpCode.SharpZipLib.dll实现在线解压缩
- 使用位逻辑运算来实现位向量
- 使用ICSharpCode.SharpZipLib-(C#)实现解压缩文件的操作类
- ——使用『与非』运算实现权限判断
- 使用C#实现AES加密解密
- 使用异或运算实现菜单项功能的启用与关闭
- 人工神经网络简介和单层网络实现AND运算--AForge.NET框架的使用(五)
- 使用位逻辑运算实现位向量
- 使用json-lib实现的JSON产生器(Java版本)
- 使用位运算实现乘法和乘方运算
- 使用ICSharpCode.SharpZipLib.dll实现在线解压缩
- 密码库LibTomcrypt的内容介绍及分析
- 使用位逻辑运算来实现位向量