Signature Asymmetric

Signature Asymmetric 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 Signature Asymmetric

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/qr/qr-mpm-generate
  • Relative URL:
    /api/v1.0/qr/qr-mpm-generate
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

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 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 dengan Private Key

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": "DIGORDER000001",
  "merchantId": "SGWDIGALLERY",
  "subMerchantId": "fd322d0f036c8443d6904973c1a329bd", 
  "amount": {
    "value": "10000.00",
    "currency": "IDR"
  },
  "urlParam": {
    "url": "https://yourthankyoupage.com",
    "type": "PAY_RETURN",
    "isDeeplink": "N"
  },
  "validUpTo": "2023-12-23T07:44:11+07:00",
  "pointOfInitiation": "Website",
  "payOptionDetails": {
    "payMethod": "014",
    "payOption": "BCAATM",
    "transAmount": {
      "value": "10000.00",
      "currency": "IDR"
    },
    "feeAmount": {
      "value": "10000.00",
      "currency": "IDR"
    }
  },
  "additionalInfo": {
    "payType": "REDIRECT",
    "userId": "425666",
    "userName": "Agung Setiadi Putra",
    "userEmail": "agung@agung.com",
    "userPhone": "082231838297",
    "buyerId": "12345678"
  }
}

Format setelah diminify
{"partnerReferenceNo":"DIGORDER000001","merchantId":"SGWDIGALLERY","subMerchantId":"fd322d0f036c8443d6904973c1a329bd","amount":{"value":"10000.00","currency":"IDR"},"urlParam":{"url":"https://yourthankyoupage.com","type":"PAY_RETURN","isDeeplink":"N"},"validUpTo":"2023-12-23T07:44:11+07:00","pointOfInitiation":"Website","payOptionDetails":{"payMethod":"014","payOption":"BCAATM","transAmount":{"value":"10000.00","currency":"IDR"},"feeAmount":{"value":"10000.00","currency":"IDR"}},"additionalInfo":{"payType":"REDIRECT","userId":"425666","userName":"Agung
Setiadi Putra","userEmail":"agung@agung.com","userPhone":"082231838297","buyerId":"12345678"}}
  • Enkripsi request body yang telah di minify menggunakan SHA-256
(SHA-256(MinifyJson(RequestBody)))
Contoh:
Format sebelum enkripsi
{"partnerReferenceNo":"DIGORDER000001","merchantId":"SGWDIGALLERY","subMerchantId":"fd322d0f036c8443d6904973c1a329bd","amount":{"value":"10000.00","currency":"IDR"},"urlParam":{"url":"https://yourthankyoupage.com","type":"PAY_RETURN","isDeeplink":"N"},"validUpTo":"2023-12-23T07:44:11+07:00","pointOfInitiation":"Website","payOptionDetails":{"payMethod":"014","payOption":"BCAATM","transAmount":{"value":"10000.00","currency":"IDR"},"feeAmount":{"value":"10000.00","currency":"IDR"}},"additionalInfo":{"payType":"REDIRECT","userId":"425666","userName":"Agung
Setiadi Putra","userEmail":"agung@agung.com","userPhone":"082231838297","buyerId":"12345678"}}
Format setelah enkripsi
f6bbc08be6997d4bd02af5254e3f934f9ed908fb7724d2e8cf98b178158a2b7a
  • 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
f6bbc08be6997d4bd02af5254e3f934f9ed908fb7724d2e8cf98b178158a2b7a
Format setelah Lowercase (tidak menggunakan HexEncode)
f6bbc08be6997d4bd02af5254e3f934f9ed908fb7724d2e8cf98b178158a2b7a

  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:/apimerchant/v1.0/debit/payment-host-to-host:f6bbc08be6997d4bd02af5254e3f934f9ed908fb7724d2e8cf98b178158a2b7a:2024-03-14T07:49:28+07:00

  1. Generate X-Signature dengan private key

X-SIGNATURE = base64Encode(SHA256withRSA(PrivateKey, StringToSign))
Contoh:
Format X-Signature
D/QV3mN8i19xZRTkOW5sdn5XtrXoT8EmepDRzaGHheT+qnnzrZlEKCBic6M5sQyj6Hp8jFSY4PCsMm7lJQFRLiGPdYf/rDPFsa/ai1MnoUoMKUFSmQHUmjAAhbQjkdNWKjoSG+xTTmyEzsBz6/P6ijWMBDTZWPIb3/qaN6oxcnhw2RLOCyCZlXwBeP6RMc3Gz1wilRGQ5jqeebQVGgUJjqAGLM/cVIjG0fXmQAmsG0g3XA7e63qW0M6am8zXHPtumRF5X4JN0CSRcV9QjvLvH21vcnYhuixebzr5dnnoroXL/aE/ptfrb79Ou0dwqRsQBCqZhwFssSFRPDhzqsZWIw==

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 dengan Public Key

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

  1. Decode X-Signature Header
Contoh:
Format X-Signature
rgfRxIG62kOVexmBsrHnl87aW1lS+JtvMUa9pF8yhHb+m1Rv63LzFFC50FTzZMhZIarrI4Tff4Q3RhvMP5nLEMwOamnVPHtYnIY9Xjvudz3AitjUU1010dGOn7vt8ojY8K4kN+extwGuxmmPePbYksy4UGs8Ll8SfwksOKgygzFy+AttZY2s2duAt8tD/D+q576j62CyOVRvMVysXVWCRnYxPBa8D9hUj+M47yxdYN21RteSkQjB90fBXAVeBeikOzosDflaO2PH80grbmKSV5hzF9Z48ABnDxkwFG7PG8cqK1XRde34aXFYsI+sXCQDLZ6Y3TWBA/iWfn1lx08T3g==
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
{
  "partnerServiceId": " Espay",
  "customerNo": "SGWDIGALLERY",
  "virtualAccountNo": "DIGORDER000002",
  "trxDateInit": "2024-06-17T21:45:46+0700",
  "inquiryRequestId": "710c1836-eddf-49d1-8234-f11e93750fdd"
}
Format setelah diminify
{"partnerServiceId":" Espay","customerNo":"SGWDIGALLERY","virtualAccountNo":"DIGORDER000002","trxDateInit":"2024-06-17T21:45:46+0700","inquiryRequestId":"710c1836-eddf-49d1-8234-f11e93750fdd"}
  • Enkripsi request body yang telah di minify menggunakan SHA-256
(SHA-256(MinifyJson(RequestBody)))
Contoh:
Format sebelum enkripsi
{"partnerServiceId":" Espay","customerNo":"SGWDIGALLERY","virtualAccountNo":"DIGORDER000002","trxDateInit":"2024-06-17T21:45:46+0700","inquiryRequestId":"710c1836-eddf-49d1-8234-f11e93750fdd"}
Format setelah enkripsi
33578ff224ac535c2be314623a3ba420f6b965f4570ec9bbb8af17ac8dbd6468
  • 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
33578ff224ac535c2be314623a3ba420f6b965f4570ec9bbb8af17ac8dbd6468
Format setelah Lowercase (tidak menggunakan HexEncode)
33578ff224ac535c2be314623a3ba420f6b965f4570ec9bbb8af17ac8dbd6468
  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/webhooks/epsay/v1.0/transfer-va/inquiry.php:33578ff224ac535c2be314623a3ba420f6b965f4570ec9bbb8af17ac8dbd6468:2024-06-17T21:45:46+0700
  1. Generate X-Signature dengan public key
X-SIGNATURE =
Base64Decode(X-SIGNATURE) = SHA256withRSA(PublicKey, StringToSign)
Contoh:
Format validasi signature
1

Try It!

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

Request

Value

Response



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');      
            



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');

          
Scroll to Top