Disbursement

Asymmetric Signature

Asymmetric Signature merupakan metode kriptografi yang menggunakan public key dan private key untuk buat dan verifikasi signature. Private key digunakan untuk membuat signature, sementara public key digunakan untuk memverifikasinya. Dalam penerapannya, pembuatan signature menggunakan private key diterapkan untuk layanan dengan alur Merchant -> Espay. Sebaliknya, validasi signature menggunakan public key diterapkan untuk layanan dengan alur Espay -> Merchant.

  • SHA256withRSA untuk generate signature dengan private key.
X-SIGNATURE = base64Encode(SHA256withRSA(PrivateKey, StringToSign))
  • SHA256withRSA untuk validasi signature dengan public key.
Base64Decode(X-SIGNATURE) = SHA256withRSA(PublicKey, StringToSign)
  • StringToSign
StringToSign = HTTPMethod+”:”+RelativeUrl+”:”+ Lowercase((SHA-256(MinifyJson(RequestBody))))+”:”+Timestamp 
Komponen Asymmetric Signature
Komponen Keterangan
HTTP Method
HTTP Method layanan yang digunakan merchant.

Contoh:
POST
Relative URL
Path API URL layanan yang Anda gunakan.

Contoh:
  • API URL:
    https://sandbox-api.espay.id/api/v1.0/balance-inquiry
  • Relative URL:
    /api/v1.0/balance-inquiry
Request Body
Request Body layanan yang Anda gunakan dalam format JSON.
Timestamp
Tanggal dan waktu lokal customer, sama seperti X-TIMESTAMP Header.

Contoh:
yyyy-MM-ddThh:mi:ssTZD

Format:
2023-08-31T07:49:28+07:00
Generate Private Key dan Public Key (PKCS#1)

Private key dan public key untuk kebutuhan production dengan format PKCS#1 dapat Anda buat menggunakan SSL. Untuk kebutuhan development, Anda dapat menggunakan contoh private key dan public key yang tersedia.

Contoh generate private key dan public key dengan format PKCS#1

With openSSL 1.1.1(PKCS#1):

openssl genrsa -out private.pem 2048

openssl rsa -in private.pem -pubout > public.pub
Contoh Private Key dan Public Key (PKCS#1)

Contoh public key format PKCS#1


-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2O9xDMTBiZ5oOy3LBVn6
TerxWMHEwxl6gr0SX1dRt4be5vq2voFMoCHokeowqpeU5ZQi0EM36W7Q1K8hH6KR
jdNqhdIHyMh7X0yhVJTQ3Fz9QcjBfeMwoovmIYHP+U08GKz7j99VojSSriYvzT1m
PdwvTuAdFT3QEXfgdMLKQCjtXF/eyg2Q+xCYJALv+zeaPlsu00RO3TM5NGaCSbFC
oF/xa4IOfV+215beBvl1fUhW6mkEo7gdhK8T0ddk5bInEJs3YzDwQNtAutLEFVot
EKX2ETqIk8S1H7Pou7tSo73O0fFGaSBhG610bKIb9lLTXCQYJKk8bygPaL3aoT+5
QwIDAQAB
-----END PUBLIC KEY-----

Contoh private key format PKCS#1


-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA2O9xDMTBiZ5oOy3LBVn6TerxWMHEwxl6gr0SX1dRt4be5vq2
voFMoCHokeowqpeU5ZQi0EM36W7Q1K8hH6KRjdNqhdIHyMh7X0yhVJTQ3Fz9QcjB
feMwoovmIYHP+U08GKz7j99VojSSriYvzT1mPdwvTuAdFT3QEXfgdMLKQCjtXF/e
yg2Q+xCYJALv+zeaPlsu00RO3TM5NGaCSbFCoF/xa4IOfV+215beBvl1fUhW6mkE
o7gdhK8T0ddk5bInEJs3YzDwQNtAutLEFVotEKX2ETqIk8S1H7Pou7tSo73O0fFG
aSBhG610bKIb9lLTXCQYJKk8bygPaL3aoT+5QwIDAQABAoIBAQDTSPIcc43kUWpH
KSSxQ59sQEVsIt1W//u4VhoMzekDDNMQuGNATIKq/Bud8jAQFq6oo4z8tltAefPf
Eer6+sU1ExKO369BOTIf8Wy4CnEaD1+CsNrzl1EJH6S2Qc6jizva9K/WwriO0RGD
mCG6jfCEk21oLxNkWt3KBa2RSx7dOLO+ct07jtRbfYCVCAezyx6fWxLJ6eVmGZXM
kOhAr9tQ6IC3v/iQgA00LNPXR+X12obcmNXtcng5uHffeZNr6tmpLpXTYLdwZlwl
FINuTGpPjp1yy6q6GQYphF51ywRFN17g8NoVHLXDAfnrmB1lgtbC3nSiAvqEq2c6
XQkAIZbBAoGBAPgQDtG7RJ/Wdo5ra9HMgceVqDQgrdY4vw4cnV4NVGSBGn8jNhk7
YrJ8siJbLxqi5cPwJzu7xS8krKyt3vBY8AFKvVJ9yZ06VVL4d2LvWr50ym/zshnC
w1WlKhcuyaqP6MCiC6pZNA5LR1AN6hK2B1ZnmSrvDkg+MZtGTAxJrF6TAoGBAN/g
aVtaHuw1Zh2ixRfUjjQ4YMSxt/68DnmAJemmWQysvFsTZLfy87KLenmLABnG9qke
sOLD/vC7h5s5G9+vN4JMbmTYGBYp0VW5wWaC7Nw8cskgsmb7BZ+K7HsQbmtxh9Nu
BeQqdmQHZvLQ6wgY+0QTy/1KTUPwxLztyJttGjiRAoGAQEkpDgFSD3osz0vXbU9q
cqa+KIQviMy79pRD1BPwQvuSOlCNvIw/T7IxF+Y5ltWQZe7evAQ1XbpLZZTJqc/i
ovMTjUU78psjcZUim2kcQy9RJyIojbSDmrZq6gceDC2vS/yyuTrU2r93g6+XcbHq
xOGkOBQrx10Wzf6xxp1xJjECgYBfSk6t4nsdAVGYtap8jS2GDqUps5dkZrkmgCQj
AnoOygtWHLgXD+MokPOtfjupvSVKMNULgG8oGjoLGNDDcfoHjO7EH7KI5H3Epk8q
ifm1eElHUJJ/AMOQ9/nWG9VUCDvPA5qgVm6T/w6TtdcEWFXC0UZXZmPi0j17SR7F
AThS8QKBgQCCyPFJzwGIP99PcakQ38oFcoU8u/ahb0ghgJfSgK+K/ChXSyfbq5zt
jRkj6UWLa3plYX3po9h0Yp6f2IxnbOa3VK6fPkcSvBxhgK3RrugPerUJzFEPd3k4
GTqOBXtXO6N7zEMYxZxv0SgrV24LPfPz0aPObDeH6F0kuzXjanopIw== 
-----END RSA PRIVATE KEY-----

Generate Signature

Generate Signature adalah proses pembuatan tanda tangan digital dengan cara melakukan hashing menggunakan algoritma SHA-256, kemudian diverifikasi menggunakan private key. Pembuatan signature ini digunakan untuk layanan yang menggunakan flow Merchant -> Espay.

Langkah-Langkah Generate Signature

Berikut ini merupakan langkah-langkah untuk generate signature dengan private key:

  1. Buat Komponen StringToSign
  • Minify Request Body.
MinifyJson(RequestBody))
Contoh:
Format sebelum diminify
{
    "partnerReferenceNo": "2020102900000000000001",
    "accountNo": "1234567890",
    "bankCardToken": "",
    "balanceTypes": [
        "Balance"
    ]
}
Format setelah diminify
{"partnerReferenceNo":"2020102900000000000001","accountNo":"1234567890","bankCardToken":"","balanceTypes":["Balance"]}
  • Enkripsi request body yang telah di minify menggunakan SHA-256
(SHA-256(MinifyJson(RequestBody)))
Contoh:
Format sebelum enkripsi
{"partnerReferenceNo":"2020102900000000000001","accountNo":"1234567890","bankCardToken":"","balanceTypes":["Balance"]}
Format setelah enkripsi
adcaaaa3bcfe4ab96e204f6ee0cba7e8f14bff94720601c7278181641c04c9bb
  • Ubah request body yang telah di enkripsi SHA-256 menjadi HexEncode dan Lowercase
Penggunaan HexEncode bersifat opsional. Anda menggunakan SHA-256 jika return SHA-256 merupakan binary stream.
Menggunakan HexEncode
Lowercase(HexEncode(SHA-256(MinifyJson(RequestBody))))
Tidak menggunakan HexEncode
Lowercase((SHA-256(MinifyJson(RequestBody))))
Contoh:
Format sebelum HexEncode dan Lowercase
adcaaaa3bcfe4ab96e204f6ee0cba7e8f14bff94720601c7278181641c04c9bb
Format setelah Lowercase (tidak menggunakan HexEncode)
adcaaaa3bcfe4ab96e204f6ee0cba7e8f14bff94720601c7278181641c04c9bb
  1. Generate StringToSign

Untuk membuat StringToSign, gabungkan semua komponen menggunakan tanda titik dua “:”.

StringToSign

HTTPMethod+”:”+RelativeUrl+”:”+ Lowercase(HexEncode(SHA-256(MinifyJson(RequestBody))))+”:”+Timestamp

Contoh:
Format StringToSign
POST:/api/v1.0/balance-inquiry:adcaaaa3bcfe4ab96e204f6ee0cba7e8f14bff94720601c7278181641c04c9bb:2024-10-08T07:49:28+07:00
  1. Generate X-Signature dengan private key
X-SIGNATURE = base64Encode(SHA256withRSA(PrivateKey, StringToSign))
Contoh:
Format X-Signature
SZc6ZcSuHzsVOqxNUAwB5/VR9IJOpyEVPGMvwiSWf5K4Bc2XwqpKaD9fdkFe7F7DPOKaPLGkjduSYhAy6m8CLNCUEdRQPV8avdlCEppEFnNtvLDO/nc7ujRgjpg/rBmdOWk5ykr48Dm0wnv1WGRyCfVKfkWcp6+o+zY/UCYakrBSR7gx7g2D2LpXojimA4OAHEWAbq4+YXreAXTqS6RUCJgRraFGBoMfJmXZT9T1UTKZIv7DKPVNbOcF4zf2SdrBJagLnIFCztiZPEbvzjxD4hnrJ7RZuOnQ0lbwSN3LXTuVO1wm9+2TrHWfCzIvccZW+qSWUAgIa/li30baLxBbdg==
Contoh Kode


PHP - Generate Signature

$stringToSign = $http_method.':'.$endpoint_url.':'.strtolower((hash('sha256', json_encode(json_decode($_POST['bodyRequest']),JSON_UNESCAPED_SLASHES)))).':'.$timestamp;

openssl_sign($stringToSign, $signature, $privKey, 'sha256WithRSAEncryption'); 
            
Try It!

Anda bisa coba masukkan data sesuai dengan input yang telah disediakan. Setelah itu Anda submit dan lihat hasilnya!

Request
Value
Response

Validasi Signature

Validasi Signature adalah proses untuk memastikan keaslian tanda tangan digital dengan cara melakukan decode Base64 pada signature, kemudian memverifikasinya menggunakan public key. Validasi signature ini digunakan untuk layanan yang menggunakan flow Espay -> Merchant.

Langkah-Langkah Validasi Signature

Berikut ini merupakan langkah-langkah untuk validasi signature dengan public key:

  1. Decode X-Signature Header
Contoh:
Format X-Signature
SZc6ZcSuHzsVOqxNUAwB5/VR9IJOpyEVPGMvwiSWf5K4Bc2XwqpKaD9fdkFe7F7DPOKaPLGkjduSYhAy6m8CLNCUEdRQPV8avdlCEppEFnNtvLDO/nc7ujRgjpg/rBmdOWk5ykr48Dm0wnv1WGRyCfVKfkWcp6+o+zY/UCYakrBSR7gx7g2D2LpXojimA4OAHEWAbq4+YXreAXTqS6RUCJgRraFGBoMfJmXZT9T1UTKZIv7DKPVNbOcF4zf2SdrBJagLnIFCztiZPEbvzjxD4hnrJ7RZuOnQ0lbwSN3LXTuVO1wm9+2TrHWfCzIvccZW+qSWUAgIa/li30baLxBbdg==
Format X-Signature setelah Base64Decode
āC{[YRo1F_2vTorPTdY!#7F?ji<{X=^;w=S]5ю$7籷ix̸ؒPk<._ ,821r meۀC?羣`9To1\]UFv1<T8,]`ݵFגG\^;:, Z;cH+nbWsx�g0n*+UuiqX\$-5~}eO
  1. Buat komponen StringToSign
  • Minify Request Body.
MinifyJson(RequestBody))
Contoh:
Format sebelum diminify
{
    "partnerReferenceNo": "2020102900000000000001",
    "accountNo": "1234567890",
    "bankCardToken": "",
    "balanceTypes": [
        "Balance"
    ]
}
Format setelah diminify
{"partnerReferenceNo":"2020102900000000000001","accountNo":"1234567890","bankCardToken":"","balanceTypes":["Balance"]}
  • Enkripsi request body yang telah di minify menggunakan SHA-256
(SHA-256(MinifyJson(RequestBody)))
Contoh:
Format sebelum enkripsi
{"partnerReferenceNo":"2020102900000000000001","accountNo":"1234567890","bankCardToken":"","balanceTypes":["Balance"]}
Format setelah enkripsi
adcaaaa3bcfe4ab96e204f6ee0cba7e8f14bff94720601c7278181641c04c9bb
  • Ubah Request Body yang telah dienkripsi SHA-256 menjadi HexEncode dan Lowercase.
Penggunaan HexEncode bersifat opsional. Anda menggunakan SHA-256 jika return SHA-256 merupakan binary stream.
Menggunakan HexEncode
Lowercase(HexEncode(SHA-256(MinifyJson(RequestBody))))
Tidak menggunakan HexEncode
Lowercase((SHA-256(MinifyJson(RequestBody))))
Contoh:
Format sebelum HexEncode dan Lowercase
adcaaaa3bcfe4ab96e204f6ee0cba7e8f14bff94720601c7278181641c04c9bb
Format setelah Lowercase (tidak menggunakan HexEncode)
adcaaaa3bcfe4ab96e204f6ee0cba7e8f14bff94720601c7278181641c04c9bb
  1. Generate StringToSign

Untuk membuat StringToSign, gabungkan semua komponen menggunakan tanda titik dua “:”.

StringToSign

HTTPMethod+”:”+RelativeUrl+”:”+ Lowercase(HexEncode(SHA-256(MinifyJson(RequestBody))))+”:”+Timestamp

Contoh:
Format StringToSign
POST:/api/v1.0/balance-inquiry:adcaaaa3bcfe4ab96e204f6ee0cba7e8f14bff94720601c7278181641c04c9bb:2024-10-08T07:49:28+07:00
  1. Generate X-Signature dengan public key
X-SIGNATURE =
Base64Decode(X-SIGNATURE) = SHA256withRSA(PublicKey, StringToSign)
Contoh:
Format validasi signature
1
Contoh Kode


PHP - Signature Validation

// Decode X-Signature
$requestSignature = base64_decode($xSignature);

// String to Sign
$stringToSign = $http_method.':'.$endpoint_url.':'.strtolower((hash('sha256', json_encode(json_decode($_POST['bodyRequest']),JSON_UNESCAPED_SLASHES)))).':'.$timestamp;

// Signature validation
$signVerify = openssl_verify($stringToSign, $requestSignature, $publicKey, 'sha256WithRSAEncryption');    
            
Try It!

Anda bisa coba masukkan data sesuai dengan input yang telah disediakan. Setelah itu Anda submit dan lihat hasilnya!

Request
Value
Request

FAQ

Asymmetric signature bekerja melalui dua proses:

  1. Generate signature:
    proses pembuatan tanda tangan digital menggunakan private key saat request dikirim dari Merchant ke Espay.
  2. Validasi signature:
    proses verifikasi tanda tangan digital menggunakan public key saat menerima request dari Espay ke Merchant.
Penggunaan signature ditentukan oleh arah flow permintaan.
  • Generate signature digunakan pada flow Merchant → Espay.
  • Validasi signature digunakan pada flow Espay → Merchant.
Pastikan mengikuti flow pada masing-masing service.
Private key dan public key merupakan pasangan kunci dalam mekanisme RSA yang digunakan untuk proses penandatanganan dan verifikasi signature. Anda dapat membuat pasangan key tersebut menggunakan OpenSSL dengan format PKCS#1.
Lihat cara pembuatan public key dan private key dengan OpenSSL di sini.
Anda hanya perlu generate public dan private key sendiri saat akan masuk ke production. Untuk kebutuhan sandbox, Anda dapat menggunakan contoh key yang tersedia di dokumentasi Espay.
Lihat contoh private key dan public key di sini.

Catatan:
Contoh key hanya digunakan untuk keperluan sandbox dan tidak boleh digunakan di production.
Error “Unauthorized. Invalid Signature” terjadi karena value X-SIGNATURE yang Anda kirim tidak sesuai dengan spesifikasi SNAP Espay atau tidak cocok dengan permintaan yang diterima sistem.

Silakan periksa kembali hal-hal berikut:

  • Format StringToSign sudah sesuai
  • Request body sudah di-minify
  • Hash body menggunakan lowercase
  • Relative URL sesuai dengan endpoint
  • Timestamp di header sama dengan timestamp di StringToSign
  • Private key yang digunakan sudah sesuai

Gunakan Signature Generator Espay untuk memastikan signature yang dikirim sudah sesuai. Jika signature sudah sesuai namun permintaan masih ditolak, silakan hubungi tim support Espay.

Scroll to Top