遇到的加密算法

栏目: 编程工具 · 发布时间: 6年前

内容简介:最近开发项目,遇到了各种见过没见过的算法。总结整理一下。AES 是对称加密算法,也就是用相同的秘钥加密和解密。它有这些特点:1、是分组加密,每个加密块大小为 128 位,即 16 个字节。

最近开发项目,遇到了各种见过没见过的算法。总结整理一下。

AES 算法

AES 是对称加密算法,也就是用相同的秘钥加密和解密。它有这些特点:

1、是分组加密,每个加密块大小为 128 位,即 16 个字节。

2、秘钥是 128/192/256 位。秘钥一般写为十六进制的 hex 格式,128 位秘钥就是 32 位的 hexcode。进行运算时需要将 hexcode(string 类型) 变为二进制字节流(char[16]类型)。

3、AES 有四种加密方式,常用的有 ECB 模式和 CBC 模式。

ECB 模式

ECB 指电子密码本模式 Electronic codebook。

AES 是分组加密,以 16 个字节为一组,如果加密数据最后一个组不够 16 个字节,就需要填充为 16 个字节。这个填充方式就叫 padding。padding 方式有 zeropadding/pkcs5padding/pkcs7padding。

ECB 是最简单的 AES 算法,用秘钥分别对填充后的分组数据进行加密得到密文。所以密文和明文的长度成正比。

遇到的加密算法

使用 OpenSSL 库的 API 如下:

#define COMM_AES_BLOCK_SIZE 16

int AES_ECBEncrypt(const char * sSource, const int iSize,
		const char * sKey, int iKeySize, std::string * poResult)
{
	poResult->clear();
	int padding = COMM_AES_BLOCK_SIZE - iSize % COMM_AES_BLOCK_SIZE;

	char * tmp = (char*)malloc(iSize + padding);
	memcpy(tmp, sSource, iSize);
	memset(tmp + iSize, padding, padding);
	poResult->reserve( iSize + padding);
	unsigned char key[COMM_AES_BLOCK_SIZE] = {0};
	memcpy(key, sKey, iKeySize > COMM_AES_BLOCK_SIZE 
	? COMM_AES_BLOCK_SIZE : iKeySize );

	AES_KEY aesKey;
	AES_set_encrypt_key(key, 8 * COMM_AES_BLOCK_SIZE, &aesKey);
	unsigned char out[ COMM_AES_BLOCK_SIZE ] = { 0 };
	for (int i = 0; i < iSize + padding; i += COMM_AES_BLOCK_SIZE) {
		AES_ecb_encrypt((unsigned char*)tmp + i, out, &aesKey,
		AES_ENCRYPT);
		poResult->append((char*)out, COMM_AES_BLOCK_SIZE);
	}
	free(tmp);
	return 0;
}

CBC 模式

CBC 指密码分组链接模式 Cipher-block chaining。

CBC 相比 ECB 会复杂一些,它将上一次加密得到的结果与本次的数据块异或之后再进行加密。这样还需要一个初始的异或数据,叫做初始化向量 IV。

遇到的加密算法

使用 OpenSSL 库的 API 如下:

static const int COMM_AES_BLOCK_SIZE = 16;
static const int COMM_AES_IV_SIZE = 16;
static const int COMM_AES_KEY_SIZE = 16;
static const int COMM_AES_PADDING_SIZE = 16;

int AES_CBCEncrypt( const char * sSource, const int iSize,
		const char * sKey, int iKeySize, std::string * poResult )
{

	poResult->clear();
	int padding = COMM_AES_PADDING_SIZE - iSize % COMM_AES_PADDING_SIZE;

	char * tmp = (char*)malloc( iSize + padding );
	memcpy( tmp, sSource, iSize );
	memset( tmp + iSize, padding, padding );
	
	unsigned char * out = (unsigned char*)malloc( iSize + padding );

	unsigned char key[ COMM_AES_KEY_SIZE ] = { 0 };
	unsigned char iv[ COMM_AES_IV_SIZE ] = { 0 };
	memcpy(key, sKey, COMM_AES_KEY_SIZE);
	memcpy(iv,"\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30 /
		\x30\x30\x30\x30\x30", 16); // 这里按照约定设置 

	AES_KEY aesKey;
	AES_set_encrypt_key( key, 8 * COMM_AES_BLOCK_SIZE, &aesKey );
	AES_cbc_encrypt((unsigned char *)tmp, out, iSize + padding, 
		&aesKey, iv, AES_ENCRYPT);

	poResult->append((char*)out, iSize + padding);
	free( tmp );
	free( out );
	return 0;
}

银行通用 MAC 加密算法

银行 ATM 通信经常使用 MAC 加密算法来当签名,它们会使用加密机来生成这个签名。这次遇到的机构使用卫士通 SJL05 型金融数据加密机。而我们使用软加密的方式来模拟加密机进行加密。

加密机原理

加密机有两个秘钥:主秘钥和工作秘钥。我理解的加密机工作流程是这样的:用户任意输入一个工作秘钥 A,加密机对 A 使用主秘钥 B 进行 ECB 加密得到 C(PMAK),然后对 C 进行 3DES 加密得到 D。D 会作为和加密机通信的秘钥 MAK,作为通信报文字段。

因此,软加密需要用加密机主秘钥 ECB 加密工作秘钥,得到明文加密秘钥(PMAK)。即软加密 MAC 算法中输入的秘钥。

MAC 算法

1、将需要加密的数据按照 8 个字节分组(不满 8 个字节则进行填充),然后两两异或,最终得到 8 字节的数据

2、将 8 字节的数据转换为 16 长度的 hex 十六进制数据

3、对十六进制数据进行 CBC 加密得到最终 MAC

参考

AES 的工作模式

SJL05金融数据加密机 程序员 手册


以上所述就是小编给大家介绍的《遇到的加密算法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

精通EJB

精通EJB

罗曼 / 第1版 (2005年9月1日) / 2005-9 / 69.0

本书是EJB组件技术教程,专注于EJB的概念、方法、开发过程的介绍。全书共分为4个部分,首先对EJB编程基础进行介绍,其次重点关注EJB编程的具体内容和过程,然后对高级EJB进行了阐述,最后的附录收集了EJB组件技术相关的其他内容。作为一本交互性好、读起来有趣、涉及到EJB中各方面知识的书籍,本书确信这正是你所寻找的。  本书是关于EJB 2.1的经典书籍,是EJB开发者必备的参考书。全书共分为3......一起来看看 《精通EJB》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换