Post not yet marked as solved
aha, Signature is ASN.1, this is now valid
verified = verifyingKey.verify(decodedSignature, signature_base, hashfunc=hashlib.sha256, sigdecode=sigdecode_der)
Post not yet marked as solved
Update, this is slightly better, at least now I can see there is an issue with the signature, the authenticator is 37 bytes long, which breaks my generated signature:
32 bytes authenticator_data_bytes
32 bytes client_data_hash_bytes
signature = 64 bytes
I'm foolishly taking the first 32 bytes of the authenticator...seems very wrong
client_data_hash = hashlib.sha256()
client_data_hash.update(client_data_bytes)
client_data_hash_bytes = client_data_hash.digest()
key_from_dict = CoseKey.from_dict(key)
publicKeyU2F = b"".join([
#bytearray.fromhex('3059301306072a8648ce3d020106082a8648ce3d030107034200'),
(0x04).to_bytes(1, byteorder='big'),
key_from_dict.x,
key_from_dict.y
])
print("publicKeyU2F: {0}".format(publicKeyU2F))
signature_base = b"".join(
[
authenticator_data_bytes[0:32],
client_data_hash_bytes,
]
)
print("authenticator_data_bytes len: {}".format(len(authenticator_data_bytes)))
print("client_data_hash_bytes len: {}".format(len(client_data_hash_bytes)))
# vk = ecdsa.VerifyingKey.from_string(publicKeyU2F, curve=ecdsa.NIST256p, hashfunc=sha256) # the default is sha1
verifyingKey = ecdsa.VerifyingKey.from_string(publicKeyU2F, curve=ecdsa.NIST256p, hashfunc=sha256)
#verifyingKey = ecdsa.VerifyingKey.from_string(bytes.fromhex(keyasHex), curve=ecdsa.SECP256k1, hashfunc=sha256, valid_encodings=['raw'])
verified = verifyingKey.verify(signature_base, decodedSignature)
Gives a
ecdsa.keys.BadSignatureError: Signature verification failed
Post not yet marked as solved
Thanks, I'm trying to get it working with a very specific use-case to begin with, reading the spec, it reads like this should work, unfortunately, I always get a bad signature error :-(
client_data_hash = hashlib.sha256()
client_data_hash.update(client_data_bytes) #credentialAssertion.rawClientDataJSON
client_data_hash_bytes = client_data_hash.digest()
publicKey = b"".join([
(0x04).to_bytes(1, byteorder='big'),
key_from_dict.x,
key_from_dict.y
])
signature_base = b"".join(
[
authenticator_data_bytes, #credentialAssertion.rawAuthenticatorData
client_data_hash_bytes,
]
)
signature_base_hash = hashlib.sha256()
signature_base_hash.update(signature_base)
signature_base_hash_bytes = signature_base_hash.digest()
vk = ecdsa.VerifyingKey.from_string(publicKey, curve=ecdsa.NIST256p, hashfunc=sha256) # the default is sha1
sig = decodedSignature #credentialAssertion.signature decoded from base64 to bytes
msg = signature_base_hash_bytes
try:
vk.verify(sig, msg)
print("good signature")
except BadSignatureError:
print("BAD SIGNATURE")
Post not yet marked as solved
I've found the key in the authData section
Post not yet marked as solved
hmmm, as noted here: https://developer.apple.com/forums/thread/708982 the engineer states passkeys have no statement...confusing
Post not yet marked as solved
Thanks for that, just adding for future reference, it looks like the attestation object is in CBOR format.
Post not yet marked as solved
ah, reading the docs more, the key could be a cose key - but still, not sure how to extract it from the bytes