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)