目录

  • ATECC508A芯片开发笔记(七):实现对数据数字签名(Sign)并验证(Verify)证书签名
    • 一、数据签名、验证基本流程
    • 二、利用508对数据签名并验证 代码实现:
      • Sign(数字签名)实现:
      • Verify(验签)实现:
    • 三、X.509证书验证
    • 四、实现代码:
  • 博主热门文章推荐:

ATECC508A芯片开发笔记(七):实现对数据数字签名(Sign)并验证(Verify)证书签名

  • 一、数据签名、验证基本流程
  • 二、利用508对数据签名并验证 代码实现:
  • 三、X.509证书验证

本节介绍利用508对证书数据进行签名、验证的步骤和原理。


一、数据签名、验证基本流程

由网络安全知识我们知道,对数据进行签名,其实就是用私钥加密而已,而验证签名就是用该私钥对应的公钥进行解密。

而如果对整个数据签名,会造成运算量大要验证数据多等缺点,因此实际应用中,一般是对原始数据算一个通过Hash算法算一个Hash值,Hash值唯一会保证数据完整性,然后再对该Hash值进行签名

因此只需验证该签名数据,并再算一次Hash与解密后的签名数据进行比较,就实现了保证数据的完整性以及身份认证双重效果。


二、利用508对数据签名并验证 代码实现:


void SignAndVerify_508Demo(uint8_t *Buffer)
{uint8_t SHA_DATA[32] = {0};uint8_t Signature_Out[64] = {0};bool verified = 0; int err = 0;err = atecc508_init(ATECC508_DEV_I2C_ADDRESS); //508A initassert_noerr(err);err = ComputeSHA256withOneStep(Buffer,sizeof(Buffer),SHA_DATA);err = atecc508_sign_hash(SLOT_x, SHA_DATA, Signature_Out);err = atecc508_generate_public_key(SLOT_x,publickeyFromAt508);err = atecc508_verify_external_mode(SHA_DATA,Signature_Out,publickeyFromAt508,&verified);}

Sign(数字签名)实现:

函数首先对508A初始化,接着对传入的数据通过SHA256算出Hash值SHA_DATA,

  • 接着就通过508A的API atecc508_sign_hash()对这个数据签名,该函数第一个参数是Slot数,既利用该Slot存储的私钥对数据进行签名。并将签名数据输出到Signature_Out

Verify(验签)实现:

  • Verify时需要利用508A实现数据签名相应的公钥,因此首先利用atecc508_generate_public_key由Slot_x的私钥产生公钥(非对称加密中私钥可以产生公钥),存储在publickeyFromAt508

  • 之后调用atecc508_verify_external_mode()(使用External验证模式)输入SHA数据、Signature数据、解签名用的PublicKey,最后508会返回Bool型的verified,如果为1则验证成功,否则失败。

其中ComputeSHA256withOneStep()是封装实现了SHA256算法,该函数会将输入数据Buffer用SHA256算出一个Hash值(32 Byte)并输出至SHA_DATA数组。
(SHA2的软件实现方法有很多,这里不再赘述,有兴趣可以在我的这篇博客中找到SHA实现源码和典型应用:https://blog.csdn.net/HowieXue/article/details/78700694 )

//
//para in:  input Bytes, bytelength
//para out: Message_Digest SHA result
//
OSStatus ComputeSHA256withOneStep(const uint8_t *bytes, unsigned int bytecount,                               uint8_t Message_Digest[SHA256HashSize])
{SHA256Context sha256Con;SHA256Reset(&sha256Con);SHA256Input(&sha256Con, bytes, bytecount);SHA256Result(&sha256Con, Message_Digest);}

三、X.509证书验证

设备认证流程关键就是验证证书,大多数用于设备端与Cloud端之间进行双向认证,过程示例图参考如下:

而508A Lib对证书验证有一个专门的API函数来实现: · atcacert_verify_cert_hw(),(其实都是调用的atcab_verify_extern()函数)

508A有一个证书管理的大结构体:atcacert_def_t,证书的类型、SN、签名、key等都封装在了里面。如果用508A验证证书,就需要填充该结构的数据

四、实现代码:

为方便Demo,新建一个测试用的atcacert_def_t 数据cert_def_device_xxx :

atcacert_def_t cert_def_device_xxx =
{.type                   = CERTTYPE_X509,.template_id            = 0,.chain_id               = 0,.private_key_slot       = 0,.sn_source              = SNSRC_DEVICE_SN,.cert_sn_dev_loc        ={.zone               = DEVZONE_NONE,.slot               = 0,.is_genkey          = 0,.offset             = 0,.count              = 0},.issue_date_format      = DATEFMT_POSIX_UINT32_BE,  //DATEFMT_RFC5280_UTC.expire_date_format     = DATEFMT_POSIX_UINT32_BE,.tbs_cert_loc           ={.offset             = 0,.count              = 0},.expire_years           = 0,.public_key_dev_loc     ={.zone               = DEVZONE_DATA,.slot               = 0,.is_genkey          = 0,.offset             = 0,.count              = 0},.comp_cert_dev_loc      ={.zone               = DEVZONE_DATA,.slot               = 0,.is_genkey          = 0,.offset             = 0,.count              = 0},//todo.std_cert_elements      ={{   // STDCERT_PUBLIC_KEY.offset         = 0,.count          = 0},{   // STDCERT_SIGNATURE.offset         = 0, .count          = 0},{   // STDCERT_ISSUE_DATE.offset         = 0,.count          = 0},{   // STDCERT_EXPIRE_DATE.offset         = 0,.count          = 0},{   // STDCERT_SIGNER_ID.offset         = 0,.count          = 0},{   // STDCERT_CERT_SN.offset         = 0,.count          = 0},{   // STDCERT_AUTH_KEY_ID.offset         = 0,.count          = 0},{   // STDCERT_SUBJ_KEY_ID.offset         = 0,.count          = 0}},.cert_elements          = NULL,.cert_elements_count    = 0,.cert_template          = xxx_DeviceCert,.cert_template_size     = sizeof(xxx_DeviceCert),.cert_template          = 0,.cert_template_size     = 0,
};

证书验证代码如下,在填充cert_def_device_xxx中,要保证两个最基本的tbs_cert_locstd_cert_elements[STDCERT_SIGNATURE].offset设置正确,

这两个数据分别是所要验证的证书中,to be signed 部分的长度,以及Signature的位置偏移量。

       //modify cert_def tbs length and sign locationcert_def_device_xxx.tbs_cert_loc.count =  tbs_length ;cert_def_device_xxx.std_cert_elements[STDCERT_SIGNATURE].offset = SignLocation;//verify cert use 508aerr = atcacert_verify_cert_hw(&cert_def_device_xxx,Certificate->certificateData,Certificate->length,PubKey);if(err != 0)return err;elsereturn 0;

将正确参数传入atcacert_verify_cert_hw(),其返回值为0则代表验证成功。其中参数部分,Certificate是证书结构体指针,其指向了在内存中存储的证书,包括其内容和长度。

刚才提到atcacert_verify_cert_hw()内部也是调用的atcab_verify_extern(),代码如下:

int atcacert_verify_cert_hw( const atcacert_def_t* cert_def,const uint8_t*        cert,size_t cert_size,const uint8_t ca_public_key[64])
{int ret = 0;uint8_t tbs_digest[32];uint8_t signature[64];bool is_verified = false;if (cert_def == NULL || ca_public_key == NULL || cert == NULL)return ATCACERT_E_BAD_PARAMS;ret = atcacert_get_tbs_digest(cert_def, cert, cert_size, tbs_digest);if (ret != ATCACERT_E_SUCCESS)return ret;ret = atcacert_get_signature(cert_def, cert, cert_size, signature);if (ret != ATCACERT_E_SUCCESS)return ret;ret = atcab_verify_extern(tbs_digest, signature, ca_public_key, &is_verified);if (ret != ATCA_SUCCESS)return ret;return is_verified ? ATCACERT_E_SUCCESS : ATCACERT_E_VERIFY_FAILED;
}

可见,atcacert_verify_cert_hw()内部实现的就是上述流程中的步骤,先计算证书To be signed 部分的SHA256,然后从证书制定位置提取其前面数据,

最后将SHA256数据(tbs_digest)和签名数据以及PublicKey传入到atcab_verify_extern()去验证,返回验证成功与否。
(传输之间无任何Secret交换,体现了508A的安全性能保证)



博主热门文章推荐:

一篇读懂系列:

  • 一篇读懂无线充电技术(附方案选型及原理分析)
  • 一篇读懂:Android/iOS手机如何通过音频接口(耳机孔)与外设通信
  • 一篇读懂:Android手机如何通过USB接口与外设通信(附原理分析及方案选型)

LoRa Mesh系列:

  • LoRa学习:LoRa关键参数(扩频因子,编码率,带宽)的设定及解释
  • LoRa学习:信道占用检测原理(CAD)
  • LoRa/FSK 无线频谱波形分析(频谱分析仪测试LoRa/FSK带宽、功率、频率误差等)

网络安全系列:

  • ATECC508A芯片开发笔记(一):初识加密芯片
  • SHA/HMAC/AES-CBC/CTR 算法执行效率及RAM消耗 测试结果
  • 常见加密/签名/哈希算法性能比较 (多平台 AES/DES, DH, ECDSA, RSA等)
  • AES加解密效率测试(纯软件AES128/256)–以嵌入式Cortex-M0与M3 平台为例

嵌入式开发系列:

  • 嵌入式学习中较好的练手项目和课题整理(附代码资料、学习视频和嵌入式学习规划)
  • IAR调试使用技巧汇总:数据断点、CallStack、设置堆栈、查看栈使用和栈深度、Memory、Set Next Statement等
  • Linux内核编译配置(Menuconfig)、制作文件系统 详细步骤
  • Android底层调用C代码(JNI实现)
  • 树莓派到手第一步:上电启动、安装中文字体、虚拟键盘、开启SSH等
  • Android/Linux设备有线&无线 双网共存(同时上内、外网)

AI / 机器学习系列:

  • AI: 机器学习必须懂的几个术语:Lable、Feature、Model…
  • AI:卷积神经网络CNN 解决过拟合的方法 (Overcome Overfitting)
  • AI: 什么是机器学习的数据清洗(Data Cleaning)
  • AI: 机器学习的模型是如何训练的?(在试错中学习)
  • 数据可视化:TensorboardX安装及使用(安装测试+实例演示)

ATECC508A芯片开发笔记(七):实现数字签名(Sign)并校验(Verify)证书签名相关推荐

  1. ATECC508A芯片开发笔记(一):初识加密芯片

    更多技术干货,欢迎扫码关注博主微信公众号:HowieXue,一起学习探讨软硬件技术知识经验,关注就有海量学习资料免费领哦: ---------- 目录 一.ATECC508A概述: 二.ATECC50 ...

  2. ATECC508A芯片开发笔记(六):产生CSR以及申请证书(X.509)流程及其内容分析

    目录 ATECC508A芯片开发笔记(六):产生CSR以及申请证书(X.509)流程及其内容分析 一.508A产生CSR文件流程 实例图1:申请证书流程: 实例图2:设备认证流程(使用证书): 二.C ...

  3. ATECC508A芯片开发笔记(九):加密读写508芯片数据的流程及相应设置

    目录 ATECC508A芯片开发笔记(九):加密读写508芯片数据的流程及相应设置 1.Encrypted Read 1.1 Standard Encrypted Read Flow 1.2 Simp ...

  4. ATECC508A芯片开发笔记(二):开发准备之 CryptoAuthLib 库简介与移植

    目录 ATECC508A芯片开发笔记(二):开发准备之 CryptoAuthLib 库简介与移植 Atmel两个官方lib介绍 一.CryptoAuthLib简介 Lib中最主要的三种对象类型: 二. ...

  5. ATECC508A芯片开发笔记(十一):NXP 平台移植ATECCx08 CryptoAuthLib库(I2C)

    目录 ATECC508A芯片开发笔记(十一):NXP 平台移植x08库(I2C) 一.CryptoAuthLib 二.Nxp RT10xx平台上移植CryptoAuthLib 2.1.在官网下载最新的 ...

  6. ATECC508A芯片开发笔记(八):ECDH算法配置方法、执行过程及实现原理

    目录 AATECC508A芯片开发笔记(八):ECDH算法配置方法.过程原理及示例代码 1.ECDH介绍及原理 2.ECDH执行过程 3.508A某一slot执行Ecdh需要配置的参数 4.示例代码 ...

  7. 【嵌入式硬件芯片开发笔记】4-20mA DAC芯片AD5421配置流程

    [嵌入式硬件芯片开发笔记]4-20mA DAC芯片AD5421配置流程 16位.串行输入.环路供电.4 mA至20 mA DAC 可用于HART协议相关电路 同AD5700配合使用 AD5421的SP ...

  8. qml开发笔记(七):输入元素鼠标输入MouseArea和键盘输入Keys

    若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...

  9. 【嵌入式硬件芯片开发笔记】HART调制解调器AD5700芯片配置流程

    [嵌入式硬件芯片开发笔记]HART调制解调器AD5700芯片配置流程 低功耗HART调制解调器 适用于AD5700/AD5700-1 我的是XTAL_EN接地,CLK_CFG的两个引脚由同一个GPIO ...

最新文章

  1. 干货!高容错微服务架构设计思路
  2. 开始使用VS2005+ASP.NET+Access(以后可能是MS SQL Server)编写管理系统的计划
  3. 白话Elasticsearch13-深度探秘搜索技术之基于multi_match+most fields策略进行multi-field搜索
  4. clientHeight,offsetHeight,scrollHeight迷一样的三个值
  5. CF1137F-Matches Are Not a Child‘s Play【LCT】
  6. mysql 1157_更新时出现MySQL错误1157,但是我在where子句中使用主键
  7. Andrew NG 机器学习编程作业3 Octave
  8. 别再这么写代码了,这几个方法不香吗?
  9. left join 和inner join关联查询区别
  10. mysql死锁自动处理方法_19. 死锁的产生和 MySQL 自动处理方式
  11. 常见的大数据术语表(中英对照)
  12. java项目汇率管理模板_项目管理文件夹模板
  13. 复杂网络matlab程序,复杂网络matlab程序
  14. 记录用NoteExpress下载文献全文成功
  15. 常见的74系列集成电路
  16. 利用Matlab求解Stewart并联机构位置正解,方法为牛顿迭代法
  17. 【Visual C++】游戏开发笔记四十 浅墨DirectX教程之八 绘制真实质感的三维世界 光照与材质专场
  18. 企业上云之服务器硬件篇(五)
  19. java动态性,java动态性
  20. 使用WebSocket实现服务端和客户端的通信

热门文章

  1. 特步与AWS合作,“跑”出行业全球品牌发展新“配速”
  2. 一次从库 Relay log read failure故障
  3. PCIe 实战2-PCIe转USB3.0
  4. 远程桌面连接失败解决方案
  5. Jetpack Compose 从开门到入门之 MenuBar桌面菜单(Desktop Menu)
  6. MATLAB算法实战应用案例精讲-【数模应用】朴素贝叶斯(NB)(附Java、R语言、Python和MATLAB代码)
  7. 运势运程星座运势算命程序源码公众号版小程序源码
  8. 使用HTML制作简单的小米界面(部分)
  9. 大数据时代如何治理骚扰电话?
  10. Apple Pay 和 苹果内购买