Skip to content
Advertisement

Sign in Javascript and Verify in Flask

It is easy to sign and verify in Javascript using existing libraries. However, it is confusing if we want to generate a public-private key pair in Javascript, sign a text and then verify in Flask. I already know some differences, like the default hashing in Javascript side as against python side. However, the verification in Flask side still fails.

index.html

function send(){
    promise =   window.crypto.subtle.generateKey(algo,
                    true, //whether the key is extractable (i.e. can be used in exportKey)
                    ["sign", "verify"] //can be any combination of "sign" and "verify"
                    );
    console.log(promise)
    promise.then( (keys) => {
        priv = keys.privateKey
        pub = keys.publicKey
        console.log(pub)
        console.log(exportCryptoKey(pub))
        const pub_key_export = exportCryptoKey(pub)
        return pub_key_export.then( (pub_key) => {
            console.log("storing keys in", pub_key)
            signature = window.crypto.subtle.sign(algo, priv, enc_msg);
            signature.then((sign) => {
                sgn = window.btoa(ab2str(sign));
                $.post("verify", {"pub": pub_key, "data": ab2str(enc_msg), "signature": sgn}, function(data){
                    console.log("data", data);
                })
            })
        })
    })
}

verify.py

def verifySignature(signature, data, pub_key):
    key = RSA.importKey(pub_key)
    h = SHA256.new(data.encode("utf-8"))
    verifier = PKCS1_v1_5.new(key)
    return verifier.verify(h, signature)

Advertisement

Answer

btoa(raw_binary_bytes) will encode your payload into base64 in js, this is done to prevent issues when transmitting raw bytes.

you need to call the decode method in python with base64.b64decode(encoded_bytes) to get the actual encrypted bytes, which you can then decrypt

Advertisement