为了账号安全,请及时绑定邮箱和手机立即绑定

验证由 pycryptodome 在 WEB Crypto API 中创建的数字签名

验证由 pycryptodome 在 WEB Crypto API 中创建的数字签名

繁星淼淼 2021-11-04 15:56:21
我正在使用 RSA 签署 SHA512 哈希并将其保存到文件中。python 和 javascript 上的哈希值相同,但无法验证签名。蟒蛇代码:from Cryptodome.Hash import SHA512from Cryptodome.PublicKey import RSAfrom Cryptodome.Signature import pkcs1_15hash = SHA512.new(someByteArray)#This is equal to digest generated in JavaScripthashDigest = hashPDF.hexdigest()pk = RSA.importKey(privateKey)signature=pkcs1_15.new(pk).sign(hashPDF)#Write signature to filewith open("storage/{0}.sig".format(hashDigest), 'wb+') as f:        f.write(signature)#Then JavaScript request occurs return content of saved signature in base64from base64 import b64encodefrom flask import jsonifywith open("storage/{0}.sig".format(pdfHashDigest), "rb") as f:        sign = b64encode(f.read())return jsonify({"sign":sign.decode("utf-8")})JavaScript:var hash=await crypto.subtle.digest('SHA-512', Uint8Array.from(atob(someBase64content), c => c.charCodeAt(0)))//This is equal to python hashDigestvar hashDigest = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');var cryptoKey=await crypto.subtle.importKey('spki', this.pemToArrayBuffer(publicKey), {name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-512'}, false, ["verify"])//Always falsevar result=await crypto.subtle.verify("RSASSA-PKCS1-v1_5", cryptoKey, Uint8Array.from(atob(signature), c => c.charCodeAt(0)), hash)我尝试了不同的方法将 base64 签名转换为 ArrayBuffer 以在 Web Crypto API 中使用:rfc4648.js、new TextEncoder()、自定义转换为 Uint8Array,但结果始终为 false。我也尝试使用伪造(https://github.com/digitalbazaar/forge)验证签名,但结果也是错误的。我哪里出错了?我试图比较哈希的字节值,它进入签名函数的输入,但实际上它是 python 上的 Crypto.Hash 对象。
查看完整描述

1 回答

?
炎炎设计

TA贡献1808条经验 获得超4个赞

Python 代码中的sign/verify实现不会自动执行散列,即用户必须在签名前显式散列数据。因此,在验证期间,用户必须根据数据的哈希值验证签名。


JavaScript 代码中的sign/verify实现会自动执行散列,即用户在签名之前不得对数据进行散列。因此,在验证期间,用户必须根据数据(而不是数据的散列)验证签名。哈希算法在密钥中指定,即在generateKey/ 中importKey使用 {hash: 'hash-algorithm'}。


发布的 JavaScript 代码中的错误是由根据数据的散列验证签名引起的。这是错误的。必须根据数据检查签名,即在 JavaScript 代码中的以下几行:


var hash=await crypto.subtle.digest('SHA-512', Uint8Array.from(atob(someBase64content), c => c.charCodeAt(0)))

...

var result=await crypto.subtle.verify("RSASSA-PKCS1-v1_5", cryptoKey, Uint8Array.from(atob(signature), c => c.charCodeAt(0)), hash)

必须替换为


var data=Uint8Array.from(atob(someBase64content), c => c.charCodeAt(0));

...

var result=await crypto.subtle.verify("RSASSA-PKCS1-v1_5", cryptoKey, Uint8Array.from(atob(signature), c => c.charCodeAt(0)), data)

尝试使用此更改执行验证。


查看完整回答
反对 回复 2021-11-04
  • 1 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信