我在 x509 中验证哪些字段(如 JWS 中的 x5c header)以证明证书的合法性?

What fields do I verify in a x509 (as x5c header in a JWS) to prove legitimacy of the Certificate?

我已经发布了一个类似的问题 here,但我意识到我的问题可能更多地与 x509 证书有关,而不是一般的 JWS。

事情是这样的,我是 JWS 的新手,Apple 现在将它们作为 server-to-server 通信的一部分进行传输。我试图了解如何完全保证 JWS 的有效性,因为据我了解,签名验证仅意味着整个 JWS 未被篡改。 我不知道如何实际验证此负载确实来自可信来源(又名 Apple)

这是我目前得到的结果 (PHP):

//1. explode jws and decode what's needed
$components = explode('.', $jws);
$headerJson = json_decode(base64_decode($components[0]),true);
$signature = base64Url_decode($components[2]);

//2. extract all certificates from 'x5c' header
foreach ($headerJson['x5c'] as $x5c){
    $c = '-----BEGIN CERTIFICATE-----'.PHP_EOL;
    $c .= chunk_split($x5c,64,PHP_EOL);
    $c .= '-----END CERTIFICATE-----'.PHP_EOL;
    $certificates[] = openssl_x509_read($c);
}

//3. verify validity of certificate chain (each one is signed by the next, except root cert)
for($i = 0; $i < count($certificates); $i++){
    if ($i == count($certificates) - 1){
        if (openssl_x509_verify($certificates[$i], $certificates[$i]) != 1){
            throw new Exception("Invalid Root Certificate");
        }
    }
    else{
        if (openssl_x509_verify($certificates[$i], $certificates[$i+1]) != 1){
            throw new Exception("Invalid Certificate");
        }
    }
}

//4. get public_key from first certificate
$public_key = openssl_pkey_get_public($certificates[0]);

//5. verify entire token, including signature (using the Firebase library)
$parsed_token = (array) \Firebase\JWT\JWT::decode($jws, $public_key, ['ES256']);

//helper function: a simple base64 url decoder
function base64Url_decode($data){
    return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}

是否有一个特定的字段可以在证书中检查(不能被欺骗)以验证 JWS 的 identity/source?

谢谢!

感谢@IMSoP 为我指明了正确的方向。 当 JWS 包含证书链 (x5c header) 时,我们应该拥有这些有效证书的副本(或者至少是根证书,因为它验证链的其余部分)。就我而言,我可以在 Apple's website.

上找到它们

下载后,操作非常简单:

openssl_x509_verify($jws_root_cert, $downloaded_apple_root_cert);