如何将与密码学相关的代码从Go移植到Python

I am trying to port certain logic from Go to Python 3, and I'm stuck with cryptography-related code.

Original code in Go is here: https://github.com/avast/apkverifier/blob/master/signingblock/frosting.go

In particular, I'm stuck in the verifySignature function:

func (f *frostingInfo) verifySignature(signed, signature []byte, keyBase64 string) error {
    dec := base64.NewDecoder(base64.StdEncoding, strings.NewReader(keyBase64))
    pubKeyAsn, err := ioutil.ReadAll(dec)
    if err != nil {
        return fmt.Errorf("failed to parse key base64: %s", err.Error())
    }

    keyDigest := sha256.Sum256(pubKeyAsn)
    f.usedKeySha256 = hex.EncodeToString(keyDigest[:])

    pkGen, err := x509.ParsePKIXPublicKey(pubKeyAsn)
    if err != nil {
        return fmt.Errorf("failed to unmarshal pk: %s", err.Error())
    }

    pk, ok := pkGen.(*ecdsa.PublicKey)
    if !ok {
        return fmt.Errorf("invalid key type: %T", pkGen)
    }

    digest := sha256.Sum256(signed)

    ecdsaSig := new(ecdsaSignature)
    if rest, err := asn1.Unmarshal(signature, ecdsaSig); err != nil {
        return err
    } else if len(rest) != 0 {
        return errors.New("x509: trailing data after ECDSA signature")
    }

    if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
        return errors.New("x509: ECDSA signature contained zero or negative values")
    }

    if !ecdsa.Verify(pk, digest[:], ecdsaSig.R, ecdsaSig.S) {
        return ErrFrostingInvalidSignature
    }

    return nil
}

How can I port to Python following calls?

  • x509.ParsePKIXPublicKey(pubKeyAsn)
  • pk, ok := pkGen.(*ecdsa.PublicKey)
  • asn1.Unmarshal(signature, ecdsaSig)
  • ecdsa.Verify(pk, digest[:], ecdsaSig.R, ecdsaSig.S)

What I have so far:

import logging

import base64
import hashlib
from .androguard_apk import APK
from .byte_reader import ByteReader
import ecdsa
from Crypto.PublicKey import RSA
from Crypto.Util import asn1


logger = logging.getLogger(__name__)
.....
def verifySignature(signed, signature, keyBase64):
    dec = base64.b64decode(keyBase64)
    pubKeyAsn = dec
    keyDigest = hashlib.sha256(pubKeyAsn).digest()
    logger.info(hashlib.sha256(pubKeyAsn).hexdigest())
    vk = ecdsa.VerifyingKey.from_der(pubKeyAsn)
    logger.info(f"Key:{vk.to_string()} ")
    # vk = ecdsa.VerifyingKey.from_string(hashlib.sha256(pubKeyAsn).hexdigest())
    # vk = ecdsa.VerifyingKey.from_string(keyBase64)
    digest = hashlib.sha256(signed).digest()
    vk.verify_digest(signature, digest)
    #res = vk.verify(signature, signed)
    logger.info(f"Validation result: {res}" )

value of keyBase64 is MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZH2+1+E07dnErAD3L6BbTnaohU0bbXriNlJI7VxJU+LjdSwPyXR5pomARAMoyPkMksLz/gitUPtFuJoPL2ziEw==

I am keep getting this error and I don't know how to proceed:

  File "apk_frosting_verifier#link-tree/apk_frosting_verifier/apk_frosting_verifier.py", line 173, in verifySignature
    vk.verify_digest(signature, digest)
  File "apk_frosting_verifier#link-tree/ecdsa/keys.py", line 109, in verify_digest
    r, s = sigdecode(signature, self.pubkey.order)
  File "apk_frosting_verifier#link-tree/ecdsa/util.py", line 221, in sigdecode_string
    assert len(signature) == 2*l, (len(signature), 2*l)
AssertionError: (71, 64)