diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4232a6f..2bef8e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,12 +17,12 @@ jobs: node-version: [12.x, 14.x, 16.x, 18.x, 19,x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - cache: 'npm' + cache: 'npm' - name: Install dependencies run: npm install - name: Run tests @@ -40,9 +40,9 @@ jobs: needs: test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: sudo apt-get install -y oathtool - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v4 with: node-version: 16 registry-url: https://registry.npmjs.org/ diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 3f165c1..a653bd1 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -20,9 +20,9 @@ jobs: # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'npm' diff --git a/lib/utils/razorpay-utils.js b/lib/utils/razorpay-utils.js index 6ba6468..1dbfc93 100644 --- a/lib/utils/razorpay-utils.js +++ b/lib/utils/razorpay-utils.js @@ -151,26 +151,23 @@ function generateOnboardingSignature(params={}, secret){ function encrypt(dataToEncrypt, secret) { try { - // Use first 16 bytes of secret as key const keyBytes = Buffer.from(secret.slice(0, 16), 'utf8'); - - // Use first 12 bytes of key as IV - const iv = Buffer.alloc(12); - keyBytes.copy(iv, 0, 0, 12); - // Create cipher with AES-GCM + // Generate a fresh random 12-byte nonce per call (fixes AES-GCM nonce reuse). + // A static IV derived from the key allows keystream recovery and tag forgery + // (NIST SP 800-38D ยง8.3 Forbidden Attack) using only two captured ciphertexts. + const iv = crypto.randomBytes(12); + const cipher = crypto.createCipheriv('aes-128-gcm', keyBytes, iv); - - // Encrypt the data + let encryptedData = cipher.update(dataToEncrypt, 'utf8'); encryptedData = Buffer.concat([encryptedData, cipher.final()]); - - // Get authentication tag and append to encrypted data + const authTag = cipher.getAuthTag(); - const finalData = Buffer.concat([encryptedData, authTag]); - - // Convert to hex string - return finalData.toString('hex'); + + // Output format: iv (12 bytes) || ciphertext || tag (16 bytes), hex-encoded. + // Receiver must read the first 24 hex chars as the IV before decrypting. + return Buffer.concat([iv, encryptedData, authTag]).toString('hex'); } catch (err) { throw new Error(`Encryption failed: ${err.message}`); }