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

来源:互联网 发布:淘宝招商是做什么的 编辑:程序博客网 时间:2024/05/17 16:44

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

谢谢

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 办的消费卡不给退怎么办 银行卡密码忘了手机号也换了怎么办 公务卡在当当购物的刷卡单怎么办 杭州市网签提示住宅均价异常怎么办 吃鸡账号没有绑定手机就买了怎么办 微信绑定的银行卡密码错误怎么办 淘宝单张券已领取达上限怎么办 去办公室给领导送礼总有人怎么办 招行信用卡临时额度到期后怎么办 中银e令不想用了怎么办 中银e令密码忘了怎么办 银行卡预留手机号改了支付宝怎么办 手机一直收到支付验证码短信怎么办 微信绑定银行卡手机号码换了怎么办 银行卡网银登录输错密码锁了怎么办 中行信用卡主付卡的付卡怎么办停 在苏宁网购的移动空调要退货怎么办 单位发的购物卡掉了怎么办 支付宝ofo退押金后余额怎么办 e招贷分期多还了怎么办 别人用我的手机号贷款不还怎么办 电脑文件夹怎么设密码忘记了怎么办 苹果手机id有分机和主机怎么办 绝地求生号被盗了邮箱被改了怎么办 微信邮箱怎么接收不到验证码怎么办 要申请一个特定的qq邮箱号怎么办 中银e贷额度为0怎么办 中银e贷被冻结了怎么办 中国银行e贷款填错了被拒怎么办 中银e贷逾期2天怎么办 大学生助学贷款网站密码忘了怎么办 乳晕毛囊挤压捏起来有小硬节怎么办 手机版模拟人生孕妇任务卡死怎么办 百度网盘的表格没保存怎么办 爱奇艺买的会员不小心删了怎么办 多次举报和拉黑克隆不了好友怎么办 货车把货拉到货主不付钱怎么办 中国银行网银公司用户名忘了怎么办 伟星管网站查不到电水管图纸怎么办 我的耕地己确权被他人侵权怎么办 掌上川电登录密码忘记了怎么办