В настоящее время я работаю над проверкой полезной нагрузки уведомления сервера Apple App Store (JWS) в приложении Laravel. Подписанные полезные данные включают в себя цепочку сертификатов в заголовке x5c, которую мне нужно проверить с помощью OpenSSL. Однако при попытке проверить подпись я получаю следующую ошибку:
0480006C:PEM routines::no start line
Похоже, проблема возникает, когда я пытаюсь извлечь открытый ключ из листового сертификата, а затем проверить подпись JWS.
Вот последовательность действий, которую я реализую:
Извлеките заголовок x5c из полезных данных JWS, чтобы получить цепочку сертификатов (листовой, промежуточный, корневой).
Преобразуйте сертификаты в кодировке Base64 из формата x5c в формат PEM с помощью следующий помощник функция:
private function buildPemFromX5c(string $x5c): string
{
return "-----BEGIN CERTIFICATE-----\n" . wordwrap($x5c, 64, "\n", true) . "\n-----END CERTIFICATE-----";
}
Загрузите открытый ключ из листового сертификата с помощью функции OpenSSL openssl_pkey_get_public().
Проверьте подпись JWS с помощью openssl_verify():
$isValid = openssl_verify($dataToVerify, $signature, $publicKey, OPENSSL_ALGO_SHA256);
Здесь возникает ошибка 0480006C:PEM подпрограммы::нет начальной строки, что указывает на проблему с форматом сертификата или открытого ключа. Похоже, данные PEM анализируются неправильно или формат открытого ключа недействителен.
Вот весь код:
public function signedPayload(Request $request)
{
try {
// Step 1: Get the signed payload from the request
$signedPayload = $request->signedPayload;
// Step 2: Split the signed payload into header, payload, and signature
[$encodedHeader, $encodedPayload, $encodedSignature] = explode('.', $signedPayload);
// Step 3: Decode the header and payload using Base64Url
$decodedHeader = base64_decode($encodedHeader);
$decodedPayload = base64_decode($encodedPayload);
$signature = base64_decode($encodedSignature);
// Step 4: Parse the JWS header
$decodedHeaderData = json_decode($decodedHeader, true);
if (!$decodedHeaderData || !isset($decodedHeaderData['x5c'])) {
throw new Exception('Invalid header: Missing x5c');
}
// Step 5: Get the certificate chain (x5c) from the header
$x5c = $decodedHeaderData['x5c'];
$this->validateCertificateChain($x5c);
// Step 6: Build the PEM format public key from x5c[0] (leaf certificate)
$pem = $this->buildPemFromX5c($x5c[0]);
// Step 7: Extract the public key from the PEM certificate using OpenSSL
$publicKey = openssl_pkey_get_public($pem);
if (!$publicKey) {
throw new Exception('Failed to extract public key from PEM certificate');
}
Log::info('Public Key Loaded: ', ['publicKey' => openssl_pkey_get_details($publicKey)['key']]);
// Step 8: Prepare the data to verify (header + payload)
$dataToVerify = $encodedHeader . '.' . $encodedPayload;
// Step 9: Verify the signature using OpenSSL
$isValid = openssl_verify($dataToVerify, $signature, $publicKey, OPENSSL_ALGO_SHA256);
// Step 10: Check if signature is valid
if ($isValid === 1) {
Log::info('Signature is valid');
return response()->json(['status' => 'success', 'message' => 'Payload signature is valid']);
} elseif ($isValid === 0) {
throw new Exception('Signature verification failed');
} else {
throw new Exception('Error during signature verification: ' . openssl_error_string());
}
} catch (Exception $e) {
Log::error('Error validating signed payload: ' . $e->getMessage());
return response()->json(['status' => 'error', 'message' => $e->getMessage()], 400);
}
}
private function validateCertificateChain(array $x5c): bool
{
$rootCAPath = storage_path('AppleRootCA-G3.pem'); // Path to Apple's root certificate (download it)
$tempDir = sys_get_temp_dir();
$certFiles = [];
foreach ($x5c as $index => $cert) {
$certPath = "{$tempDir}/cert{$index}.pem";
file_put_contents($certPath, $this->buildPemFromX5c($cert));
$certFiles[] = $certPath;
}
// Validate the chain (ensure each cert is signed by the next)
for ($i = 0; $i < count($certFiles) - 1; $i++) {
$currentCert = $certFiles[$i];
$parentCert = $certFiles[$i + 1];
$currentCertDetails = openssl_x509_parse(file_get_contents($currentCert));
$parentCertKey = openssl_pkey_get_public(file_get_contents($parentCert));
if (!openssl_x509_verify(file_get_contents($currentCert), $parentCertKey)) {
throw new Exception("Invalid certificate chain at position {$i}");
}
}
// Verify the root certificate
$lastCert = $certFiles[count($certFiles) - 1];
$isRootValid = openssl_x509_checkpurpose($lastCert, X509_PURPOSE_ANY, [$rootCAPath]);
if (!$isRootValid) {
throw new Exception('Invalid certificate chain: Root CA does not match');
}
Log::info('Root CA matched successfully');
return true;
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... ed-payload
Возникла ошибка при попытке проверки полезных данных, подписанных Apple. ⇐ Php
Кемеровские программисты php общаются здесь
1732809679
Anonymous
В настоящее время я работаю над проверкой полезной нагрузки уведомления сервера Apple App Store (JWS) в приложении Laravel. Подписанные полезные данные включают в себя цепочку сертификатов в заголовке x5c, которую мне нужно проверить с помощью OpenSSL. Однако при попытке проверить подпись я получаю следующую ошибку:
0480006C:PEM routines::no start line
Похоже, проблема возникает, когда я пытаюсь извлечь открытый ключ из листового сертификата, а затем проверить подпись JWS.
Вот последовательность действий, которую я реализую:
Извлеките заголовок x5c из полезных данных JWS, чтобы получить цепочку сертификатов (листовой, промежуточный, корневой).
Преобразуйте сертификаты в кодировке Base64 из формата x5c в формат PEM с помощью следующий помощник функция:
private function buildPemFromX5c(string $x5c): string
{
return "-----BEGIN CERTIFICATE-----\n" . wordwrap($x5c, 64, "\n", true) . "\n-----END CERTIFICATE-----";
}
Загрузите открытый ключ из листового сертификата с помощью функции OpenSSL openssl_pkey_get_public().
Проверьте подпись JWS с помощью openssl_verify():
$isValid = openssl_verify($dataToVerify, $signature, $publicKey, OPENSSL_ALGO_SHA256);
Здесь возникает ошибка 0480006C:PEM подпрограммы::нет начальной строки, что указывает на проблему с форматом сертификата или открытого ключа. Похоже, данные PEM анализируются неправильно или формат открытого ключа недействителен.
Вот весь код:
public function signedPayload(Request $request)
{
try {
// Step 1: Get the signed payload from the request
$signedPayload = $request->signedPayload;
// Step 2: Split the signed payload into header, payload, and signature
[$encodedHeader, $encodedPayload, $encodedSignature] = explode('.', $signedPayload);
// Step 3: Decode the header and payload using Base64Url
$decodedHeader = base64_decode($encodedHeader);
$decodedPayload = base64_decode($encodedPayload);
$signature = base64_decode($encodedSignature);
// Step 4: Parse the JWS header
$decodedHeaderData = json_decode($decodedHeader, true);
if (!$decodedHeaderData || !isset($decodedHeaderData['x5c'])) {
throw new Exception('Invalid header: Missing x5c');
}
// Step 5: Get the certificate chain (x5c) from the header
$x5c = $decodedHeaderData['x5c'];
$this->validateCertificateChain($x5c);
// Step 6: Build the PEM format public key from x5c[0] (leaf certificate)
$pem = $this->buildPemFromX5c($x5c[0]);
// Step 7: Extract the public key from the PEM certificate using OpenSSL
$publicKey = openssl_pkey_get_public($pem);
if (!$publicKey) {
throw new Exception('Failed to extract public key from PEM certificate');
}
Log::info('Public Key Loaded: ', ['publicKey' => openssl_pkey_get_details($publicKey)['key']]);
// Step 8: Prepare the data to verify (header + payload)
$dataToVerify = $encodedHeader . '.' . $encodedPayload;
// Step 9: Verify the signature using OpenSSL
$isValid = openssl_verify($dataToVerify, $signature, $publicKey, OPENSSL_ALGO_SHA256);
// Step 10: Check if signature is valid
if ($isValid === 1) {
Log::info('Signature is valid');
return response()->json(['status' => 'success', 'message' => 'Payload signature is valid']);
} elseif ($isValid === 0) {
throw new Exception('Signature verification failed');
} else {
throw new Exception('Error during signature verification: ' . openssl_error_string());
}
} catch (Exception $e) {
Log::error('Error validating signed payload: ' . $e->getMessage());
return response()->json(['status' => 'error', 'message' => $e->getMessage()], 400);
}
}
private function validateCertificateChain(array $x5c): bool
{
$rootCAPath = storage_path('AppleRootCA-G3.pem'); // Path to Apple's root certificate (download it)
$tempDir = sys_get_temp_dir();
$certFiles = [];
foreach ($x5c as $index => $cert) {
$certPath = "{$tempDir}/cert{$index}.pem";
file_put_contents($certPath, $this->buildPemFromX5c($cert));
$certFiles[] = $certPath;
}
// Validate the chain (ensure each cert is signed by the next)
for ($i = 0; $i < count($certFiles) - 1; $i++) {
$currentCert = $certFiles[$i];
$parentCert = $certFiles[$i + 1];
$currentCertDetails = openssl_x509_parse(file_get_contents($currentCert));
$parentCertKey = openssl_pkey_get_public(file_get_contents($parentCert));
if (!openssl_x509_verify(file_get_contents($currentCert), $parentCertKey)) {
throw new Exception("Invalid certificate chain at position {$i}");
}
}
// Verify the root certificate
$lastCert = $certFiles[count($certFiles) - 1];
$isRootValid = openssl_x509_checkpurpose($lastCert, X509_PURPOSE_ANY, [$rootCAPath]);
if (!$isRootValid) {
throw new Exception('Invalid certificate chain: Root CA does not match');
}
Log::info('Root CA matched successfully');
return true;
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79234300/error-encountered-when-trying-to-verifying-apple-signed-payload[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия