IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 20220418-信息安全工程-USBKey -> 正文阅读

[网络协议]20220418-信息安全工程-USBKey

希望帮到有缘人

USBKey Learning

证书

一些证书类型:

  • PEM:既可以保存证书,也可以保存密钥(为了区别证书和密钥,将后者后缀改成key

  • CER,CRT:只保存证书,不保存密钥

  • P12(PFK):同时保存证书和密钥,有密码保护

所谓的用户证书,就是用户用自己的私钥对对自身信息内容进行签名,然后发给CA证书签发机构,CA验证后用CA的私钥签发的数字证书

此外还要知道的文件类型

  • CSR:证书请求文件

使用openssl生成p12格式的RSA和ECC证书

  • 生成n位RSA密钥

    $ openssl genrsa -out 4xwi11_rsa_sk.key [n]
    
  • 从RSA密钥中提取公钥

    $ openssl rsa -in 4xwi11_rsa_sk.key -pubout -out 4xwi11_rsa_pk.key
    

    关于RSA密钥文件的直接提取或使用不妨看看这篇,Fr.https://4xwi11.github.io/posts/d77a51b9/

  • 在prime256v1下生成ECC密钥(前面的参数是椭圆曲线的参数用openssl ecparam -list_curves命令查看

    $ openssl ecparam -genkey -name prime256v1 -param_enc explicit -outform pem -out 4xwi11_ec_sk.key
    
  • 从ECC密钥中提取公钥

    $ openssl ec -in 4xwi11_ec_sk.key -pubout -out 4xwi11_ec_pk.key
    

    ECC查看私钥内容

    $ openssl ecparam -in 4xwi11_ec_sk.key -text
    
  • 用密钥生成证书

    生成证书申请文件

    $ openssl req -new -out 4xwi11.csr -key 4xwi11_ec_sk.key -keyform PEM
    

    签发crt证书(这里其实是自签名

    $ openssl x509 -req -in 4xwi11.csr -out 4xwi11.crt -signkey 4xwi11_ec_sk.key -CAcreateserial -days 3650
    

    将crt转为p12

    $ openssl pkcs12 -export -clcerts -in 4xwi11.crt -inkey 4xwi11_ec_sk.key -out 4xwi11.p12
    

    使用下面命令可以查看私钥

    $ openssl pkcs12 -info -in 4xwi11.p12 -nodes -nocerts
    

使用gmssl生成p12格式的SM2证书

安装gmssl,Fr.https://github.com/guanzhi/GmSSL/tree/master

为了加深理解,在用gmssl生成SM2证书的同时,模拟下证书是如何签发的

首先要关注下gmssl的配置文件/usr/local/gmssl/openssl.cnf(在安装gmssl的目录,因为要符合配置文件,所以要保持文件名相同或者根据需求进行修改,添加相应的默认文件,即mkdir newcerts private certs crl && touch index.txt && vi serial,并在serial中输入初始化序列号,比如02

其中

  • dir:CA所在的目录
  • certificate:CA的证书
  • private_key:CA的密钥

image-20220413161356161

  1. CA生成密钥

    $ gmssl sm2 -genkey -out private/cakey.pem
    
  2. CA自签名证书

    $ gmssl req -new -x509 -key private/cakey.pem -out cacert.pem
    
  3. 客户端生成密钥

    $ gmssl sm2 -genkey -out 4xwi11.key
    
  4. 客户生成csr(好像公司等信息要和CA自签时一致

    $ gmssl req -new -key 4xwi11.key -out 4xwi11.csr
    
  5. CA签发crt证书

    $ gmssl ca -in 4xwi11.csr -out 4xwi11.crt -cert demoCA/cacert.pem -keyfile demoCA/private/cakey.pem
    
  6. 验证签名

    $ gmssl verify -verbose -x509_strict -CAfile demoCA/cacert.pem 4xwi11.crt
    

    image-20220413162645103

  7. 将crt转为p12

    $ gmssl pkcs12 -export -in 4xwi11.crt -inkey 4xwi11.key -out 4xwi11.p12
    

将导入usbkey的容器里,接着就是很迷的地方,如下图,上面那个是老师帮我用在线网站生成证书然后导出公钥和私钥的,下面那个是我自己的, 我是没找到有什么办法可以把公私钥像上面那样导出来,反正我的无法正常使用(只能对称加密。其中应该有版本的问题,我看别人的都是V2.2.19,直接导入就是上面那样,而且还有创建容器的按钮,WTF

image-20220413164549289

不过这个问题是可以通过调用API来解决的,后面还会提到

运行demo

总之折腾到这里本型号demo提供的功能都能够使用了

image-20220413170153545

image-20220415122507534

调用智能密码钥匙实现以下功能

在所有的操作之前,先实例化mTokenPlugin对象

var token = new mTokenPlugin();

获取随机数

函数原型如下

image-20220331140303276

p = token.SOF_GenerateRandom(100)

console.log(p);
console.log(_Base64decode(p));

获取的随机数base64解码出来是字节码,如下图所示。和预想的不一样。。。所以硬件是产生的随机值是字节形式的

经过验证uLength是随机数的字节长度,怎么验证的呢。。有点啰嗦


对这些字节码进行转10进制数字操作,代码如下,结果如下图二所示:20个字节(256进制)转10进制bit位在160左右

进一步分析随机函数参数uLength与bit位的关系,代码如下,结果如下图三所示,可以说是SOF_GenerateRandom函数接口会生成uLength*8bit长度的随机数,即uLength表示随机数的字节长度,并且可以传浮点数

image-20220331113253307

from base64 import b64decode

# u1Length = 20

a = ['TFqASTnk/wbgnJdrsrhTm/f3TOM=',
     '48mhqXP2TVvDEobwtrnu0ygRETI=',
     'Ic1j/mrYsVf1nrHJYU5pvjk8T2A=',
     'JhYXyMjulyA2S4bW147VhnnRzy8=',
     'DtyF8fKEmxdHAZnMj0/ySy/DNqI=',
     'w3+204ZtTNg+0bwjJx2raPBKMds=',
     '6pv9XIWX1FOHrMb1pArMZEHGltI=',
     'fadDSTrjvzx31ZyObwgMmOCz4mw=',
     'rGS3q41jnt7NiOjymaMAOkcd89U=']
for i in a:
    val = 0
    src = b64decode(i)
    assert len(src) == 20
    for j in range(len(src)):
        val += src[j] * 256 ** (len(src) - j - 1)
    print(f"256进制 ====> {val} && {val.bit_length()}nbits")
    print(f"l2b     ====> {int(src.hex(), 16)} && {int(src.hex(), 16).bit_length()}nbits")
    print()

image-20220331130401022

from base64 import b64decode

a = '''ag==
hI8=
0Sm+
CZkaAQ==
D0Dx6mY=
068tI/hc
ncwlaByQDA==
75LErcGq05M=
wjZVgpFGfT9T
L+WBOYEtterUrA==
jbhw/b4YoYpR+Ec=
Nk/dDpr8EOx9iSeS
r0hXkHskSHLQ+UMQ7A==
eeK12gh+wg+Xhk9eVLU=
UJ1xtQt/BjO7h8mn7z67
HUAO119KLqthbpX1zgvZcA==
quI3zQp4rc0WOSnXZpfTV74=
MPWaDcS1IRBpzwvX8hZGvQI/
TS16Gp6tsPKvebTacsQS6ZmYsQ==
1GKgYDJKoW8IJ9HaW/ORecc3xQc=
f4BigtV4opSqbABIwMUfMTBYMI96
UOaNdWFj8imAu67qu/iRSIcRIuGS1g==
lcfCepOg/mve2G08xRYKOOTTL+6zkFo=
MRcKTt8yjdqkCHbX9+4O+6O3xzSEjQDj
ES3f7/RSfO0aolrMPAzt+MIQhaNH7CkbFA==
lA897tf2Gs9mPLHIWZ+w6w6r0T4W4fMHfLQ=
NRTOxPqLWCfiXju8C+Dx5f3xTZSmgYSbGd7B
DLHWBO289HTYHvyK+Bm1tcrqtP008zL5QsJsBg==
1R0MRh31HJDnM0XQqKgidxiLflRnrpLme9b1tRE=
FCgYN14B2ZMrl0Msi6gJe87BuZRRpeqhu0d4y2T3
qN9sPcdG2b0Lt99t1NYwmXpLc6WLe9GpPO8XsMr82Q==
sWIr4C+6HqFo5CEiMvnk5Mqqr3Pmx35beLTSAveS/UU=
r6xdBYpVZexlUgqDh1FsDi+DDhqyrDksLFr9ilLVjtjf
5ps8iGmx3shHAPefTU/5AhIGMuu7njIakNFywcJIULZZ1A==
3BopWTfTO4N+x5v+yHjscolXWkwOqBdI4yPeMGefRhmp3wI=
Ip2cZ5A1UTFrFsxIakG9DUPATXqbS0KSMu+aqW+sBhqeTpPe
M5PxkVw1NPK9OyfIScu4JbSA0xfjxuwqjl0+TTgG7c7ohLZFcw==
VdSryos9SkzYDp/9FJ9CrgiCSGDO82Yk70mIKIVGOx84e43FVrQ=
2I+cngj0i8R8De++1saob3CEzOA4QYwC2efYXrKNheiaBGmXdsit
RGrDRgwEjpyLbywpW8hddYRpAsVxTcthPOTYxxOtNPOnwG3kcbQwsA==
xkqdiU0j/sxqHZS/1pzps5hdPjcO7qIkC8HjBIJGd5DT140lulD0u6A=
bBz9giAeit7NNaIC6+miB4H+kRCm2cV4p02Uxgp/BdqH5XkNKEEXvSjK
fe2MPtPIk9uBwOEA0tjrtfF2cDJbqrXZ8TMLu7rXva1+LwTNwn7S80Qtbw==
DqLOCXrkhiKm698fYJ2hjQ2U+U2cMzZM8zJbldvE5U/31/OK+00KhXuAvDw=
NZSASmxK054Vkepw3RHDzN1ktv8ws/6ygdgNrjesqN5Dvcy0htCajU3MavMu
cCO05rf7qSyJYqKtwW0hfezE/3uvJdXZcpJoLqkL2WCWevLz0gPkaQ9FkLFtMQ==
sFfqBBsD50+GHzkDYM26NAkXWclJbrpdsvYvxVZobhnGXVO71XOvZPDJBzt9cxw=
e7ZNpcp8absdDM1Rr6w9HE1mJ6HiucrrGaEsWGRl0TvQkXXrv+i2BiWB6Am/PfB2
czOPxtLV7/x0n4Qckbs3jzlFWaQGw7S+Oi/v5e7QEPLFpml2hTmf+/UvgyZFMosxxQ==
j2kjfvLVbHyNwcys3QuLDNGRwpFRiQvJy++1qUkhVvAwUUTib/zhP1JuqRfhYbH1muo=
xMdZnrCht3I2Ly9QtpmEC+FxSPgYj7PrVF3sC9oYleNXaYITAWzgYvtaNpFIb+CJaz7u
lpbl2niIqCKRN+BcJ++AEtUkyYo5oUsTisLLQYGIXaRyT2mv+4ld8W5eloD6J/RuUE/o1A==
HwJCb2T1dOIQlJp5Jy1dTrrKk8hqf+fgCqYyEOk0GhtA6lZUMa1bYCu/yzJl/cz2ppt/wyk=
lhut0vBBSSEVC1wxvwTzCTzwcWVOiwoovdafUuG8UKOMWjTjEqQot92o2V01HCWGlwZyb0cG
21hBqIC4GdIL+Hs80pu7FYmefeQ1bBiSb9DpAUljYn7EtJAxFIxWwhP65OIsImc2+h6WimEgsg==
PDH4YNMJ7SZ3UkXljr2kKTH8VvJ8HyOCK3Na92c2KVbnOJKQmMMfymBjCmbRlX3CrIUSHFZ+8Ao=
75T5YhJ6iPRN+EGcq/IEv1sIkgM0uj0MFHaN4xsKFRWOkA9lgDSM8HHDhZe0QxgYrARWcLuzhFHP
QC8zKJ4x6hXExqGD1aJgxZwzMefaKzw7GnWz4VG5HabW41XcLDdCy/BGRhdIEgezhu3I9LYdqnOziA==
zMwi+jrILWmp761Kqu5I+sSbjI6a7Aq0ZTINN8M2YZTrxrlBdkOoqhMNeZRyOnHHXcTX0ApJYi9GPfw=
c+kVJ8Jkl2R23E7nz/nhVrpN88UFcOGcrVShCa9KZUbIb8B5Vp55gS03zGjFnJ2pdwWiZI8hOnMDgeYQ
gF5V7dY/gjknFnampP2sgS2OGPtzxbOmhD/gA/CUWIBTARS5aZIOH1ucL9TTw9cy7pASDp5c+OrGxt5/0A==
rgpYBo/iU7y0eekZ9P+V5hpw/niSO/ZiFNSBpbmnRmG3zDV54dK/94QSiG93/iiWrPf1wHwAK+xgSnCh3Gw=
lFo+c8sAML/iUfOtdr2m/2pYr3bAqXfHVjbct1kps8sjGUNzpizxo380sv5vGbWe6wcN61ve4g6QYkETQdKs
WsIoM7O0o0Y/q7gVY9kzfg1jpwGXugmvMKdZFBfgrUawDoo9Gj6n2uxmiiGzSfBgdUv9mB0vDB2HnWNdnox6Vw==
kuThcoRn1SaOa8WtygLWEBaEcJWpy965qonIkAAYc3RFkwv02OXKdLR3r177GL7hbRmBf/e1JoMV7BwkVU5QM+g=
p1xkYFnMzfdc82rl7+ap3Hcg/JPaBgQWBfsxxVNHC8O0LhULZRy4R9Mchcayz34P9kZXGC1wJA2A98F+5NJI7bS2
c45NRpfx7wwFwupCnNNBsGJFdDHT+rp2mNJPbKxwIjs+j4oVIxlcVYLLOZEllvhUxCziafDspDGbyoPmgkntE5qo4g==
zhH2LRT0/IqIVjbCssBSna84TvHfFCbUpih5ONYFBl06hCbvmgd8jE6aaHu+/1ahGFgSji7uHcaO8XIOKtlYk9HnRpA=
//5V/ePt5Ryc7RK/k6Y7VE0IcufLav+UNeUvaEMZixhGGnvndeL+mfMfBy7xi4gAgjwtDS4LMakEleOamZhGplKCCqa2
YNVJ6yNFMKku+4e6CtibSn8yvFIV8TCzpXt6xdgdXypSlXbcZwzKa6Yp+vMKGDwcLAmimXCvc5RbzpRTK7ycMja4Xy1WzA==
eTnppoAMfCwcDKI5Y5bMaWYIXPTliPVInt5eAzbXOyGA/1ilR5VzMyFs0RDdk35TxIV6gOqp+kI0y7f9VjhofmZ3xW9iS14=
7fzG82S4iFkTF67rTIZXnq1OzcurS1E3BLiHNQ6OpZX6cBHwQ3pyRh8+4NxX/Fan55rRu4T3sueNYkkyALbL+ocsY2WqzCCN
+FgoYx5RKEVC56nIlonC2KakkJNDKZC+JXlMIzYg/J1JQoqZhzSzw9qtxfOoqH35+VvyHtBYqn85tgDxQ4H3/C30TLOA9TGx2Q==
E1wah2OhOC4Ci69pSfC8xgHKQ2xsKPrOAcSqqW2iHrU2U4U41YftwKmP9ecaV1ppckzJTNWgPUnMXWT9qW36aJfLXr8HldeQMkk=
M7tJwW8Uy7ZTnwTsMUghgUAZf/8s7zO7WlJvfRdb6TyMhgQ/DQXUNYE2f5kxs5K2GOjMBpY0l9eTG2fsvqx0GyYZUh0vmwBXRtfl
sT7xNdQA5a8E4CknveaEaes2nqIAWGFVEO59Eqsuj9mn+ORTQPK7bviPNDnuVLw1WGPGLUbDodXRO4aR+CTNykf48SFqE30Q76iF4w==
/y/Vhv9MLDoU7I/OUNPe3owl6NqIDn+WsOh+y9brBybBX3AiIKXafTu+A/ldZzTGur2UFmBxHKGnfc16e0D9gSwxchRCbEP83krbYu8=
kLm+qmyPUVIDC6meodWE0HJdp0EjiwZVFRlRic6SUT+6aOOetWS3ssyp+wyh8XNp7gmUUrwUhWyDCVPMwATLm0V995SOCcO3cu0UXigK
Cgms7yCoIzF1GduQBzFojjOh0KW/nbb5Y96PRYjn9DlbPbAA85XRUMMhfnZMQjaCQvCN3BTpI1g0yPQR/spd87e30DhYm1tZv1Q47ipMOw==
5e25+gtBAiEFsS0/79Ng04moXbV1ZCUhgTtuXrV1pbDyzjRZrqiNTYOrv0mh1lJa1dEtfWuU8z584yz2JwF8y8oRA60oIWpZuq7hjCa8PHQ=
wUWEuc+rWRpto1IuUXX78V+dVnUcXyPRwQ9+rZkcolY5GsDD+qIIVOLeZniKIW2YCrDcFYeurhgnZ0i8hoODpDb4072Gt27jnksutrU8hSD/
9yOJv/swvwBq/4elnXW5TqtENuB5P7jnp0RsIGeO3kzXutM7ogjnLOUbFJNSv1a3RFxHK1GejNahxZzSgmK6gFbdXsiYliuC7bQUMDDzZ36TdA==
+vA3YDDLZKObVe9sMpdypWBGtrVNNCOiS7uH/sFDFzmjaUD+kcfnDnVizt1GQiZAi3qZgxw/yZPCgzOHLkb1XXRUD/3KZxR/kyaYyHC0f2cS570=
dirYz92a6Ti1eVo4jbR/xEUz3iABhvx3SpnXQy4c8JyzSiNNGclQvM7WAXbSzuKP11hBfqmOsa5AfGvscWtyKwRMTUyNeJ9Wd2lrOMi49EeEzrE2
yNh0XNDVZMvvt43WzxZpVEfoOdcdctknN6DH+mdtg0jnKgflDAy42T1YC/CtEflFt3DyrI+60r7eYpkfX7dCkWBDH85U+lbvbCikd0k8dBoH87H5Qg==
2ZGzjSQ8qJPQRPpus+LXLhpWbAmEpW/XfZykfggniKemx7C1Gp58r1sBS3e6RZ6wSrGjp5/6NaoHt2RxE/J6cpvGwO8w9tx1CTi5RT9QyZ7tMAWAxBk=
A08n0IuKVA55LnnkTIrSrWow59V3WekpgOXusIt396Da3cz6/OQl9y5tcEV+CqyBVH72gD67S5QqoXTxMX1ianCydJ5Pcchfu5Y6Omr5Th9Tp9zqylIr
tW2QfvKUpQ1wb7mSEi79G+uaUNNlgKOBOofyINQb3+/HRMTYf+zfFT6AXVH1BJlMnb2Hf3xt0EhLZl0K3ltRrU1IodMDMG+lb/RDngWgyvUBbk9oCi3Z2w==
bcoUQq2gKiWEXrjOyEGNCIRXLIJ0eXsy5TONrlQjrCZxjud3cMKwcT7ltFXBOY0eo+ngUUr5gacoZD1wg1xj+c170X39orN8eDZzEBAVien8gjglaiAzmXc=
fOAEFAYLifb3sRiqxN8UMjMRXX9APRTcJEW9tdQqo+xDvPh6a9632h/3pDtKz+o76iYDgnUp6yyMtlwnNNxmaQncLhwXOylq88zG/RJCGeX065ggogwSr7ZA
uAjjXRMggTBEGpt0pee7oj3iqh1HdncUEG3rxTqU/WV8Etv11MEgpz5D3p8KCERvzlfxDWRl886xzHejK0bRth6EaYn63M9YdwXO7KqFOQIOM40DbMGR1HAOGw==
KaH6UZTvVJ1R5bdRTciIclz8M4t7mAo+IXVT9n0DrbbWqKp15evyK9Z2RnokDkWKuly8gsmqKq5TYcJbW2y0iO94lVuPT7c+wJPn7ruWc9E4euLdU/eflktebww=
MXRDmE60qUYHuXqXqFV2nThyQJaCcMkmT2MeBgEK08wZzSo14UXU7WZmwv5gV0A72bxj1NeVIIPP60Id2JnjuCwfSg5g1EbX4xGdBeQOHwbjFWqoQ7MB93r6McRA
RvExfm8ab0wqM9/p3oIwPglkkZvKxtgh68tkj49pRCRos8G1gGbt/9bBCwv1nqvTRi9y4IGw5g/RtcnGGzm7xiWWThVbFs4tVWnpMai6tas6rWLkTt9PJKyKfkvq/w==
U3iCt1dI95gxG8zDjEA1H/BasP/Wxvos31UKGN932SoDXQXhLZM5qzhoUqlbk/9wYAfmxubzAC2iDR6oReYk3v1V0dmjzhs60XJzphP9C14a8Ciju6W2LDktoaZbvEA=
trVvSeN1Ki4F905FEQnOZXamKQGY0J6hVw4Ut6WyCJzR4Jkw8fLHh5JdBR5KIXLvo+swOuYDavSDWQnKdkRQYJaxkmWPwBPUGcgREOWuWBbxY+QvKrHQYkOPZzFPXNLe
aQXkWomVggiirRDHTDxoeqmRJ34HrwqD/b02XuDiZiOHr0VrAjs3416nKMAD8BbjcxOdd8f0vspdraEUNzgp7qlqY1bDnUZj8044RMpGzkVUNqGI424OxBzfX0EGEeGOUA==
075bh4Kd3zyYJfvsEU4o0vJyqCRrbzFKiYFTeBuesCg1sNmCtDINOn8oftA/na2JtMl0PjBobFlXP/DSYmYbTIuBbLftbfIT9gcn2ITsNlOE1DdcK6d52VI1itD6JJm/WQs=
M1Mb+GE81R1ddl/woj9ee4HzVXv587QLMIpTdvjtou1PpHfgRQDQodvVLPiwJ/d5WTTLK4jChdYT6VPSBxF0mjoVGwKzUBbsgVoy4oEo/OtXKKIri575BEAK6lN5IlEaqGT8'''
la = a.split('\n')
for i in range(len(la)):
    src = b64decode(la[i])
    print(f"uLength: {i + 1} ====> nbits: {int(src.hex(), 16).bit_length()}")

image-20220331140122921


不过这一切在老师后面给的另一份文档中得到证实。。。

最终在js里可以这么用

/* TASK */
// get real random
const gen_rand_bits = $('#gen_rand_bits');
gen_rand_bits.click(function() {
    const rand_bits = $('#rand_bits');
    const rand_num = $('#rand_num');

    rand_num.val('');
    let nbits = rand_bits.val();
    if (nbits === '') {
        alert('请输入合法长度');
        return null;
    }
    if (nbits > 6148) {
        alert('长度过长,须小于6148Bytes');
        return null;
    }
    nbits = parseFloat(nbits);
    p = token.SOF_GenerateRandom(nbits);
    if (p === -3) {
        alert("与硬件交互失败,请检查是否插入USBKEY并是否登录");
        return null;
    }
    else if (p === -2) {
        alert("生成随机数失败,错误码:", token.SOF_GetLastError());
        return null;
    }
    else {
        p = _Base64decodeArray(p);
        let val = 0n;
        let len = p.length;
        for(let i = 0; i < len; ++i) {
            val +=  BigInt(p[i]) * 256n ** (BigInt(len) - BigInt(i) - 1n);
        }
        rand_num.val(val);
    }
})

此外,经过测试(多次重装mPlugin_Setup,该硬件生成的最大随机数位数在6148*8=49184 bits左右

计算HAMC

HMAC

哈希运算消息认证码,简单来说就一句话

image-20220414114142773

伪代码如下

function hmac (key, message) {
    if (length(key) > blocksize) {
        key = hash(key) // keys longer than blocksize are shortened
    }
    if (length(key) < blocksize) {
        // keys shorter than blocksize are zero-padded (where ∥ is concatenation)
        key = key ∥ [0x00 * (blocksize - length(key))] // Where * is repetition.
    }
    o_key_pad = [0x5c * blocksize] ⊕ key // Where blocksize is that of the underlying hash function
    i_key_pad = [0x36 * blocksize] ⊕ key // Where ⊕ is exclusive or (XOR)

    return hash(o_key_pad ∥ hash(i_key_pad ∥ message)) // Where ∥ is concatenation
}

注意下面框框框起来

image-20220414164004737

下面这张wiki的图就将用SHA-1做HMAC的流程解释得很清楚

![img-M6dVVBex-1650284483008)(http://mypictruebed.oss-cn-hangzhou.aliyuncs.com/img/SHAhmac.svg)]

blocksize参照下表

image-20220414143856714

js实现

// HAMC
const gen_hmac = $('#gen_hmac');
gen_hmac.click(function() {
    const hmac_val = $('#hmac_val');
    const hmac_key = $('#hmac_key');
    const hmac_msg = $('#hmac_msg');
    const hmac_digest = $('#hmac_digest');
    const container = $('#sele_contentList');

    let userID = '1234567812345678';
    let key = hmac_key.val();
    let msg = hmac_msg.val();
    let digest = hmac_digest.val();

    let key_length = key.length;
    let msg_length = msg.length;

    let containerName = container.find("option:selected").text();

    token.SOF_SetUserID(userID);
    token.SOF_SetDigestMethod(digest);

    let block_size = 64;
    if (digest == 130 || digest == 131) {
        block_size = 128;
    }

    let tmp_msg = stringToByte(msg);
    let tmp_key = stringToByte(key);
    if (key_length > block_size) {
        tmp_key = token.SOF_DigestData(containerName, _Base64encodeArray(tmp_key), key_length);
        tmp_key = _Base64decodeArray(tmp_key);
    }

    key_length = tmp_key.length;
    if (key_length < block_size) {
        for (let i = 0; i < block_size - key_length; ++i) {
            tmp_key.push(0x0);
        }
    }

    var o_key_pad = new Array(block_size).fill(0x5c);
    var i_key_pad = new Array(block_size).fill(0x36);

    for (let i = 0; i < block_size; ++i) {
        o_key_pad[i] = tmp_key[i] ^ o_key_pad[i];
        i_key_pad[i] = tmp_key[i] ^ i_key_pad[i];
    }

    let tmp1 = i_key_pad.concat(tmp_msg);
    tmp1 = token.SOF_DigestData(containerName, _Base64encodeArray(tmp1), tmp1.length);

    tmp1 = _Base64decodeArray(tmp1);

    let tmp2 = o_key_pad.concat(tmp1);
    tmp2 = token.SOF_DigestData(containerName, _Base64encodeArray(tmp2), tmp2.length);

    if (tmp2 != null && tmp2 != "") {
        hmac_val.val('');
        hmac_val.val(tmp2);
    }
    else {
        alert("HMAC失败,错误码:" + token.SOF_GetLastError());
    }
})

验证一下好吧

image-20220414192200667

image-20220414192219666

image-20220414191937686

image-20220414191906310

生成公私钥对

函数原型如下所示

这个会根据参数,创建一个名为containerName的容器,返回0成功。然后可以用SOF_ExportPubKeyEx将公钥导出,这个在demo里已经实现了,就不再赘述

image-20220331182215226

image-20220418162916346

导出公钥,制作数字证书,并将证书导入USBKey

文档里看到生成公私钥如上,还有生成公私钥并生成证书请求、还有将提前生成好的证书导入usbkey的API

要申请证书,还必须找一个CA

image-20220331182348971

image-20220415130636618

创建容器(有点鸡贼,调用SOF_GenerateP10Request接口,借用申请证书请求时创建的容器

// create container meanwhile determine nbits of RSA or ECC
const create_con = $('#create_con');
create_con.click(function() {
let container_name = $('#container_name').val();
let key_type = $('#key_type').val();
let key_nbits = parseInt($('#key_nbits').val());
let enc_sign = parseInt($('#enc_sign').val());

let rtn = token.SOF_GenerateP10Request(container_name, '4xwi11', key_type, enc_sign, key_nbits);
if (rtn != null && rtn != '') {
	alert('容器创建成功');
}
else {
	alert('容器创建失败,错误代码:', token.SOF_GetLastError());
}
})

将openssl或者gmssl创建的证书导入刚才创建好的容器

其中证书的内容即自签名的证书内容,格式为base64编码

// import Cert
const import_cert = $('#import_cert');
import_cert.click(function() {
    let container_name = $('#container_name').val();
    let import_cer_info = $('#import_cer_info').val();
    let enc_sign = parseInt($('#enc_sign').val());

    let res = token.SOF_ImportCert(container_name, import_cer_info, enc_sign);
    if (res === 0) {
        alert('导入成功');
    }
    else {
        alert("导入失败:", token.SOF_GetLastError());
    }
})

2022-04-18补充:

上面这个鸡贼的方法,当然会惨遭不测(现象是在数字签名的时候,除了老师导给我的SM2证书,我自己生成的其他证书验签都失败了)由于错得我觉得比较印象深刻,这里单独补充一下

原因是

image-20220418155711428

这个来自《GMT0016-2012智能IC卡及智能密码钥匙密码应用接口规范》

所以上面这个操作是完全错误的,内部的私钥和导入的证书其实是对不上的

解决的方法是,将证书请求或公钥导出来,然后给外面的CA去做证书,然后再把证书导入(注意这里不能再自签名了,因为容器内部的私钥导不出来。然后暂时没找到合适的指定公钥的证书生成工具以及这个pkcs10的证书申请我也没怎么搞懂,先咕咕咕了

同样,也是因为上面这段话,是不能内部产生加密容器的

调用USBKey进行RSA或SM2数字签名

这个demo里,直接copy,注意RSA的摘要算法不能是SM3,而SM2的摘要算法只能有SM3

image-20220418135954626

还有一点,注意userID并非鸡肋。这在最后补充SM2签名还会提到

image-20220418140233530

项目

编写基于web的前后端程序,用USBKey实现银行转账时的签名流程,如:输入转账信息,点击“转账”按钮,弹出对话框,让用户输入USBKey的PIN码,如果PIN码正确,则对转账信息进行数字签名并存储相关信息,否则失败

所有功能在之前都实现过了,存储感觉没什么意思,就没连数据库,简单实现了一下

一些坑

虽然坑很多,但主要的还是记录下

  • 问题:key管理软件可以使用,但web端连不到

    解决:重新安装mPlugin_Setup

image-20220414113556640

补充

可以发现SM2签名,每次点签名按钮生成的签名都是不一样的,而RSA固定不变。因为前者在签名过程中使用了随机数

填下ECC和SM2签名的坑

ECDSA

image-20220418190109643

SM2DSA

在ECDSA基础上,就非常好理解了

首先,要准备用户ID,这也是为什么上文这里有SOF_SetUserID的API

image-20220418185506664

  • 签名

    image-20220418185625565

  • 验签

    image-20220418185802766

    image-20220418185818600

具体的还是看文档吧

Reference.

  1. GMT0016-2012智能IC卡及智能密码钥匙密码应用接口规范
  2. 龙脉国密KEY 证书综合应用插件用户手册
  3. openssl官方文档
  4. gmssl模拟CA发布证书
  5. 外校实验课usbkey使用(他们的key管理工具都是v2.2.19的。。
  6. js-Bignt处理大数
  7. wiki-HAMC
  8. HMAC-blocksize
  9. https://lazzzaro.github.io/2020/11/07/crypto-ECC/
  10. SM2椭圆曲线公钥密码算法
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 19:15:05  更:2022-04-22 19:18:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:33:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码