A secure, modular JavaScript/TypeScript solution for retrieving, displaying, and exporting payment billing address and card details with AES-256-GCM encryption and PBKDF2 key derivation.
- AES-256-GCM Authenticated Encryption: Industry-standard AEAD cipher
- PBKDF2 Key Derivation: 100,000 iterations with SHA-256
- Web Crypto API: Uses native browser encryption where possible
- Node.js Crypto Module: Server-side encryption/decryption
- Zero Storage of Plaintext: Sensitive data only in memory
- HTTPS Enforced: In production environments
- CORS Protection: Whitelist trusted origins
- Security Headers: Helmet.js middleware
- Rate Limiting Ready: Template for implementation
pba-csv-script/
βββ backend/
β βββ server.js # Express API server
βββ frontend/
β βββ vanilla/
β β βββ index.html # HTML UI
β β βββ pba-script.js # Frontend logic
β β βββ styles.css # Stylesheet
β βββ react/ # React component (coming soon)
βββ encryption/
β βββ encryption.js # Encryption module (AES-256-GCM + PBKDF2)
βββ package.json # Dependencies
βββ README.md # This file
- Node.js >= 16.0.0
- npm >= 8.0.0
-
Clone/Extract the project
cd pba-csv-script -
Install dependencies
npm install
-
Create environment file (optional)
cat > .env << EOF PORT=3000 NODE_ENV=development FRONTEND_URL=http://localhost:3000 EOF
npm startThe server runs on http://localhost:3000
Available Endpoints:
GET /api/health- Health checkGET /api/billing/address- Retrieve billing address dataPOST /api/billing/export-encrypted-csv- Encrypt and export CSVPOST /api/billing/decrypt-csv- Decrypt CSV file
- Open
frontend/vanilla/index.htmlin a modern browser - The UI automatically loads billing data from the backend
- Copy fields individually or export as encrypted CSV
Features:
- β Copy individual fields to clipboard
- β Copy all visible fields at once
- β Select fields for export
- β Password-protected CSV export
- β AES-256-GCM encryption
- β Decrypt previously exported files
npm run devRequires nodemon (installed via npm install)
- Minimum 8 characters recommended
- Use strong, randomly generated passwords
- Store encryption passwords securely (not in code)
Always use HTTPS in production:
// In production, enforce HTTPS
app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
res.redirect(`https://${req.header('host')}${req.url}`);
}
next();
});Never commit sensitive data:
# .gitignore
.env
.env.local
node_modules/Update allowed origins in backend/server.js:
const allowedOrigins = [
'https://your-payment-portal.com',
'https://card-issuer.com'
];Implement rate limiting to prevent brute force attacks:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use('/api/', limiter);Always validate and sanitize user input:
// Example validation
if (!fields || !Array.isArray(fields) || fields.length === 0) {
return res.status(400).json({ error: 'Invalid fields' });
}Log security-relevant events:
console.log({
timestamp: new Date(),
event: 'export',
fields: selectedFields,
ip: req.ip
});Current PBKDF2 settings (100,000 iterations) provide strong security. Increase iterations for higher security (at cost of performance):
const ENCRYPTION_CONFIG = {
pbkdf2Iterations: 300000, // Increase for higher security
// ... other config
};- Key Size: 256 bits (32 bytes)
- Nonce/IV Size: 128 bits (16 bytes)
- Tag Size: 128 bits (16 bytes)
- Mode: Galois/Counter Mode (GCM) - provides authenticated encryption
- Hash Algorithm: SHA-256
- Iterations: 100,000
- Salt Size: 256 bits (32 bytes)
- Derived Key Size: 256 bits (32 bytes)
User Password
β
PBKDF2 (100,000 iterations, SHA-256)
β
256-bit Key
β
AES-256-GCM Encryption (with random IV)
β
Ciphertext + IV + Auth Tag
β
Base64 Encoded JSON
β
Download as file
curl -X GET http://localhost:3000/api/billing/addressResponse:
{
"success": true,
"data": {
"card_number": "4532-1111-2222-3333",
"expiry_date": "12/25",
"cvv": "***",
"address": {
"apt_unit": "Suite 100",
"address_line_1": "123 Main Street",
"city": "San Francisco",
"state_province": "CA",
"country": "United States",
"postal_code": "94105"
}
}
}curl -X POST http://localhost:3000/api/billing/export-encrypted-csv \
-H "Content-Type: application/json" \
-d '{
"password": "SecurePassword123",
"fields": ["address_line_1", "city", "state_province", "postal_code"]
}'Response:
{
"success": true,
"encrypted": "{\"salt\":\"...\",\"iv\":\"...\",\"tag\":\"...\",\"ciphertext\":\"...\"}",
"metadata": {
"algorithm": "aes-256-gcm",
"iterations": 100000
}
}curl -X POST http://localhost:3000/api/billing/decrypt-csv \
-H "Content-Type: application/json" \
-d '{
"password": "SecurePassword123",
"payload": "{...encrypted payload...}"
}'npm test- Copy Field: Click "Copy" on any field, verify clipboard content
- Copy All: Click "Copy All Visible", check all fields copied
- Export CSV:
- Select fields
- Enter password
- Click "Export Encrypted CSV"
- Verify download
- Decrypt:
- Upload encrypted file
- Enter password
- Verify CSV is readable
-
Include as Module
<link rel="stylesheet" href="pba/frontend/vanilla/styles.css"> <script src="pba/frontend/vanilla/pba-script.js"></script>
-
Configure API Base URL
// In pba-script.js const API_BASE_URL = 'https://your-backend.com/api';
-
Update CORS in Backend
const allowedOrigins = [ 'https://payment-portal.example.com' ];
import PBAComponent from './components/PBAComponent';
export default function PaymentPage() {
return <PBAComponent apiUrl="https://your-api.com" />;
}- Node.js 16+ on server
- HTTPS certificate (Let's Encrypt recommended)
- Environment variables configured
# .env.production
PORT=443
NODE_ENV=production
FRONTEND_URL=https://payment-portal.example.comFROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]Build and run:
docker build -t pba-csv-script .
docker run -p 3000:3000 -e NODE_ENV=production pba-csv-scriptProblem: "Access to XMLHttpRequest blocked by CORS policy"
Solution: Update allowedOrigins in backend/server.js
Problem: "Decryption failed - invalid password or corrupted data"
Causes:
- Wrong password entered
- Corrupted JSON payload
- Mismatched encryption/decryption versions
Solution: Verify password and payload integrity
Problem: Copy button doesn't work
Causes:
- HTTPS not used (required for Clipboard API)
- Browser doesn't support Clipboard API
Solution: Fallback to older approach in pba-script.js
MIT License - See LICENSE file
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Submit a pull request
For issues or questions:
- Check existing issues
- Create new issue with:
- Browser/Node.js version
- Error message
- Steps to reproduce
- React component version
- Vue.js component version
- Rate limiting middleware
- JWT authentication
- Database integration
- Audit logging system
- Admin dashboard
- Multi-user support
- Argon2 key derivation option
This script handles sensitive payment data. Ensure compliance with:
- PCI-DSS (Payment Card Industry Data Security Standard)
- GDPR (General Data Protection Regulation)
- CCPA (California Consumer Privacy Act)
- Your local data protection regulations
Always perform security audits before production deployment.
This project is released under a Dual License Model:
β Free for research and non-commercial use - Educational projects, personal research, non-profit organizations
πΌ Commercial use requires explicit permission - Contact the project owner for commercial licensing terms
For full license details, see LICENSE.md.
Last Updated: December 2025
Version: 1.0.0