Ana içeriğe geç

HTML formu imzası

Alıcı, herhangi bir form alanını doğrudan tarayıcıda değiştirebilir — örneğin daha düşük bir tutar girebilir. Bu yüzden fatura alanları imzalı bir kapta taşınır: hizmet imzayı yeniden hesaplar ve eşleşmezse faturayı oluşturmaz.

İmzayı mağazanın sunucusu hesaplar. Tarayıcıya yalnızca hazır data ve signature çifti gider.

Ne imzalanır

data = base64url(json)
signature = HMAC-SHA256(data, formSecret)

HMAC, JSON baytları üzerinden değil, data dizesi üzerinden hesaplanır. Hizmet, imzayı gönderilen dizeye göre olduğu gibi doğrular ve ancak ondan sonra dizeyi çözer.

Buradan çıkan sonuç, kanonikleştirme olmadığıdır: anahtar sırası, JSON girintileme ve Unicode kaçış stili imzayı etkilemez. Herhangi bir standart JSON kodlayıcı iş görür.

Referans seti

Bu değerleri kodunuza koyun ve çıktıyı karşılaştırın.

Örnek gizli anahtar:

dvc3khto5WpjEPojZfYJsbJzFEPPVnRa

Tutar ve ödeme süresi sayı olarak; dizeler de kabul edilir:

{"projectId":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d","amountFiat":10.5,"currencyFiat":"USD","timeToPay":1,"description":"Order #7, delivery","serviceData":"order-7"}

data dizesi, bu baytların base64url'sidir. Burada dolgu kaldırılmıştır; hizmet dolgulu halini de kabul eder:

eyJwcm9qZWN0SWQiOiJhMWIyYzNkNC01ZTZmLTRhN2ItOGM5ZC0wZTFmMmEzYjRjNWQiLCJhbW91bnRGaWF0IjoxMC41LCJjdXJyZW5jeUZpYXQiOiJVU0QiLCJ0aW1lVG9QYXkiOjEsImRlc2NyaXB0aW9uIjoiT3JkZXIgIzcsIGRlbGl2ZXJ5Iiwic2VydmljZURhdGEiOiJvcmRlci03In0

Bu dizenin yukarıdaki gizli anahtarla imzası:

09628020c47400c9231420450af642adfdb3c246f33e3e12cb8e28f96c2a785e

Bu değerlerle, aşağıdaki örnekler tam olarak bu data ve imzayı yazdırır. Sonuna "output":"errors" anahtarı eklenmiş aynı JSON, farklı bir data dizesi ve farklı bir imza üretir.

JSON aynı göründüğü halde data eşleşmiyorsa neden JSON kodlayıcıdır: farklı anahtar sırası veya ayırıcılardan sonra boşluklar. Hizmet böyle bir kabı kabul eder, ancak referansla birebir eşleşmez.

Örnekler

<?php

function signedContainer(array $fields, string $formSecret): array {
$data = rtrim(strtr(base64_encode(json_encode($fields)), '+/', '-_'), '=');

return [
'data' => $data,
'signature' => hash_hmac('sha256', $data, $formSecret),
];
}

// Test values from the reference set. Before going live,
// replace the secret with the form secret from your project settings
$container = signedContainer([
'projectId' => 'a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d',
'amountFiat' => 10.5,
'currencyFiat' => 'USD',
'timeToPay' => 1,
'description' => 'Order #7, delivery',
'serviceData' => 'order-7',
], 'dvc3khto5WpjEPojZfYJsbJzFEPPVnRa');

echo $container['data'], "\n";
echo $container['signature'], "\n";

Örnek değerler ASCII'dir, ancak kod herhangi bir Unicode ile değişiklik gerekmeden çalışır. PHP ve Python, ASCII dışı karakterleri varsayılan olarak \uXXXX biçimine dönüştürür; JavaScript ham UTF-8 gönderir — hizmet ikisini de kabul eder.

İki yaygın hata

Kap yerine JSON imzalanır. HMAC, data dizesi üzerinden, yani base64url üzerinden hesaplanır. Hata kendini “her şey eşleşiyor ama imza eşleşmiyor” şeklinde gösterir.

Kap, imzalandıktan sonra yeniden oluşturulur. data dizesinin tek bir baytı bile değişirse imza geçersizdir. Çifti, kodunuzda tek bir yerde oluşturun.

İmza eşleşmiyorsa

JSON → data → imza zincirini adım adım izleyin; referanstan sapan ilk halka nedendir. Önce data dizesini kontrol edin: gizli anahtara bağlı değildir.