LogoLogo
  • Ứng dụng VinID
  • Giới thiệu chung
    • Dịch vụ thanh toán VinID Pay
    • Dịch vụ loyalty VinID Point
    • Quy trình tích hợp
  • Tài liệu tích hợp
    • Môi trường tích hợp
    • Quy tắc kết nối chung
      • Request Header
      • X-Key-Code
      • Signature - chữ kí điện tử
      • Ví dụ Request / Response
      • Extra Data
    • OneID SSO Integration (PKCE)
      • Auth endpoint
      • Token endpoint
      • Refresh token
      • Logout endpoint
      • Profile endpoint
      • OpenID Configuration
    • Tích hợp với VinID Pay
      • Thanh toán Merchant QR
      • Thanh toán Transaction QR
      • Thanh toán App to App
      • Thanh toán Web Payment
      • Thanh toán Linked Account
      • Dịch vụ chi hộ
      • Callback / IPN
      • Refund giao dịch
    • Tích hợp với VinID Loyalty
      • Dịch vụ lấy hạng thành viên trung thành
      • Dịch vụ VinID Giftcode
        • Deprecated APIs
      • Dịch vụ Topup VinID Point
        • Deprecated APIs
    • Tích hợp với VinID Voucher
      • Dịch vụ E-Voucher
    • Mã lỗi chung
  • Đối soát
    • Đối soát Ví điện tử VinID Pay
  • Khác
    • Thuật ngữ
    • Câu hỏi thường gặp
    • Ứng dụng quản lý
      • Merchant Mobile App
      • Merchant Website
    • Thông tin hỗ trợ
Powered by GitBook
On this page
  • Tạo chữ ký điện tử
  • Format chữ ký điện tử

Was this helpful?

Export as PDF
  1. Tài liệu tích hợp
  2. Quy tắc kết nối chung

Signature - chữ kí điện tử

Mô tả về chữ kí điện tử để xác thực dữ liệu.

PreviousX-Key-CodeNextVí dụ Request / Response

Last updated 4 years ago

Was this helpful?

VinID sử dụng chữ ký điện tử (signature) để xác thực dữ liệu đầu vào và ra trên mỗi HTTP Request.

Hệ thống VinID sử dụng thuật toán SHA256 RSA ( key size = 2048 bit) để tạo signature.

Tạo chữ ký điện tử

openssl genrsa -out RS256-2048-Private.rsa 2048
openssl rsa -in RS256-2048-Private.rsa -pubout > RS256-2048-Public.rsa
brew update
brew install openssl
echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile

openssl genrsa -out RS256-2048-Private.rsa 2048
openssl rsa -in RS256-2048-Private.rsa -pubout > RS256-2048-Public.rsa
  • Tải và cài đặt OpenSSL từ

  • Thêm đường dẫn vào biến môi trường PATH của Windows

openssl genrsa -out RS256-2048-Private.rsa 2048
openssl rsa -in RS256-2048-Private.rsa -pubout > RS256-2048-Public.rsa

Format chữ ký điện tử

  • PrivateKey: do merchant tự generate ra theo định dạng SHA256 RSA ( 2048 )

  • URL: Endpoint API

RawData = {url};{method};{X-Nonce};{X-Timestamp};{X-Key-Code};{body}
X-Signature = ​SHA256WithRSA(PrivateKey, RawData)
RawData = {url};{method};{X-Nonce};{X-Timestamp};{X-Key-Code};
X-Signature = ​SHA256WithRSA(PrivateKey, RawData)

Ví dụ:

url: '/merchant-integration/v1/qr/gen-transaction-qr'
method: 'POST'
X-Nonce: '00a81e60-2684-4cf9-878d-f37559213059'
X-Timestamp: 1570723375
X-Key-Code: 'b7bdf002-4948-44d2-99d1-99c8c81c3f47'
Body: {"callback_url":"https://webhook.site/17d9577f-70ca-4918-8388-1d6d53d8bc69","description":"Kiểm thử thanh toán","order_amount":10000,"order_currency":"VND","pos_code":"IPOS002","service_type":"PURCHASE","store_code":"ISTORE002"}
RawData: /merchant-integration/v1/qr/gen-transaction-qr;POST;00a81e60-2684-4cf9-878d-f37559213059;1570723375;b7bdf002-4948-44d2-99d1-99c8c81c3f47;{"callback_url":"https://webhook.site/17d9577f-70ca-4918-8388-1d6d53d8bc69","description":"Kiểm thử thanh toán","order_amount":10000,"order_currency":"VND","pos_code":"IPOS002","service_type":"PURCHASE","store_code":"ISTORE002"}
X-Signature: SHA256WithRSA(PrivateKey, RawData)
=> X-Signature: ERSt3cZoijwJf8QIZdcpHPygcDQJ+tA7l/2EVyJyhO8fwpp6mbrYWsyhyqDjD4zkhGwcXVJ7zJQUDWFpCPitG9GlmssEnkp57YK94/6GR54x6COzPqOlJjoQ4Lq6Fvw99QVmjiL+WjGWSOTUkusXh9dr871vCrjcYmyFSCZ9Ydfw6l4iv2evOnibUtalIkdsNM6evrVa7qW28Uno5t8fmz68QJeXd0dqL4lm2tsFAr9094jbWh/zlynqAW9MOIIYjXQC7XwEVKiBEmoZyTnSd8SLITLNIXvLCJjjVT5XYqZAMNIyoNYZKom8dUjLuirBBurcUpXuxlu01O8dU9qHdg==
url: '/merchant-integration/v2/qr/query/20200623T0017FB54CBB'
method: 'GET'
X-Nonce: '00a81e60-2684-4cf9-878d-f37559213059'
X-Timestamp: 1570723375
X-Key-Code: 'b7bdf002-4948-44d2-99d1-99c8c81c3f47'
RawData: /merchant-integration/v2/qr/query/20200623T0017FB54CBB;GET;00a81e60-2684-4cf9-878d-f37559213059;1570723375;b7bdf002-4948-44d2-99d1-99c8c81c3f47;
X-Signature: SHA256WithRSA(PrivateKey, RawData)
=> X-Signature: ERSt3cZoijwJf8QIZdcpHPygcDQJ+tA7l/2EVyJyhO8fwpp6mbrYWsyhyqDjD4zkhGwcXVJ7zJQUDWFpCPitG9GlmssEnkp57YK94/6GR54x6COzPqOlJjoQ4Lq6Fvw99QVmjiL+WjGWSOTUkusXh9dr871vCrjcYmyFSCZ9Ydfw6l4iv2evOnibUtalIkdsNM6evrVa7qW28Uno5t8fmz68QJeXd0dqL4lm2tsFAr9094jbWh/zlynqAW9MOIIYjXQC7XwEVKiBEmoZyTnSd8SLITLNIXvLCJjjVT5XYqZAMNIyoNYZKom8dUjLuirBBurcUpXuxlu01O8dU9qHdg==

Code mẫu tạo Signature

// GenerateSignature util to generate signature form Auth Claim of merchant
func GenerateSignature(claim *dtos.AuthClaims, privKey []byte) (string, error) {
    block, _ := pem.Decode(privKey)
    privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        fmt.Printf("Error ParsePKCS1PrivateKey: %v", err)
        return "", err
    }
    hash := generateHash(claim.URL, claim.Method, claim.Nonce, claim.Timestamp, claim.KeyCode, claim.Body)
    signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash[:])
    if err != nil {
        fmt.Printf("Error from signing: %s\n", err)
        return "", err
    }
    claim.Signature = base64.StdEncoding.EncodeToString(signature)
    return claim.Signature, nil
}
function generateSignature($url, $method, $nonce, $timestamp, $apiKey, $requestBody, $privateKey)
{
    $data = $url . ";" . $method . ";" . $nonce . ";" . $timestamp . ";" . $apiKey . ";" . $requestBody;
    $p = openssl_pkey_get_private($privateKey);
    if (!$p) {
        trigger_error("Invalid private key\n".$privateKey, E_USER_WARNING);
        throw new InvalidPrivateKeyException($privateKey);
    }
    $signSuccess = openssl_sign($data, $signature, $p, OPENSSL_ALGO_SHA256);
    $encodedSignature = base64_encode($signature);
    openssl_free_key($p);
    return $encodedSignature;
}
def generateSign():
    requestBody = json.dumps(params, default=lambda o:o.__dict__, ensure_ascii=False,separators=(',', ':'))
    data = url+";"+method+";"+nonce+";"+str(int(timestamp))+";"+keyCode+";"+requestBody
    f = open("/home/vid/Documents/leo/sb_private.pem", "r")
    pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read())
    sign = OpenSSL.crypto.sign(pkey, data, "sha256")
    encodedSign = base64.b64encode(sign)
    return encodedSign
import java.io.File;
import java.nio.file.Files;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

public class VinIDSignature {

    //The method that signs the data using the private key that is stored in keyFile path
    public String generateSign(String url, String method, String nonce, String timestamp, String keyCode, String requestBody, String keyFile) throws Exception {
        String body = requestBody == null || "".equals(requestBody) ? "" : requestBody;
        String data = url + ";" + method + ";" + nonce + ";" + timestamp + ";" + keyCode + ";" + body;
        java.security.Signature rsa = java.security.Signature.getInstance("SHA256withRSA");
        rsa.initSign(getPrivate(keyFile));
        rsa.update(data.getBytes());
        return new String(Base64.getEncoder().encode(rsa.sign()));
    }

    //Method to retrieve the Private Key from a file
    private PrivateKey getPrivate(String filename) throws Exception {
        byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(spec);
    }
}
using System.Text;
using System.IO;
using java.security.spec;
using java.security;
using System;
using System.Security.Cryptography;

namespace OneID
{
    class Security
    {
        public string sign(string url, string method, string nonce, string timestamp, string keycode, string requestBody, string keyfile)
        {
            string data = url + ";" + method + ";" + nonce + ";" + timestamp + ";" + keycode + ";" + requestBody;
            RSACryptoServiceProvider ras = PemKeyUtils.GetRSAProviderFromPemFile(keyfile);
            return System.Convert.ToBase64String(ras.SignData(Encoding.ASCII.GetBytes(data), CryptoConfig.MapNameToOID("SHA256")));
        }
    }
}
https://wiki.openssl.org/index.php/Binaries