JavaScript Blowfish Encryption Library
This library implements the Blowfish symmetric-key block cipher for JavaScript, supporting both browser and Node.js environments. Currently at version 1.0.4, the package provides basic encryption and decryption capabilities, including Electronic Codebook (ECB) and Cipher Block Chaining (CBC) modes. A key feature is its robust handling of UTF-8 strings and automatic zero-padding to ensure input data conforms to Blowfish's 8-byte block length, with a utility to `trimZeroes` after decryption for text. It also offers built-in base64 encoding/decoding for handling the binary output of encryption. While Blowfish was designed for speed and flexibility with variable key lengths (32-448 bits) in 1993, its 64-bit block size is now considered a security weakness due to susceptibility to 'Sweet32' birthday attacks, especially for large data volumes (over 4GB). It's generally recommended for legacy systems or specific constrained environments rather than new applications, where modern ciphers like AES or Twofish are preferred. The library itself appears to be in a maintenance or inactive state, with no recent updates since 2018.
Common errors
-
Decrypted string contains extra null characters or appears corrupted after decryption.
cause The library automatically pads input strings with null bytes to meet the 8-byte block size requirement of Blowfish. These null bytes are retained after decryption if not explicitly removed.fixFor text data, apply `bf.trimZeroes(decryptedString)` after decryption to remove the padding characters. -
Error: 'IV must be 8 bytes long' or unexpected output when using CBC mode.
cause CBC (Cipher Block Chaining) mode requires an Initialization Vector (IV) that is exactly 8 bytes in length. Not providing it, or providing one of incorrect length, will cause issues.fixPass an 8-byte string as the second argument to the `Blowfish` constructor if specifying 'cbc' mode, and also to the `encrypt` and `decrypt` methods. E.g., `new Blowfish("key", "cbc"); bf.encrypt("message", "cbcvecto");` -
Encrypted output is unreadable or causes issues when stored/transmitted as text.
cause The `encrypt` method produces a raw binary string. Many text-based systems (databases, web forms, URLs) cannot correctly handle or preserve binary strings.fixUse `bf.base64Encode()` on the result of `bf.encrypt()` to convert the binary string into a safe, ASCII-representable format. Remember to `bf.base64Decode()` it before decryption.
Warnings
- breaking Blowfish, with its 64-bit block size, is susceptible to 'Sweet32' birthday attacks and is not recommended for encrypting data larger than 4GB. This is a fundamental cryptographic weakness of Blowfish, not specific to this library's implementation.
- gotcha The `encrypt` method returns a raw binary string. This output is not human-readable or safe for direct transmission in many text-based systems (e.g., JSON, URL query parameters).
- gotcha The library automatically pads input strings with null characters (`\0`) to meet Blowfish's 8-byte block length requirement. For text data, these padding characters will remain in the decrypted output.
- gotcha When using CBC (Cipher Block Chaining) mode, an 8-byte initialization vector (IV) is mandatory. Failing to provide a correct IV will lead to incorrect encryption/decryption or runtime errors.
- deprecated The Blowfish algorithm itself, while never fully broken, is considered an older cipher (designed in 1993) and has largely been superseded by more modern and robust algorithms like AES for general-purpose encryption.
Install
-
npm install javascript-blowfish -
yarn add javascript-blowfish -
pnpm add javascript-blowfish
Imports
- Blowfish
const Blowfish = require('javascript-blowfish');import { Blowfish } from 'javascript-blowfish'; - Blowfish constructor
const bf = Blowfish("secret key");const bf = new Blowfish("secret key"); - CommonJS Import (Legacy)
import Blowfish from 'javascript-blowfish'; // for CommonJS environments
const Blowfish = require('javascript-blowfish');
Quickstart
import { Blowfish } from 'javascript-blowfish';
const encryptionKey = process.env.BLOWFISH_KEY ?? 'my-super-secret-key-1234567890';
const message = 'This is a secret message to be encrypted.';
// Initialize Blowfish in ECB mode (default)
const bf = new Blowfish(encryptionKey);
// Encrypt the message
const encrypted = bf.encrypt(message);
console.log('Encrypted (binary string):', encrypted);
// Decrypt the message
let decrypted = bf.decrypt(encrypted);
// Trim zero padding for string/text information
decrypted = bf.trimZeroes(decrypted);
console.log('Decrypted message:', decrypted);
// Example with Base64 encoding for easier handling of binary output
const bfBase64 = new Blowfish(encryptionKey);
const encryptedBase64 = bfBase64.base64Encode(bfBase64.encrypt(message));
console.log('Encrypted (Base64):', encryptedBase64);
let decryptedBase64 = bfBase64.decrypt(bfBase64.base64Decode(encryptedBase64));
decryptedBase64 = bfBase64.trimZeroes(decryptedBase64);
console.log('Decrypted (from Base64):', decryptedBase64);