ff1-js
Version:
FF1 (Format-Preserving Encryption) implementation in JavaScript/TypeScript
282 lines (200 loc) โข 7.69 kB
Markdown
# ff1-js
A pure JavaScript/TypeScript implementation of FF1 (Format-Preserving Encryption) based on the NIST SP 800-38G specification. This library provides secure format-preserving encryption that maintains the format and length of your data while ensuring strong cryptographic protection.
## ๐ Features
- **NIST Compliant**: Implements FF1 according to NIST SP 800-38G specification
- **Format Preserving**: Maintains the format and length of your data
- **Multiple Alphabets**: Support for numeric, alphanumeric, hexadecimal, and custom alphabets
- **TypeScript Support**: Full TypeScript definitions included
- **Zero Dependencies**: Pure JavaScript implementation with no external dependencies
- **Cross-Platform**: Works in Node.js and modern browsers
- **Comprehensive Testing**: 100% test coverage with extensive test suite
## ๐ฆ Installation
```bash
npm install ff1-js
```
## ๐ฏ Quick Start
### Basic Usage
```javascript
import { FF1, Alphabets } from 'ff1-js';
// Create an FF1 instance for alphanumeric encryption
const ff1 = new FF1(
'your-32-byte-key-here', // Key (16, 24, or 32 bytes)
'your-tweak-value', // Tweak
62, // Radix (base)
Alphabets.ALPHANUMERIC // Alphabet
);
// Encrypt
const encrypted = ff1.encrypt('Hello123');
console.log(encrypted); // Output: "K0d8I, J7vaK!"
// Decrypt
const decrypted = ff1.decrypt(encrypted);
console.log(decrypted); // Output: "Hello123"
```
### Using Helper Functions
```javascript
import { createNumericFF1, createAlphanumericFF1 } from 'ff1-js';
// For numeric data (0-9)
const numericFF1 = createNumericFF1('your-key', 'your-tweak');
const encrypted = numericFF1.encrypt('123456');
console.log(encrypted); // Output: "789012" (same length, numeric only)
// For alphanumeric data (0-9, a-z, A-Z)
const alphanumericFF1 = createAlphanumericFF1('your-key', 'your-tweak');
const encrypted = alphanumericFF1.encrypt('ABC123');
console.log(encrypted); // Output: "XyZ789" (same length, alphanumeric)
```
## ๐ API Reference
### FF1 Class
#### Constructor
```typescript
new FF1(
key: Buffer | string,
tweak: Buffer | string,
radix: number,
alphabet: string,
minLength?: number,
maxLength?: number
)
```
**Parameters:**
- `key`: Encryption key (16, 24, or 32 bytes)
- `tweak`: Tweak value (0 to 2^104 bytes)
- `radix`: Base of the alphabet (2-256)
- `alphabet`: String containing all valid characters
- `minLength`: Minimum input length (default: 2)
- `maxLength`: Maximum input length (default: 100)
#### Methods
##### `encrypt(input: string, tweak?: Buffer | string): string`
Encrypts a string while preserving its format.
##### `decrypt(input: string, tweak?: Buffer | string): string`
Decrypts a string while preserving its format.
##### `getConfig(): FF1Config`
Returns the current configuration.
### Predefined Alphabets
```javascript
import { Alphabets } from 'ff1-js';
Alphabets.NUMERIC // "0123456789" (radix: 10)
Alphabets.LOWERCASE // "abcdefghijklmnopqrstuvwxyz" (radix: 26)
Alphabets.UPPERCASE // "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (radix: 26)
Alphabets.ALPHANUMERIC // "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" (radix: 62)
Alphabets.HEXADECIMAL // "0123456789abcdef" (radix: 16)
Alphabets.BASE64 // "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" (radix: 64)
```
### Helper Functions
#### `createFF1(key, tweak, alphabet?, minLength?, maxLength?)`
Creates an FF1 instance with a custom alphabet.
#### `createNumericFF1(key, tweak, minLength?, maxLength?)`
Creates an FF1 instance for numeric data (0-9).
#### `createAlphanumericFF1(key, tweak, minLength?, maxLength?)`
Creates an FF1 instance for alphanumeric data (0-9, a-z, A-Z).
## ๐ง Usage Examples
### Credit Card Number Encryption
```javascript
import { createNumericFF1 } from 'ff1-js';
const ff1 = createNumericFF1('your-secret-key-32-bytes', 'card-tweak');
// Encrypt credit card number
const cardNumber = '1234567890123456';
const encrypted = ff1.encrypt(cardNumber);
console.log(encrypted); // "9876543210987654" (same length, numeric)
// Decrypt
const decrypted = ff1.decrypt(encrypted);
console.log(decrypted); // "1234567890123456"
```
### Social Security Number Encryption
```javascript
import { createNumericFF1 } from 'ff1-js';
const ff1 = createNumericFF1('your-secret-key-32-bytes', 'ssn-tweak');
const ssn = '123456789';
const encrypted = ff1.encrypt(ssn);
console.log(encrypted); // "987654321" (same length, numeric)
```
### Custom Alphabet
```javascript
import { FF1 } from 'ff1-js';
// Custom alphabet for phone numbers (digits + dash)
const phoneAlphabet = '0123456789-';
const ff1 = new FF1('your-key', 'your-tweak', 11, phoneAlphabet);
const phone = '555-1234';
const encrypted = ff1.encrypt(phone);
console.log(encrypted); // "123-5678" (same format, same length)
```
### Hexadecimal Data
```javascript
import { FF1, Alphabets } from 'ff1-js';
const ff1 = new FF1('your-key', 'your-tweak', 16, Alphabets.HEXADECIMAL);
const hexData = 'abcdef123456';
const encrypted = ff1.encrypt(hexData);
console.log(encrypted); // "123456abcdef" (same length, hexadecimal)
```
## ๐ Security Considerations
### Key Management
- Use cryptographically secure random keys
- Store keys securely (environment variables, key management systems)
- Rotate keys regularly
- Never hardcode keys in your source code
### Tweak Usage
- Use unique tweaks for different data types
- Tweak should be deterministic for the same data type
- Consider using a hash of the data type as tweak
### Example Secure Setup
```javascript
import { createAlphanumericFF1 } from 'ff1-js';
import crypto from 'crypto';
// Generate secure key
const key = crypto.randomBytes(32);
// Create tweak from data type
const dataType = 'user-id';
const tweak = crypto.createHash('sha256').update(dataType).digest();
const ff1 = createAlphanumericFF1(key, tweak);
// Use for user ID encryption
const userId = 'user123';
const encrypted = ff1.encrypt(userId);
```
## ๐งช Testing
Run the test suite:
```bash
npm test
```
Run with coverage:
```bash
npm run test:coverage
```
## ๐ฆ Building
Build the library:
```bash
npm run build
```
This creates:
- `dist/cjs/` - CommonJS build
- `dist/esm/` - ES Module build
- `dist/umd/` - UMD build for browsers
- `dist/types/` - TypeScript definitions
## ๐ Browser Usage
For browser usage, include the UMD build:
```html
<script src="dist/umd/ff1.js"></script>
<script>
const ff1 = new FF1.FF1('your-key', 'your-tweak', 62, FF1.Alphabets.ALPHANUMERIC);
const encrypted = ff1.encrypt('Hello123');
</script>
```
## ๐ Requirements
- Node.js >= 18.0.0
- TypeScript >= 5.0.0 (for development)
## ๐ค Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests for new functionality
5. Ensure all tests pass
6. Submit a pull request
## ๐ License
MIT License - see [LICENSE](LICENSE) file for details.
## ๐ References
- [NIST SP 800-38G](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38Gr1-draft.pdf)
- [Format-Preserving Encryption](https://en.wikipedia.org/wiki/Format-preserving_encryption)
## ๐ Support
For support and questions:
- Email: kasfi.tamiya@ifabula.com
- GitLab Issues: [Create an issue](https://gitlab.com/kasfi.tamiya/ff1-js/issues)
---
**Made with โค๏ธ by PT Ifabula Digital Kreasi**