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

2024-04-27 22:34:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我用RSA签名SHA512散列并将其保存到文件中。python和javascript上的散列是相同的,但签名无法验证。Python代码:

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代码:

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加密API中使用:rfc4648.js,new textcodector(),自定义转换为Uint8Array,但结果总是错误的。我还尝试使用forge(https://github.com/digitalbazaar/forge)验证签名,但结果也是假的。你知道吗

我哪里做错了?我试图比较散列的字节值,散列用于签名函数的输入,但实际上是这样的加密哈希对象。你知道吗


Tags: tofromimportnewvarhashjavascriptawait
1条回答
网友
1楼 · 发布于 2024-04-27 22:34:10

Python代码中的^{}/^{}实现不会自动执行哈希运算,即用户必须在签名之前显式地对数据进行哈希运算。因此,在验证期间,用户必须根据数据的散列来验证签名。你知道吗

JavaScript代码中的^{}/^{}实现自动执行散列,即用户在签名之前不能散列数据。因此,在验证过程中,用户必须根据数据验证签名(而不是根据数据的散列)。哈希算法在密钥中指定,即在^{}/^{}中使用{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)

尝试使用此更改执行验证。你知道吗

相关问题 更多 >