简体   繁体   中英

AWS KMS to sign messages - trouble using python's ecdsa lib when getting the verifiying key

I'm signing my messages using my code below:

def sign_msg_hash(self, msg_hash: HexBytes):
        signature = self._kms_client.sign(
            KeyId=self._key_id,
            Message=msg_hash,
            MessageType="DIGEST",
            SigningAlgorithm="ECDSA_SHA_256",
        )
        act_signature = signature["Signature"]
        
        return (act_signature)

However, when trying to do the following:

 sign = kms.sign_msg_hash(transaction)
vks = ecdsa.VerifyingKey.from_public_key_recovery_with_digest(
                sign, transaction, curve=ecdsa.SECP256k1, hashfunc=sha256
            )

I get the following error:

ecdsa.util.MalformedSignature: Invalid length of signature, expected 64 bytes long, provided string is 72 bytes long

Now, when trying to use sign[:64] instead, it sometimes works but at other times gives me the following error:

raise SquareRootError("%d has no square root modulo %d" % (a, p)) ecdsa.numbertheory.SquareRootError: 6631794589973073742270549970789085262483305971731159368608959895351281521222 has no square root modulo 115792089237316195423570985008687907853269984665640564039457584007908834671663

Im not sure if this has anything to do with the encoding of the signature from the KMS or not, hence I appreciate any help provided.

So after some digging, it turned it out it was a matter of encodings, as the kms sign function returns the signature in DER format

hence to what i did was the following:

  1. I took the signature and split it, and got the r and s values as follows(thats for python):

    decoding=ecdsa.util.sigdecode_der(sign,int("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",16))

  2. then concatinated the result (note that r and s should be in big endian order):

    new_sign = decoding[0].to_bytes(32, byteorder= 'big') + decoding 1 .to_bytes(32, byteorder= 'big')

  3. then used the new sign:

    vks = ecdsa.VerifyingKey.from_public_key_recovery_with_digest( new_sign, transaction, curve=ecdsa.SECP256k1, hashfunc=sha256 )

another thing i encountered was with kms_client.get_public_key() so ill add it here anyways:

  1. First call the method:

    kms_pub_key_bytes = kms_client.get_public_key(KeyId=key_id)["PublicKey"]

  2. then get the last 128 chars which are essentially the r and s values

    kms_pre_sha3 = kms_pub_key_bytes.hex()[-128:]

from there on do whatever you want with the public key:)

I hope that helps someone, since i for sure needed it.

i will also link an article i read that could further help: https://medium.com/asecuritysite-when-bob-met-alice/der-asn-1-and-crypto-formatting-43c33d8fe639

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM