I am signing SHA512 hash with RSA and save it to file. The hash is the same on both python and javascript, but signature can not be verified. Python code:
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)
I tried different ways to convert base64 signature into ArrayBuffer to use in Web Crypto API: rfc4648.js, new TextEncoder(), custom conversions to Uint8Array, but result is always false. Also i tried to verify signature using forge (https://github.com/digitalbazaar/forge) but result is also false.
Where am i getting wrong? I tried to compare byte values of hash, which goes to input of signing functions, but actually it is Crypto.Hash object on python.