Passbook, PHP и подпись

Всякий раз, когда я пытаюсь добавить свой пропуск в сберегательную книжку, он терпит неудачу из-за:

Подпись манифеста не прошла успешную проверку

Мой код для подписи ниже:

$privKey = "certs/key.pem";
$keyPassword = "PASSWORD";
$wwdr = "certs/wwdr.pem";
$cert = file_get_contents("certs/certificate.pem");
$certData = openssl_x509_read($cert);

openssl_pkcs7_sign($path . "/" . "manifest.json", 
$path . "/" . "signature", 
$certData, 
array("file://" . $privKey, $keyPassword), 
array(), 
PKCS7_BINARY|PKCS7_NOATTR|PKCS7_DETACHED,
"certs/wwdr.pem");

Спасибо!


person caycehouse    schedule 22.03.2013    source источник
comment
Правильно ли вы получаете данные с помощью WWDR?   -  person Marin Sagovac    schedule 22.03.2013
comment
Я должен получить это как-то по-другому?   -  person caycehouse    schedule 22.03.2013
comment
Ознакомьтесь с этим github.com/tschoffelen/PHP-PKPass/blob/ master/src/PKPass.php   -  person Marin Sagovac    schedule 22.03.2013
comment
Да, я копался в его коде, но не видел, где мой обрывается.   -  person caycehouse    schedule 22.03.2013
comment
Попробуйте изменить PKCS7_BINARY|PKCS7_NOATTR|PKCS7_DETACHED на PKCS7_BINARY | PKCS7_DETACHED   -  person Marin Sagovac    schedule 22.03.2013
comment
И я не вижу подписи convertPEMtoDER. Это base64 расшифровано. Правильно ли закодирована ваша подпись base64?   -  person Marin Sagovac    schedule 22.03.2013
comment
Хорошо, я изменил первый код и добавил вторую часть кода. Я все еще получаю ту же ошибку, хотя в iosSimulator... в Safari моя ошибка имеет немного другое значение «PAPassValidator: _signatureIsValid не удалось загрузить файл подписи».   -  person caycehouse    schedule 22.03.2013


Ответы (1)


Попробуйте следующее, используя файл сертификата, а не его содержимое, и удалив PKSC7_NOATTR, поскольку в iOS 6.1.1 подпись должна содержать дату подписания.

openssl_pkcs7_sign($path . "/manifest.json",
            $path . "/signature",
            'file://' . $fullPathTo . 'certs/certificate.pem',
            array('file://' . $fullPathTo . $privKey, $keyPassword),
            array(),
            PKCS7_BINARY|PKCS7_DETACHED,
            $fullPathTo . $wwdr);

openssl_pkcs7_sign создает вложение электронной почты, поэтому вам также потребуется извлечь часть подписи, так как это все, что нужно пакету .pkpass.

// Read the signature file
$email = file_get_contents($path . "/signature");

// Extract the signature using a regex
$pattern = "/.*?Content-Disposition: attachment; filename=\".*?\"(.*?)-----.*?/sm";
preg_match_all($pattern, $email, $signature);

// Base64 encode the part of result we need
$signature = base64_decode($signature[1][0]);

// Write contents to a new signature file
file_put_contents ($path . "/signature", $signature);

Если он по-прежнему не загружается, убедитесь, что ваш сертификат является действительным сертификатом идентификатора типа пропуска и что ваш закрытый ключ является правильным для вашего сертификата. Вы даже можете проверить свои журналы PHP, чтобы убедиться, что команда openssl_pkcs7_sign выполняется правильно.


Обновить

Когда я пытаюсь добавить ваш пакет .pkpass в Passbook, я получаю следующую ошибку в консоли устройства.

<Warning>: Invalid data error reading pass pass.datafarms.peppermints/123456. Manifest JSON didn't parse: The operation couldn’t be completed. (Cocoa error 3840.)

Ваш файл подписи выглядит нормально, ошибка заключается в части вашего кода, которая вычисляет хэши SHA1 и создает manifest.json

Глядя на ваш пакет .pkpass, ваш манифест поврежден двумя способами:

  1. Он содержит несколько объектов
  2. Значения SHA1 не соответствуют содержимому файла

Для этого пакета .pkpass ваш manifest.json должен быть:

{
    "strip.png" : "f95387c0843a51dac73f1b0a3181da9c99ba3dc4",
    "[email protected]" : "f325a97fc6bafbe53a5e8feb7b2c509a8ceb6b10",
    "[email protected]" : "7b7b025774128b95e50f2bcda55e608412e95a37",
    "[email protected]" : "68b61c27657a0018da71c7f73626c8a891da753c",
    "icon.png" : "6b15fa477ece83fdd4f544a2381444272a0e39a0",
    "logo.png" : "7cf1d842afde33c4b14978f330cf98d05c3e57f2",
    "pass.json" : "971417ec80638736cb3392d6d5db53d554f138a4",
}

Но на данный момент это:

{
    "strip.png" : "156b528933284a0a58fc316897e1b7d202dfe3e8",
    "[email protected]" : "99f5dc1a0c5ed300193f87e42d8632f7251a3f26",
    "[email protected]" : "f36816f173aa9011186b80b140dfc49395d31051",
    "[email protected]" : "c10dd92e6c043c4bcf6214251d6fcb2a760cd9ad",
    "icon.png" : "d181ad4208e06afb63d5e6049a40521b458da19d",
    "logo.png" : "81c27284f77a447375ba39fb2f0005eeaccf28d8",
    "pass.json" : "e5960e9004d5fff241d77415413d609f47d7b2fb",
}{
    "strip.png" : "156b528933284a0a58fc316897e1b7d202dfe3e8",
    "[email protected]" : "99f5dc1a0c5ed300193f87e42d8632f7251a3f26",
    "[email protected]" : "f36816f173aa9011186b80b140dfc49395d31051",
    "[email protected]" : "c10dd92e6c043c4bcf6214251d6fcb2a760cd9ad",
    "icon.png" : "d181ad4208e06afb63d5e6049a40521b458da19d",
    "logo.png" : "81c27284f77a447375ba39fb2f0005eeaccf28d8",
    "pass.json" : "e5960e9004d5fff241d77415413d609f47d7b2fb",
}{
    "strip.png" : "156b528933284a0a58fc316897e1b7d202dfe3e8",
    "[email protected]" : "99f5dc1a0c5ed300193f87e42d8632f7251a3f26",
    "[email protected]" : "f36816f173aa9011186b80b140dfc49395d31051",
    "[email protected]" : "c10dd92e6c043c4bcf6214251d6fcb2a760cd9ad",
    "icon.png" : "d181ad4208e06afb63d5e6049a40521b458da19d",
    "logo.png" : "81c27284f77a447375ba39fb2f0005eeaccf28d8",
    "pass.json" : "e5960e9004d5fff241d77415413d609f47d7b2fb",
}{
    "strip.png" : "156b528933284a0a58fc316897e1b7d202dfe3e8",
    "[email protected]" : "99f5dc1a0c5ed300193f87e42d8632f7251a3f26",
    "[email protected]" : "f36816f173aa9011186b80b140dfc49395d31051",
    "[email protected]" : "c10dd92e6c043c4bcf6214251d6fcb2a760cd9ad",
    "icon.png" : "d181ad4208e06afb63d5e6049a40521b458da19d",
    "logo.png" : "81c27284f77a447375ba39fb2f0005eeaccf28d8",
    "pass.json" : "e5960e9004d5fff241d77415413d609f47d7b2fb",
}{
    "strip.png" : "156b528933284a0a58fc316897e1b7d202dfe3e8",
    "[email protected]" : "99f5dc1a0c5ed300193f87e42d8632f7251a3f26",
    "[email protected]" : "f36816f173aa9011186b80b140dfc49395d31051",
    "[email protected]" : "c10dd92e6c043c4bcf6214251d6fcb2a760cd9ad",
    "icon.png" : "d181ad4208e06afb63d5e6049a40521b458da19d",
    "logo.png" : "81c27284f77a447375ba39fb2f0005eeaccf28d8",
    "pass.json" : "e5960e9004d5fff241d77415413d609f47d7b2fb",
}{
    "strip.png" : "156b528933284a0a58fc316897e1b7d202dfe3e8",
    "[email protected]" : "99f5dc1a0c5ed300193f87e42d8632f7251a3f26",
    "[email protected]" : "f36816f173aa9011186b80b140dfc49395d31051",
    "[email protected]" : "c10dd92e6c043c4bcf6214251d6fcb2a760cd9ad",
    "icon.png" : "d181ad4208e06afb63d5e6049a40521b458da19d",
    "logo.png" : "81c27284f77a447375ba39fb2f0005eeaccf28d8",
    "pass.json" : "e5960e9004d5fff241d77415413d609f47d7b2fb",
}{
    "strip.png" : "156b528933284a0a58fc316897e1b7d202dfe3e8",
    "[email protected]" : "99f5dc1a0c5ed300193f87e42d8632f7251a3f26",
    "[email protected]" : "f36816f173aa9011186b80b140dfc49395d31051",
    "[email protected]" : "c10dd92e6c043c4bcf6214251d6fcb2a760cd9ad",
    "icon.png" : "d181ad4208e06afb63d5e6049a40521b458da19d",
    "logo.png" : "81c27284f77a447375ba39fb2f0005eeaccf28d8",
    "pass.json" : "e5960e9004d5fff241d77415413d609f47d7b2fb",
}{
    "strip.png" : "156b528933284a0a58fc316897e1b7d202dfe3e8",
    "[email protected]" : "99f5dc1a0c5ed300193f87e42d8632f7251a3f26",
    "[email protected]" : "f36816f173aa9011186b80b140dfc49395d31051",
    "[email protected]" : "c10dd92e6c043c4bcf6214251d6fcb2a760cd9ad",
    "icon.png" : "d181ad4208e06afb63d5e6049a40521b458da19d",
    "logo.png" : "81c27284f77a447375ba39fb2f0005eeaccf28d8",
    "pass.json" : "e5960e9004d5fff241d77415413d609f47d7b2fb",
}{
    "strip.png" : "156b528933284a0a58fc316897e1b7d202dfe3e8",
    "[email protected]" : "99f5dc1a0c5ed300193f87e42d8632f7251a3f26",
    "[email protected]" : "f36816f173aa9011186b80b140dfc49395d31051",
    "[email protected]" : "c10dd92e6c043c4bcf6214251d6fcb2a760cd9ad",
    "icon.png" : "d181ad4208e06afb63d5e6049a40521b458da19d",
    "logo.png" : "81c27284f77a447375ba39fb2f0005eeaccf28d8",
    "pass.json" : "e5960e9004d5fff241d77415413d609f47d7b2fb",
}{
    "strip.png" : "156b528933284a0a58fc316897e1b7d202dfe3e8",
    "[email protected]" : "99f5dc1a0c5ed300193f87e42d8632f7251a3f26",
    "[email protected]" : "f36816f173aa9011186b80b140dfc49395d31051",
    "[email protected]" : "c10dd92e6c043c4bcf6214251d6fcb2a760cd9ad",
    "icon.png" : "d181ad4208e06afb63d5e6049a40521b458da19d",
    "logo.png" : "81c27284f77a447375ba39fb2f0005eeaccf28d8",
    "pass.json" : "e5960e9004d5fff241d77415413d609f47d7b2fb",
}
person PassKit    schedule 22.03.2013
comment
Я попробовал то, что вы сказали мне сделать выше, и это все еще дает мне ту же ошибку, я знаю, что мой сертификат должен быть действительным, и я не получаю никаких ошибок в журналах php о том, что что-то идет не так. - person caycehouse; 24.03.2013
comment
Не могли бы вы опубликовать ссылку на пакет .pkpass, созданный вашим скриптом. Это должно дать некоторые подсказки относительно того, почему он терпит неудачу. - person PassKit; 25.03.2013
comment
Смотрите обновленный ответ - проблема с вашим manifest.json, а не с вашей подписью. - person PassKit; 26.03.2013
comment
Теперь я получаю эту ошибку после исправления моего манифеста, предполагая, что я неправильно архивирую? MobileSafari[5936] ‹Предупреждение›: спецификация не может извлечь архив: не удалось прочитать подпись PKZip MobileSafari[5936] ‹Предупреждение›: загрузка PassBook Pass не удалась : пропуск не может быть прочитан, поскольку он недействителен. - person caycehouse; 27.03.2013
comment
Можете выложить ссылку на другой .pkpass? - person PassKit; 27.03.2013
comment
Ваш manifest.json все еще неверен. Значения SHA1 выглядят нормально, но объект повторяется. Измените .pkpass на .zip, разархивируйте и посмотрите на свой manifest.json, и вы поймете, что я имею в виду. - person PassKit; 27.03.2013
comment
Я не видел ничего другого между моим манифестом, созданным моей программой, и манифестом, созданным программой, которая работает на 100%. - person caycehouse; 27.03.2013
comment
Можете ли вы опубликовать свой код, который создает ваш манифест? Похоже, это может быть добавление строки к существующему файлу. - person PassKit; 28.03.2013
comment
Этот код записывает манифест function writeManifest($data, $path) { $fp = fopen($path . "/" . 'manifest.json', 'w'); fwrite($fp, json_encode($data)); fclose($fp); } - person caycehouse; 29.03.2013
comment
Выглядит нормально, но, возможно, попробуйте изменить на function writeManifest($data, $path) { file_put_contents(json_encode($data), $path . "/" . 'manifest.json'); } Вы должны вызывать эту функцию только один раз - вы делаете что-нибудь еще с manifest.json, потому что ваш текущий вывод предполагает, что где-то есть цикл, который добавляет объект json несколько раз. - person PassKit; 29.03.2013