我需要验证 x509 中的哪些字段(作为 JWS 中的 x5c 标头)来证明证书的合法性?

Rai*_*idi 4 php storekit x509 jwt

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

事情是这样的,我对 JWS 还很陌生,Apple 现在将它们作为服务器到服务器通信的一部分进行传输。我试图了解如何完全保证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));
}
Run Code Online (Sandbox Code Playgroud)

是否有一个特定字段可以检查证书内部(无法被欺骗的字段)以验证 JWS 的身份/来源?

谢谢!

Rai*_*idi 6

感谢@IMSoP 为我指明了正确的方向。当 JWS 包含证书链(x5c标头)时,我们应该拥有这些有效证书的副本(或者至少是根证书,因为它验证链的其余部分)。就我而言,我可以在苹果网站上找到它们。

下载它们后,就像这样简单:

openssl_x509_verify($jws_root_cert, $downloaded_apple_root_cert);
Run Code Online (Sandbox Code Playgroud)