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

标签 php jwt x509 storekit

我已经发布了类似的问题 here ,但我意识到我的问题可能更多地与 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));
}

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

谢谢!

最佳答案

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

下载后,操作非常简单:

openssl_x509_verify($jws_root_cert, $downloaded_apple_root_cert);

关于php - 我在 x509(如 JWS 中的 x5c header )中验证哪些字段以证明证书的合法性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69816264/

相关文章:

java - 找不到符号 : KeyStore. TrustedCertificateEntry

c# - 使用私钥将 X509Certificate2 导出到字节数组

saml - 如何验证 SAML 证书?

xml - 通过 JWT token 在 Azure API 管理中进行授权

php - 使用curl和正则表达式获取表数据

php - 将 PHP 的不同变量输入接收到 C++ 中

php - PHP cURL 可以在单个请求中检索响应 header 和正文吗?

ios - 验证 JWT token 签名

java - Spring Security 中 PreAuthenticatedAuthenticationToken 的用途?

php - 如何使用 Luracast ReSTLer 返回 HTTP 200 OK 以外的肯定响应?