0

我试图在我的应用程序和 php 之间设置应用程序证明,但除了 Apple 自己的文档之外,我很少找到任何其他解释来源,这让我陷入了相当早期的状态。到目前为止,我得到了以下步骤:

在客户端,按照https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity,我将我的证明创建为 base64 编码字符串:

attestation.base64EncodedString()

然后我从现在开始按照https://developer.apple.com/documentation/devicecheck/validating_apps_that_connect_to_your_server将该字符串发送到服务器。

文档说,证明是 CBOR 格式。因此,我首先解码 base64 编码字符串并使用 ( https://github.com/Spomky-Labs/cbor-php ) 对其进行解析。

<?php
use CBOR\Decoder;
use CBOR\OtherObject;
use CBOR\Tag;
use CBOR\StringStream;

$otherObjectManager = new OtherObject\OtherObjectManager();
$tagManager = new Tag\TagObjectManager();

$decoder = new Decoder($tagManager, $otherObjectManager);
$data = base64_decode(/* .. base64 encoded attestation string as send from the client (see swift snippet above) */);

$stream = new StringStream($data);
$object = $decoder->decode($stream);

$norm = $object->getNormalizedData();
$fmt = $norm['fmt'];
$x5c = $norm['attStmt']['x5c'];

从文档中,规范化对象应具有以下格式:

{
   fmt: 'apple-appattest',
   attStmt: {
     x5c: [
       <Buffer 30 82 02 cc ... >,
       <Buffer 30 82 02 36 ... >
     ],
     receipt: <Buffer 30 80 06 09 ... >
   },
   authData: <Buffer 21 c9 9e 00 ... >
 }

它的作用:

$fmt == "apple-appattest" // true

然后根据文档的下一个描述为:

验证 x5c 数组是否包含 App Attest 的中间证书和叶证书,从数组中第一个数据缓冲区 (credcert) 中的凭证证书开​​始。使用Apple 的 App Attest 根证书验证证书的有效性。

但是,我不知道如何进一步进行。eg 的内容$norm['attStmt']['x5c'][0]是可读字符和字形的混合。为了给你一个想法,这是来自以下内容的随机子字符串$norm['attStmt']['x5c'][0]:“Certification Authority10U Apple Inc.10 UUS0Y0*�H�=*�H�=B��c�}�”。这就是为什么我不是真的确定我必须执行任何进一步的编码/解码步骤。

我尝试解析证书,但没有任何运气(var_dump 都返回 false):

 $cert = openssl_x509_read($x5c[0]);
 var_dump($cert); // false - indicating that reading the cert failed
 
 $parsedCert = openssl_x509_parse($cert, false);
 var_dump($parsedCert); // false - of course, since the prior step did not succeed

非常感谢任何想法、指导或替代资源。谢谢!

4

1 回答 1

0

过了一会儿,我想出了以下解决方案。$x5c 字段包含一个证书列表,都是二进制形式。我编写了以下转换器来创建 PEM 格式的即用型证书,它执行以下操作:

  1. base64 对二进制数据进行编码
  2. 64 字节后换行
  3. 添加 BEGIN 和 END 标记(还要注意结束证书行上的尾随换行符)

function makeCert($bindata) {
     $beginpem = "-----BEGIN CERTIFICATE-----\n";
    $endpem = "-----END CERTIFICATE-----\n";

    $pem = $beginpem;
    $cbenc = base64_encode($bindata);
    for($i = 0; $i < strlen($cbenc); $i++) {
        $pem .= $cbenc[$i];
        if (($i + 1) % 64 == 0)
            $pem .= "\n";
    }
    $pem .= "\n".$endpem;

    return $pem;
}

然后以下工作:

openssl_x509_read(makeCert($x5c[0]))
于 2021-10-14T08:21:04.750 回答