上海动信微电子科技有限公司

联系我们

13482583038

技术资料

您的当前位置:幸运蛋蛋平台网址 > 新闻中心 > 技术资料

DX8加密芯片应用开发手册(六)

发布时间:2017-09-05浏览次数:载入中...来源:上海动信微电子科技有限公司


7.2.基于标识数据加解密函数(DX82C04):


DX8加密芯片应用开发手册第六部分主要讲解DX82C04物联网安全加密芯片在基于标识认证实现数据加解密中函数的实现方法!


7.2.1. 基本原理

DX82C04物联网加密芯片的基本原理图

用户执行数据加密或者解密运算需要两个步骤:

l  产生加密密钥或者产生解密密钥

l  加密明文或者解密密文

1.  加密方DX82芯片首先根据输入的标识参数和内部产生的真随机数,共同生成随机动态的会话密钥(真正的数据加解密密钥,动态存储在DX82芯片内部,永远无法读出),然后对明文数据进行加密。

2.  加密方将动态的随机数和密文传给解密方。

3. 解密方收到数据后,首先利用动态的随机数恢复会话密钥,然后对密文数据进行解密。

说明1只有加密密钥产生成功后才能执行数据加密,同样只有解密密钥产生成功后才能执行数据解密,任何错误都会使DX82芯片内部密钥产生标志清除。

说明2会话密钥只能由拥有加密方输入的标识参数的DX82芯片才能恢复,因此加密方对谁进行加密,就只有谁能解密,即使第三方获得了动态的随机数和密文也无法恢复真正的会话密钥。


7.2.2. 会话密钥产生模式


DX82每次产生会话密钥的输入参数主要依赖:芯片内部自动产生的真随机数、群密钥、可选的对方8个字节SN序列号、可选的对方7个字节UID号以及双方可临时约定的8个字节任意OT值共同运算产生。根据输入可选的参数相,可以实现一对一私聊和一对多群聊。

关于群密钥,DX82芯片内置了一个固定的公共密钥域和一个用户可设的私有密钥域(KEYB),DX82芯片之间可以选择私有域内加解密通信,也可选择公共域内实现跨群加解密通信,根据可选的输入参数相可以有以下8种模式:

 

会话密钥模式

群密钥

选择

可选项

备注

SN

UID

OT

PUBLIC

公共域

 

 

 

公共域群聊

PUBLIC_OT

 

 

Yes

公共域临时群聊

PUBLIC_SN

Yes

 

 

公共域私聊

PUBLIC_SNOT

Yes

 

Yes

公共域临时群私聊

PUBLIC_ID

 

Yes

 

公共域私聊

PUBLIC_IDOT

 

Yes

Yes

公共域临时群私聊

PUBIC_IDSN

Yes

Yes

 

公共域私聊

PUBLIC_IDSNOT

Yes

Yes

Yes

公共域临时群私聊

PRIVATE

私有域

KEYB

 

 

 

私有域群聊

PRIVATE_OT

 

 

Yes

私有域临时群聊

PRIVATE_SN

Yes

 

 

私有域私聊

PRIVATE_SNOT

Yes

 

Yes

私有域临时群私聊

PRIVATE_ID

 

Yes

 

私有域私聊

PRIVATE_IDOT

 

Yes

Yes

私有域临时群私聊

PRIVATE_IDSN

Yes

Yes

 

私有域私聊

PRIVATE_IDSNOT

Yes

Yes

Yes

私有域临时群私聊

 

说明1SN是出厂后永远物理唯一的,UID是用户设定的逻辑唯一,UID可以是用户自定义的编码规则,也可以绑定现有的编码规范,如手机号、QQ号等,便于记忆,SNUID单独参与会话密钥产生均可实现私聊,但SNUID一起参与唯一性会更强。

说明2OT值可以理解为临时的会议密钥或者临时的验证码,需要通过其他方式告知对方。


7.2.3. 数据结构定义


7.2.3.1.  CRYPTO_TYPE

             C语言:                                              Java语言:

DX82的C语言CRYPTO_TYPE           DX82的Java语言CRYTO_TYPE



7.2.3.2.  CRYPTO_MODE

            C语言:                                                           Java语言:

DX82的C语言的CRYPTO_MODE       DX82的Java语言的CRYPTO_MODE



7.2.3.3.  CRYPTO_PARA

           C语言:                                        Java语言:

DX82的C语言的CRYPTO_PARA         DX82的Java语言的CRYPTO_PARA



seedDX82芯片产生会话密钥时,在芯片内部自动产生动态的随机数

slen指定上述动态随机数的长度


7.2.4. 直接初始化会话密钥


u8_x DX8_InitSessionKey(u8_x *buf);

功能描述:直接初始化会话密钥

参数:    buf   输入的16个字节会话密钥

返回值:  初始化成功返回0,否则返回错误代码

说明: 该函数功能是直接初始化会话密钥,适合于事先双方直接约定会话密钥场合,不需要动态产生会话密钥,初始化成功后,接下来只能执行数据加密或者解密的命令,其他任何其他命令或者错误都将清除密钥初始化标志。

示例代码:

u8_x rv;

u8_x buf[16];

rv = DX8_ InitSessionKey (buf);

if (rv) {

   printf(“Initial Session Key failed, rv = 0x%.2x\n”, rv);

   return rv;

}


7.2.5. 根据标识产生会话密钥


u8_x DX8_GenSessionKey( CRYPTO_TYPE type,

CRYPTO_MODE mode,

CRYPTO_PARA *para );

功能描述:根据CRYPTO_TYPE, CRYPTO_MODE, CRYPTO_PARA产生相应的会话密钥

参数:    type  会话密钥的类型,包括加密、解密、签名、验签的会话密钥

          mode  会话密钥的模式,请见前文会话密钥产生模式

          para  产生会话密钥的参数,请见示例代码描述

返回值:  产生成功返回0,否则返回错误代码

 

示例代码1(加密方:产生加密会话密钥):

u8_x rv;

CRYPTO_PARA para;

//  PRIVATE_IDSNOT模式为例,需要对para.ID, para.SN, para.OT赋值

//  1. 请赋值解密方ID, 如:

para.ID = 0xxxxxxx;

//  2. 请赋值解密方SN, 如:

para.SN = 0xxxxxxx;

//  3. 请赋值临时OT, 如:

para.OT = 0xxxxxxx;

//  4. 加密需要使用动态随机数的长度,最大32个字节,如:

para.slen = 32;

//  5. 产生加密的会话密钥:

rv = DX8_ GenSessionKey (CRYPTO_ENC, PRIVATE_IDSNOT, ¶);

if (rv) {

      printf(“Generate Session Key failed, rv = 0x%.2x\n”, rv);

      return rv;

}

说明1加密方会话密钥产生成功后,para.seed将存储DX82芯片返回指定长度的动态随机数,该随机数需要和密文一起传给解密方

说明2加密方会话密钥产生成功后,接着只能执行数据加密的操作,其他任何命令和错误都会清除芯片内部的会话密钥产生标志

 

示例代码2(解密方:产生解密会话密钥):

u8_x rv;

CRYPTO_PARA para;

// 不管什么模式,产生解密会话密钥时,使用的是芯片自身的SNID

//  PRIVATE_IDSNOT为例,需要对para.OT赋值,

//  1. 请赋值加密方使用的OT值,如:

para.OT = 0xxxxxx

//  2. 请赋值加密方的产生的动态随机数,如:

para.seed = 0xxxxxx

//  3. 请赋值加密方的产生的动态随机数的长度,如:

para.slen = 32

//  4. 产生解密会话密钥:

rv = DX8_ GenSessionKey (CRYPTO_DEC, PRIVATE_IDSNOT, ¶);

if (rv) {

      printf(“Generate Session Key failed, rv = 0x%.2x\n”, rv);

      return rv;

}

说明1加解密双方必须使用相同会话密钥模式,否则无法产生正确会话密钥

说明2解密会话密钥产生成功后,接着只能执行数据解密的操作,其他任何命令和错误都会清除芯片内部的会话密钥产生标志

示例代码3(签名方:产生签名会话密钥):

u8_x rv;

CRYPTO_PARA para;

// 不管什么模式,产生签名会话密钥时,使用芯片自身的SNID

//  PRIVATE_IDSNOT为例,只需对para.OT赋值

//  1. 请赋值临时OT, 如:

para.OT = 0xxxxxx

//  2. 签名需要使用动态随机数的长度,如:

para.slen = 32

//  3. 产生签名的会话密钥

rv = DX8_ GenSessionKey (CRYPTO_SIG, PRIVATE_IDSNOT, ¶);

if (rv) {

      printf(“Generate Session Key failed, rv = 0x%.2x\n”, rv);

      return rv;

}

说明1签名会话密钥产生成功后,para.seed将存储DX82芯片返回指定长度的动态随机数,该随机数需要和签名值一起传给验签方

说明2签名会话密钥产生成功后,接着只能执行数据签名的操作,其他任何命令和错误都会清除芯片内部的会话密钥产生标志

 

示例代码4(验签方:产生验签会话密钥):

u8_x rv;

CRYPTO_PARA para;

//  PRIVATE_IDSNOT为例,需要对para.ID, para.SN, para.OT赋值

//  1. 请赋值签名方ID, 如:

para.ID = 0xxxxx

//  2. 请赋值签名方SN, 如:

para.SN = 0xxxxx

//  3. 请赋值签名方使用的OT, 如:

para.OT = 0xxxx

//  4. 请赋值签名方产生的动态随机数, 如:

para.seed = 0xxxxx

//  5. 上述动态随机数的长度,如:

para.slen = 32

//  6. 产生验签会话密钥:

rv = DX8_ GenSessionKey (CRYPTO_VSIG, PRIVATE_IDSNOT, ¶);

if (rv) {

      printf(“Generate Session Key failed, rv = 0x%.2x\n”, rv);

      return rv;

}

说明:签名方和验签方必须使用相同会话密钥模式,否则无法产生正确会话密钥


7.2.6. Crypto计算


u8_x DX8_DoCrypto( CRYPTO_TYPE type,

u8_x  *din,

u8_x  *dout,

u16_x len );

功能描述:根据指定的CRYPTO_TYPE对输入数据进行Crypto计算

参数:    type   crypto计算类型,包括加密、解密、签名、验签

          din    输入数据

          dout   输出数据

          len    计算数据的长度

返回值:  计算成功返回0,否则返回错误代码

说明:在进行指定的crypto类型计算前,必须要先直接初始化会话密钥或者产生相应的会话密钥,否则返回操作权限错误,会话密钥产生成功后,可连续多次执行相应的crypto计算,任何其他的命令都会清除DX82芯片内部的会话密钥标志。

示例代码:

u8_x rv;

u8_x din[1024];

u8_x dout[1024];

// 加密运算

rv = DX8_ GenSessionKey (CRYPTO_ENC, PRIVATE_IDSNOT, ¶);

rv = DX8_DoCrypto(CRYPTO_ENC, din, dout, 1024);

// 解密运算

rv = DX8_ GenSessionKey (CRYPTO_DEC, PRIVATE_IDSNOT, ¶);

rv = DX8_DoCrypto(CRYPTO_DEC, din, dout, 1024);

// 签名运算

rv = DX8_ GenSessionKey (CRYPTO_SIG, PRIVATE_IDSNOT, ¶);

rv = DX8_DoCrypto(CRYPTO_SIG, din, dout, 1024);

// 验签运算

rv = DX8_ GenSessionKey (CRYPTO_VSIG, PRIVATE_IDSNOT, ¶);

rv = DX8_DoCrypto(CRYPTO_VSIG, din, dout, 1024);


7.3.用户SHA1计算(DX82


DX82芯片为用户提供了硬件SHA1模块,可方便主机的进行摘要计算,减轻主机计算能力,一次完整SHA1计算分为三个步骤:

l  初始化

l  一次或者多次加载数据

l  获取计算结果


7.3.1. SHA1初始化


u8_x DX8_Sha1Init(u8_x flag);

功能描述:初始化DX82芯片硬件SHA1

参数:    flag, 0: Lib库软件计算, 1DX8芯片计算

返回值:  初始化成功返回0,否则返回错误代码


7.3.2. SHA1数据加载


u8_x DX8_Sha1Update(u8_x *message, u16_x len);

功能描述:SHA1消息数据的输入,可以多次调用此函数进行数据加载

参数:    message   消息输入

          len         消息长度

返回值:  数据加载成功,否则返回错误代码


7.3.3. 获取SHA1计算结果


u8_x DX8_Sha1Final(u8_x *digest);

功能描述:获取SHA1摘要计算结果

参数:    digest   返回的结果数据,20个字节

返回值:  执行成功返回0,否则返回错误代码

SHA1示例代码:

u8_x rv; u8_x message[1024]; u8_x digest[20];

rv = DX8_Sha1Init();

rv = DX8_Sha1Update (message,1024); // 一次或者多次加载

rv = DX8_Sha1Final(digest);

 

7.4.软件流加密函数


此部分库函数全部上位机软件计算,不访问硬件DX8芯片,供嵌入式系统安全协议开发,用户可采用此部分的函数对明文数据进行预先软件加密变换,更加增强系统的安全性能。


7.4.1. 初始化流加密密钥:


u8_x Lib_InitStreamKey(u8_x *buf, u8_x *seed, u8_x slen);

功能描述:初始化流加密密钥

参数:    buf   输入16个字节的密钥

          seed  输入的随机种子

          slen  seed的字节长度,最大为32个字节

返回值:  执行成功返回0,否则返回错误代码


7.4.2. 流加密:


u8_x Lib_StreamEncryption(u8_x *din, u8_x *dout, u16_x len);

参数:    din    输入明文数据

          dout   输出密文数据

          len    计算数据的长度

返回值:  计算成功返回

【返回列表】
jJ0xB1OwwrkLV9yI+Ft7LmqB9B021S0kS/2Azpec0byB1EHllJ47Etzu8Xn8NPz2O1Atzf61lsaKuagicZSOETLL0ZRx3V1zsxXJKglY+9MAi7rSTq3GIM9W0xB8XKO/KfCywedWs93qNy7ER/O7E3UHte/fgdh/CVbX0EvlJwdLdu2JrwVAZ2foc5UGAZ+icOLuYX+PI5Bfa+25djf2Ow==