使用 PHP 为 Apple Wallet 通行证创建 PKCS #7 分离签名

Sha*_*ane 2 php ssl sign ios pkcs#7

这对我来说是一个全新的概念,所以我在黑暗中拍摄。

要创建签名文件,请使用与您的签名证书关联的私钥对清单文件进行 PKCS #7 分离签名。包括 WWDR 中间证书作为签名的一部分。您可以从 Apple 的网站下载此证书。将签名写入pass包顶层的文件签名。包括使用 S/MIME 签名时间属性对通行证进行签名的日期和时间。

我的理解:

要创建签名文件,请制作清单文件的 PKCS #7 分离签名

我将openssl_pkcs7_sign使用 flag使用该函数PKCS7_DETACHED

使用与您的签名证书关联的私钥。

我将使用我的 sslcert.pem文件的位置作为signcert参数,并使用cert.key文件的位置作为privkey参数。

包括 WWDR 中间证书作为签名的一部分。

我将在extracerts参数中包含 WWDR 证书的路径

包括使用 S/MIME 签名时间属性对通行证进行签名的日期和时间。

我将包括一个关键的阵列signing-time和价值类似2015-05-03 10:40:00headers参数。

我的代码:

private function createSignature($dir)
{
    $cert = '/etc/ssl/cert.pem';
    $key = '/etc/ssl/private/cert.key';
    $wwdr = '/location/of/apple/wwdr/cert.cer';
    $headers = [
        'signing-time' => (new DateTime())->format('o-m-d H:i:s'),
    ];

    return openssl_pkcs7_sign("$dir/manifest.json", "$dir/signature", $cert, $key, $headers, PKCS7_DETACHED, $wwdr);
}
Run Code Online (Sandbox Code Playgroud)

其他问题:

我在该openssl_pkcs7_sign函数的文档示例中注意到,文件的某些位置以file://. 为什么是这样?

Sha*_*ane 6

  1. https://developer.apple.com/account/ios/identifier/passTypeId生成通行证类型 ID
  2. https://developer.apple.com/account/ios/certificate/create/为该 Pass Type ID 创建证书
  3. 下载证书并将其放入您的钥匙串中
  4. 在您的钥匙串中找到证书并将其导出为Certificates.p12没有密码
  5. 打开终端,运行openssl pkcs12 -in Certificates.p12 -clcerts -nokeys -out pass_cert.pem -passin pass:生成证书
  6. 在终端中,运行openssl pkcs12 -in Certificates.p12 -nocerts -out pass_key.pem -passin pass: -passout pass:YourPassword以生成密钥
  7. https://www.apple.com/certificateauthority/下载 WWDR 证书并将其放入您的钥匙串
  8. 将 WWDR 证书从您的钥匙串导出为 wwdr.pem

创建分离签名的函数:

public function createSignature()
{
    $cert = "file://location/of/pass_cert.pem";
    $key = "file://location/of/pass_key.pem";
    $wwdr = "/location/of/wwdr.pem";

    openssl_pkcs7_sign("/location/of/manifest.json", "/location/of/signature",
        $cert, [$key, 'YourPassword'], [], PKCS7_BINARY | PKCS7_DETACHED, $wwdr);

    // convert pem to der
    $signature = file_get_contents("/location/of/signature");
    $begin = 'filename="smime.p7s"';
    $end = '------';
    $signature = substr($signature, strpos($signature, $begin) + strlen($begin));
    $signature = substr($signature, 0, strpos($signature, $end));
    $signature = trim($signature);
    $signature = base64_decode($signature);

    file_put_contents("/location/of/signature", $signature);
}
Run Code Online (Sandbox Code Playgroud)

参考: