首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在pycryptodome中验证pycryptodome创建的数字签名

在pycryptodome中验证pycryptodome创建的数字签名
EN

Stack Overflow用户
提问于 2019-09-30 19:47:29
回答 1查看 740关注 0票数 1

我正在用SHA512签署SHA512哈希并将其保存到文件中。在python和javascript上哈希都是相同的,但是签名不能被验证。Python代码:

代码语言:javascript
复制
from Cryptodome.Hash import SHA512
from Cryptodome.PublicKey import RSA
from Cryptodome.Signature import pkcs1_15

hash = SHA512.new(someByteArray)
#This is equal to digest generated in JavaScript
hashDigest = hashPDF.hexdigest()
pk = RSA.importKey(privateKey)
signature=pkcs1_15.new(pk).sign(hashPDF)
#Write signature to file
with open("storage/{0}.sig".format(hashDigest), 'wb+') as f:
        f.write(signature)

#Then JavaScript request occurs return content of saved signature in base64

from base64 import b64encode
from flask import jsonify
with open("storage/{0}.sig".format(pdfHashDigest), "rb") as f:
        sign = b64encode(f.read())
return jsonify({"sign":sign.decode("utf-8")})

JavaScript:

代码语言:javascript
复制
var hash=await crypto.subtle.digest('SHA-512', Uint8Array.from(atob(someBase64content), c => c.charCodeAt(0)))
//This is equal to python hashDigest
var 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 false
var result=await crypto.subtle.verify("RSASSA-PKCS1-v1_5", cryptoKey, Uint8Array.from(atob(signature), c => c.charCodeAt(0)), hash)

我尝试了不同的方法将base64签名转换为ArrayBuffer,以便在Web中使用: rfc4648.js、新的TextEncoder()、自定义转换到Uint8Array,但是结果总是错误的。此外,我试图验证签名使用伪造(https://github.com/digitalbazaar/forge),但结果也是假的。

我哪里搞错了?我试着比较散列的字节值,它用于签名函数的输入,但实际上它是python上的Crypto.Hash对象。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-01 18:24:38

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

JavaScript代码中的sign/verify实现自动执行散列操作,即用户在签名前不能散列数据。因此,在验证过程中,用户必须根据数据(而不是数据的哈希)验证签名。哈希算法在密钥中指定,即在generateKey/importKey中使用{散列:‘散列-算法’}。

发布的JavaScript代码中的错误是由根据数据的散列验证签名引起的。这是错误的。必须对照数据检查签名,即在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)

必须代之以

代码语言:javascript
复制
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)

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58174378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档