I am trying to implement the server-side auth verification for iOS GameKit client-side authenticated user as detailed here:
This API receives the Player ID, timestamp and salt from the Client. It also sends the public keys URL. The certificate needs to be fetched from this URL to extract the public key but the encoding seems weird as every decode format failed but reading the same certificate from a local file works. So as work around, I'm reading it from a file thats downloaded in a seperate job.
I have written the code for verification process as below but its always failing at the verification step, any idea where I am going wrong?
import struct
import base64
import hashlib
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography import x509
from cryptography.hazmat.primitives import hashes
# GameKit public key URL and other params
public_key_url = "https://static.gc.apple.com/public-key/gc-prod-9.cer"
player_id = <GameKit_TeamPlayerID>
bundle_id = <App_Bundle_ID>
timestamp = 1683019415788
salt = "OnSojw=="
# client-generated signature and payload
client_signature = <GameKit_Client_Signature>
client_payload =player_id.encode('UTF-8') + bundle_id.encode('UTF-8') + struct.pack('>Q',timestamp) + base64.b64decode(salt)
# Download and decode the GameKit public key
# Or read from local cer file
with open("gc-prod-9.cer", "rb") as f:
cert_data = f.read()
# Parse the certificate data
cert = x509.load_der_x509_certificate(cert_data)
# Extract the public key from the certificate
public_key = cert.public_key()
# Hash the client payload with SHA-256
payload_hash = hashlib.sha256(client_payload).digest()
# Verify the client signature using the GameKit public key
signature_bytes = base64.b64decode(client_signature)
try:
public_key.verify(
signature_bytes,
payload_hash,
padding.PKCS1v15(),
hashes.SHA256()
)
print("Client signature verified successfully")
except Exception as e:
print("Client signature verification failed")
print(str(e))
Its throwing the exception:
in _rsa_sig_verify raise InvalidSignature cryptography.exceptions.InvalidSignature
Am I missing something? I could not find any up-to-date answer or code sample anywhere.
I have already gone through this 10 year old SO post but the solution is obsolete and as far as I could understand, my code is just the updated version of the answers.