Unix crypt(3) DES-based Hash Implementation
unix-crypt-td-js is a JavaScript implementation of the DES-based Unix crypt(3) password hashing algorithm, primarily based on the `crypt.c` source from the Seventh Edition Unix distribution. The package's current stable version is 1.1.4, with its last known publication to npm occurring in October 2019. Despite its historical accuracy in replicating the original Unix `crypt(3)` behavior, the underlying Data Encryption Standard (DES) algorithm is now considered cryptographically insecure. It utilizes a 56-bit key and only the first eight characters of a password, combined with a 12-bit salt, making it highly susceptible to modern brute-force attacks, dictionary attacks, and rainbow table attacks. The package is effectively unmaintained, with Snyk reporting an 'Inactive' maintenance status and limited community activity. Due to these fundamental security weaknesses and lack of ongoing development, it is unsuitable for securing sensitive data or user passwords in contemporary applications. Developers requiring secure password hashing should use modern, robust algorithms like bcrypt, scrypt, or Argon2, which are designed to resist current cryptanalytic techniques. The package has no active release cadence.
Common errors
-
Passwords are being compromised easily.
cause The DES-based Unix crypt(3) hash, implemented by this package, is fundamentally weak and susceptible to modern cracking techniques like brute-force and rainbow tables.fixImmediately replace `unix-crypt-td-js` with a modern, secure password hashing library such as `bcrypt`, `scrypt-js`, or `argon2`. -
Hash output is the same for different long passwords.
cause The Unix crypt(3) DES algorithm only processes the first 8 characters of the input password; any characters beyond that are ignored.fixThis is an inherent limitation of the algorithm. If full password entropy is required, you *must* switch to a different hashing algorithm that supports and utilizes longer passwords.
Warnings
- breaking The Data Encryption Standard (DES) algorithm used by this package is cryptographically insecure due to its short 56-bit key length and susceptibility to brute-force attacks with modern hardware. It has been formally withdrawn as a standard by NIST and is considered obsolete.
- gotcha The underlying Unix crypt(3) DES algorithm only uses the first eight characters of the provided password for hashing, silently truncating any longer input. This significantly reduces the effective entropy and makes passwords easier to crack.
- gotcha The DES-based crypt(3) algorithm uses a small 12-bit salt, leading to a limited number of unique hashes (4096 possible salts). This makes it highly vulnerable to precomputed rainbow table attacks, especially when combined with common passwords.
- deprecated This package is effectively unmaintained, with no new versions released to npm in recent years and limited community activity, as reported by Snyk.
Install
-
npm install unix-crypt-td-js -
yarn add unix-crypt-td-js -
pnpm add unix-crypt-td-js
Imports
- unixCryptTD
import { unixCryptTD } from 'unix-crypt-td-js';const unixCryptTD = require('unix-crypt-td-js'); - unixCryptTD
const { unixCryptTD } = require('unix-crypt-td-js');import unixCryptTD from 'unix-crypt-td-js';
Quickstart
const unixCryptTD = require('unix-crypt-td-js');
const password = 'mysecretpassword';
const salt = 'ab'; // In real Unix crypt(3), salt is typically 2 characters.
const hashedPassword = unixCryptTD(password, salt);
console.log(`Hashed password (string): ${hashedPassword}`); // Expected output: 'abF03p.uQ.KqE'
// Example with byte array input and byte array output
const passwordBytes = [102, 111, 111, 98]; // 'foob'
const saltBytes = [97, 114]; // 'ar'
const hashedPasswordBytes = unixCryptTD(passwordBytes, saltBytes, true);
console.log(`Hashed password (bytes): [${hashedPasswordBytes.join(', ')}]`); // Expected output: '[97, 114, 108, 69, 75, 110, 48, 79, 122, 86, 74, 110, 46]'
// Demonstrating the 8-character limit (the extra 's' is ignored)
const longPassword = 'thisisalongpassword';
const shortSalt = 'cd';
const hashedLongPassword = unixCryptTD(longPassword, shortSalt);
const hashedFirst8Chars = unixCryptTD('thisisal', shortSalt);
console.log(`Hashed long password: ${hashedLongPassword}`);
console.log(`Hashed first 8 chars: ${hashedFirst8Chars}`);
console.log(`Are they the same? ${hashedLongPassword === hashedFirst8Chars}`); // Should be true