文档章节

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

H
 HowieXue
发布于 2017/07/19 21:48
字数 1236
阅读 23
收藏 0

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 init
        assert_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的软件实现方法网上有很多介绍,这里不再赘述)

//
//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证书验证

508A对证书验证有一个专门的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 location
       cert_def_device_xxx.tbs_cert_loc.count =  tbs_length ;
       cert_def_device_xxx.std_cert_elements[STDCERT_SIGNATURE].offset = SignLocation;

       //verify cert use 508a
       err = atcacert_verify_cert_hw(&cert_def_device_xxx,
                                             Certificate->certificateData,
                                                     Certificate->length,
                                                             PubKey);
       if(err != 0)
            return err;
       else
            return 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的安全性能保证)


欢迎转载,Howie原创作品,本文地址:

http://blog.csdn.net/HowieXue/article/details/75330820

谢谢

© 著作权归作者所有

共有 人打赏支持
H
粉丝 0
博文 13
码字总数 12540
作品 0
Java加密技术(十二)——*.PFX(*.p12)&个人信息交换文件

今天来点实际工作中的硬通货! 与计费系统打交道,少不了用到加密/解密实现。为了安全起见,通过非对称加密交换对称加密密钥更是不可或缺。那么需要通过什么载体传递非对称算法公钥/私钥信息...

mrliuze
2015/05/28
0
0
使用OpenSSL实现证书操作

伴随着计算机的发展,计算机的安全问题也一直困扰着我们,在现代社会计算机信息安全更显得格外的重要,如今的社会是一个信息的社会,你我每天都在使用计算机,随着电子邮件、社区网游、即使通...

景光
2013/02/02
0
0
Java加密技术(六)——数字签名算法DSA

接下来我们介绍DSA数字签名,非对称加密的另一种实现。 DSA DSA-Digital Signature Algorithm 是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。简单的说,...

mrliuze
2015/05/27
0
0
[Java 安全]消息摘要与数字签名

消息摘要 算法简述 定义 它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原...

guitar_zp
2016/07/24
0
0
Web开发必须了解的密码学技术

对称加密与非对称加密 按照密钥的使用形式,加密算法可以分为对称加密和非对称加密(又叫公钥加密)。对称加密在加密和解密的过程中,使用相同的秘钥;而非对称加密在加密过程中使用公钥进行...

邱振源的博客
2017/11/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

《看图轻松理解数据结构与算法系列》导引贴

最近学习数据结构,遇到一个很喜欢的博主,他的文章图文并茂,理解起来很容易。特此开贴记录,方便反复阅读。 博主主页 https://juejin.im/user/57c3970f79bc440063e58518/posts?sort=popul...

科陆李明
35分钟前
1
0
20.27 分发系统介绍~ 20.30 expect脚本传递参数

分发系统介绍分发系统-expect讲解(也就是一个分发的脚本)场景:业务越来越大,网站app,后端,编程语言是php,所以就需要配置lamp或者lnmp,最好还需要吧代码上传到服务器上;但是因...

洗香香
49分钟前
2
0
设计一个百万级的消息推送系统

前言 首先迟到的祝大家中秋快乐。 最近一周多没有更新了。其实我一直想憋一个大招,分享一些大家感兴趣的干货。 鉴于最近我个人的工作内容,于是利用这三天小长假憋了一个出来(其实是玩了两...

crossoverJie
55分钟前
2
0
软件架构:5种你应该知道的模式

Singleton(单例模式)、仓储模式(repository)、工厂模式(factory)、建造者模式(builder)、装饰模式(decorator)……大概每个上课听讲的程序员都不会陌生——软件的设计模式为我们提供...

好雨云帮
今天
3
0
OSChina 周二乱弹 —— 这只是一笔金钱交易

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @小小编辑:推荐歌曲《暮春秋色》- 窦唯 / 译乐队 《暮春秋色》- 窦唯 / 译乐队 手机党少年们想听歌,请使劲儿戳(这里) @我没有抓狂:跨服聊...

小小编辑
今天
1K
19

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部