{"id":11130,"library":"javascript-blowfish","title":"JavaScript Blowfish Encryption Library","description":"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.","status":"maintenance","version":"1.0.4","language":"javascript","source_language":"en","source_url":"https://github.com/agorlov/javascript-blowfish","tags":["javascript","node","js","blowfish","encryption","decryption","encypher","decypher","typescript"],"install":[{"cmd":"npm install javascript-blowfish","lang":"bash","label":"npm"},{"cmd":"yarn add javascript-blowfish","lang":"bash","label":"yarn"},{"cmd":"pnpm add javascript-blowfish","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"While the README examples show a CommonJS-like `var bf = new Blowfish()`, the package ships TypeScript types, implying a named export for ESM. The CommonJS `require` pattern is also widely used for older Node.js projects.","wrong":"const Blowfish = require('javascript-blowfish');","symbol":"Blowfish","correct":"import { Blowfish } from 'javascript-blowfish';"},{"note":"Blowfish is a class, and must be instantiated with the `new` keyword.","wrong":"const bf = Blowfish(\"secret key\");","symbol":"Blowfish constructor","correct":"const bf = new Blowfish(\"secret key\");"},{"note":"For older Node.js or CommonJS-only environments, `require` is the standard. If the module has a default export, `import Blowfish from '...'` might work in transpiled environments, but named import is safer for class exports.","wrong":"import Blowfish from 'javascript-blowfish'; // for CommonJS environments","symbol":"CommonJS Import (Legacy)","correct":"const Blowfish = require('javascript-blowfish');"}],"quickstart":{"code":"import { Blowfish } from 'javascript-blowfish';\n\nconst encryptionKey = process.env.BLOWFISH_KEY ?? 'my-super-secret-key-1234567890';\nconst message = 'This is a secret message to be encrypted.';\n\n// Initialize Blowfish in ECB mode (default)\nconst bf = new Blowfish(encryptionKey);\n\n// Encrypt the message\nconst encrypted = bf.encrypt(message);\nconsole.log('Encrypted (binary string):', encrypted);\n\n// Decrypt the message\nlet decrypted = bf.decrypt(encrypted);\n\n// Trim zero padding for string/text information\ndecrypted = bf.trimZeroes(decrypted);\n\nconsole.log('Decrypted message:', decrypted);\n\n// Example with Base64 encoding for easier handling of binary output\nconst bfBase64 = new Blowfish(encryptionKey);\nconst encryptedBase64 = bfBase64.base64Encode(bfBase64.encrypt(message));\nconsole.log('Encrypted (Base64):', encryptedBase64);\n\nlet decryptedBase64 = bfBase64.decrypt(bfBase64.base64Decode(encryptedBase64));\ndecryptedBase64 = bfBase64.trimZeroes(decryptedBase64);\nconsole.log('Decrypted (from Base64):', decryptedBase64);","lang":"typescript","description":"This quickstart demonstrates basic Blowfish encryption and decryption using a secret key. It covers handling the binary output of encryption, including trimming zero padding for text data and using base64 encoding for convenient representation."},"warnings":[{"fix":"For new applications or large data volumes, prefer modern ciphers like AES (e.g., `crypto` module in Node.js) or Twofish, which use larger block sizes (e.g., 128-bit).","message":"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.","severity":"breaking","affected_versions":"all"},{"fix":"Always use `bf.base64Encode()` on the encrypted output before storing or transmitting it, and `bf.base64Decode()` before decryption, as shown in the examples. This converts the binary data into a safe text format.","message":"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).","severity":"gotcha","affected_versions":"all"},{"fix":"After decrypting text data, explicitly call `bf.trimZeroes(decryptedString)` to remove the trailing null characters and restore the original plaintext.","message":"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.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure you provide an 8-byte string as the second argument to `bf.encrypt(message, 'cbcvecto')` and `bf.decrypt(encrypted, 'cbcvecto')` when operating in CBC mode. The IV should be unique for each encryption operation (though not necessarily secret) and transmitted alongside the ciphertext.","message":"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.","severity":"gotcha","affected_versions":"all"},{"fix":"Consider migrating to Advanced Encryption Standard (AES) implementations (e.g., Node.js's built-in `crypto` module or a well-vetted third-party library) for new projects to ensure better security posture and performance on modern hardware.","message":"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.","severity":"deprecated","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"For text data, apply `bf.trimZeroes(decryptedString)` after decryption to remove the padding characters.","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.","error":"Decrypted string contains extra null characters or appears corrupted after decryption."},{"fix":"Pass 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\");`","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.","error":"Error: 'IV must be 8 bytes long' or unexpected output when using CBC mode."},{"fix":"Use `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.","cause":"The `encrypt` method produces a raw binary string. Many text-based systems (databases, web forms, URLs) cannot correctly handle or preserve binary strings.","error":"Encrypted output is unreadable or causes issues when stored/transmitted as text."}],"ecosystem":"npm"}