phpdevicecheck

App Attest - Hash verification of public key is failing


I'm implementing App Attest server verification on a PHP server.

I'm stuck on step 5 of the Verify the assertion documentation:

Create the SHA256 hash of the public key in credCert, and verify that it matches the key identifier from your app.

At this point, I have the following variables:

$credentialId = ... ; // Bytes extracted from the attestation authData
$credCert = openssl_x509_read($x5c[0]); // The certificate chain is verified elsewhere
$pKey = openssl_pkey_get_public($credCert); // Extract the public key
$keyPem = openssl_pkey_get_details($pKey)['key'];

I don't uderstand what should be SHA-256 encoded to result in $credentialId ($credentialId is correctly validated against the key identifier, as described in step 9).

What I tried so far:

Can someone point me in the right direction? What public key bytes should be extracted and hashed?


Solution

  • I found a solution.

    TL;DR

    $pKey = openssl_pkey_get_details(openssl_pkey_get_public($credCert));
    $pBytes = "\x04" . $pKey['ec']['x'] . $pKey['ec']['y'];
    
    if (hash('sha256', $pBytes, true) === $credentialId) {
         // SUCCESS!!
    }
    

    I published a Gist with my currently working solution for all the steps required by app attest in PHP.

    Why this works

    Apple expect the public key to be in the X9.62 uncompressed point format.

    As per this security exchange answer, we can create the format by extracting the x and y points from the key, concatenate them and prepend them with a 0x04.

    The x and y points are specified in the array returned by openssl_pkey_get_details in the following format:

    [
        "bits" => 256,
        "key" => """
          -----BEGIN PUBLIC KEY-----\n
          BLA BLA BLA BLA\n
          BLA BLA BLA BLA\n
          -----END PUBLIC KEY-----\n
          """,
        "ec" => [
          "curve_name" => "prime256v1",
          "curve_oid" => "1.2.840.10045.3.1.7",
          "x" => b"some random bytes",
          "y" => b"some random bytes",
        ],
        "type" => 3,
    ]