NAGAD API v3.3

Developer Portal & Reference

Test Crypto
Security & Cryptography Specification

RSA Encryption & Digital Signature

নগদ পেমেন্ট গেটওয়ের সবচেয়ে গুরুত্বপূর্ণ অংশ হলো RSA ক্রিপ্টোগ্রাফি। এখানে প্রতিটি রিকোয়েস্ট Nagad Public Key দ্বারা এনক্রিপ্ট ও মার্চেন্ট Private Key দ্বারা সাইন করা হয়। নিচে প্রতিটা স্টেপ পানির মতো সহজ করে ব্যাখ্যা করা হলো।

1 The 4 Keys Used in Nagad Gateway

Merchant Key Pair (You Generate)
  • Merchant Private Key (MS Private Key) Saved securely on your server (.env or config). Used to generate digital signatures for outgoing requests and to decrypt incoming sensitive response data.
  • Merchant Public Key (MS Public Key) Uploaded to the Nagad Merchant Portal. Nagad uses this key to encrypt sensitive response data and verify merchant digital signatures.
Nagad Gateway Key Pair (Provided by Nagad)
  • Nagad Gateway Public Key (NPG Public Key) Downloaded from Nagad Merchant Portal. Used by your server to encrypt sensitive request data before sending to Nagad and to verify Nagad response signatures.
  • Nagad Gateway Private Key (NPG Private Key) Stored confidentially inside Nagad's secure HSM servers. Nagad uses this to decrypt incoming merchant requests and sign API responses.

Cryptographic Algorithm Standards:

Encryption Algorithm: RSA (PKCS#1 v1.5 Padding)
Signature Algorithm: SHA1withRSA
Payload Encoding: Base64 (RFC 4648)

2 How to Generate Merchant RSA Keys (OpenSSL)

You can generate a valid 2048-bit RSA key pair on Windows (PowerShell/Git Bash), Linux, or Mac using standard OpenSSL commands:

Terminal / Bash
# Step 1: Generate 2048-bit RSA Private Key
openssl genrsa -out merchant_private.pem 2048

# Step 2: Extract Public Key in PKCS#8 PEM format (Upload this to Nagad Portal)
openssl rsa -in merchant_private.pem -pubout -out merchant_public.pem
Important Formatting Note: Nagad expects clean PEM formatted keys without line feed issues or carriage returns. Ensure you maintain the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers.

3 Request Preparation Pipeline (Encryption & Signing)

প্রতিটি রিকোয়েস্ট পাঠানোর আগে নিচের ৩টি ক্রিপ্টো স্টেপ সম্পন্ন করতে হয়:

1 Prepare Plain Sensitive JSON Payload JSON String

মার্চেন্ট আইডি, ডেট-টাইম (yyyyMMddHHmmss), অর্ডার আইডি এবং র‍্যান্ডম চ্যালেঞ্জ কি দিয়ে একটা প্লেইন JSON স্ট্রিং তৈরি করুন:

{"merchantId":"687450000031324","datetime":"20260909120000","orderId":"ORD123456","challenge":"695EF3869547B6C07F5D56399935FB72D21737EA"}
2 Encrypt Sensitive JSON & Base64 Encode -> sensitiveData Nagad Public Key + PKCS1Padding

এই প্লেইন JSON স্ট্রিং-টিকে Nagad Gateway Public Key এবং PKCS1Padding দিয়ে এনক্রিপ্ট করে Base64 স্ট্রিং-এ কনভার্ট করুন।

sensitiveData = Base64_Encode( RSA_Encrypt(plainSensitiveJson, Nagad_Public_Key, PKCS1Padding) )
3 Sign Sensitive JSON & Base64 Encode -> signature Merchant Private Key + SHA1withRSA

একই প্লেইন JSON স্ট্রিং-টিকে আপনার Merchant Private Key দিয়ে SHA1withRSA অ্যালগরিদমে সাইন করে Base64 স্ট্রিং-এ কনভার্ট করুন।

signature = Base64_Encode( SHA1withRSA_Sign(plainSensitiveJson, Merchant_Private_Key) )

4 Response Handling Pipeline (Decryption & Verification)

Nagad থেকে রেসপন্স আসলে রেসপন্সটি ডিক্রিপ্ট ও সিগনেচার ভেরিফাই করতে হয়:

1 Base64 Decode & Decrypt with Merchant Private Key RSA Decrypt
plainDecryptedData = RSA_Decrypt( Base64_Decode(response.sensitiveData), Merchant_Private_Key, PKCS1Padding )

ডিক্রিপ্ট করার পর প্লেইন JSON পাবেন, যাতে থাকবে paymentReferenceId এবং challenge (অথবা random)।

2 Verify Signature with Nagad Public Key SHA1withRSA Verify
isValid = SHA1withRSA_Verify( plainDecryptedData, Base64_Decode(response.signature), Nagad_Public_Key )

সিগনেচার ভেরিফাই সফল হলে রেসপন্সটি নির্ভুল হিসেবে নিশ্চিত হবে।

5 Crypto Implementation Code Snippets

const crypto = require('crypto');

/**
 * Nagad Cryptography Utility for Node.js
 */
class NagadCrypto {
  /**
   * Encrypt plain JSON string with Nagad Public Key (PKCS1 Padding)
   */
  static encrypt(dataString, nagadPublicKeyPem) {
    const buffer = Buffer.from(dataString, 'utf8');
    const encrypted = crypto.publicEncrypt(
      {
        key: nagadPublicKeyPem,
        padding: crypto.constants.RSA_PKCS1_PADDING,
      },
      buffer
    );
    return encrypted.toString('base64');
  }

  /**
   * Generate SHA1withRSA Digital Signature with Merchant Private Key
   */
  static sign(dataString, merchantPrivateKeyPem) {
    const signer = crypto.createSign('RSA-SHA1');
    signer.update(dataString, 'utf8');
    signer.end();
    return signer.sign(merchantPrivateKeyPem, 'base64');
  }

  /**
   * Decrypt sensitive data with Merchant Private Key (PKCS1 Padding)
   */
  static decrypt(base64EncryptedData, merchantPrivateKeyPem) {
    const buffer = Buffer.from(base64EncryptedData, 'base64');
    const decrypted = crypto.privateDecrypt(
      {
        key: merchantPrivateKeyPem,
        padding: crypto.constants.RSA_PKCS1_PADDING,
      },
      buffer
    );
    return decrypted.toString('utf8');
  }

  /**
   * Verify Nagad Response Signature (SHA1withRSA)
   */
  static verify(dataString, base64Signature, nagadPublicKeyPem) {
    const verifier = crypto.createVerify('RSA-SHA1');
    verifier.update(dataString, 'utf8');
    verifier.end();
    return verifier.verify(nagadPublicKeyPem, base64Signature, 'base64');
  }
}

module.exports = NagadCrypto;