0

I am trying to do the equivalent of openssl passwd -6 in nodejs using the crypto library.

My attempt was to use this function:

import * as crypto from "node:crypto";
import { promisify } from "node:util";

const pbkdf2 = promisify(crypto.pbkdf2);

export async function sha256Password(
  password: string,
  salt: string
): Promise<string> {
  const derivedKey = await pbkdf2(password, salt, 10000, 64, "sha256");

  return `$6$${salt}$${derivedKey.toString("base64")}`;
}

However given a password "my-password" and a salt "saltytest" the string that openssl generates is:

openssl -6 --salt saltytest my-password
$6$saltytest$PxLELj3gGh05NbVO3c3o1mt92k5KZsg1V3OtI4dlclCclCqT4jwwN4Oi325S7T5VNI8JlEF3BnwhkxP5xmYHn/

But my sha256Password function yields something different:

await sha256Password("my-password", "saltytest")
$6$saltytest$anHaLrq0Dl+zNBuXT0v5w91vxwDSNtz/DU2hnRtE2CBiCx5uhyzMi+Euo0bENXe1Poriyq96YpkMHS8hx4IGPQ==

What I am not really sure about, is how exactly openssl passwd -6 really works. In particular I wonder which of my assumptions were wrong:

  • The correct function to use is pbkdf2
  • Encoding of output is base64
  • Number of iterations or passes is 10,000
  • The key-length is 64
d_inevitable
  • 4,381
  • 2
  • 29
  • 48
  • 1
    *...What I am not really sure about, is how exactly openssl passwd -6 really works....* Is described in the [openssl-passwd](https://www.openssl.org/docs/man3.1/man1/openssl-passwd.html) documentation, namely the [algorithm by U. Drepper](https://www.akkadia.org/drepper/SHA-crypt.txt). AFAIK there is no ready-to-use implementation in node/crypto, but you can implement this on your own. However, there are already NodeJS libraries for this, e.g. [unixcrypt](https://github.com/markusberg/unixcrypt). – Topaco Jul 21 '23 at 08:14

1 Answers1

0

Thanks for the comment @Topaco. The suggestion of using unixcrypt actually works:

npm install unixcrypt
import { encrypt } from "unixcrypt";


export function sha256Password(password: string, salt: string): string {
  return encrypt(password, `$6$${salt}`);
}
encrypt("my-password", "$6$saltytest");
$6$saltytest$PxLELj3gGh05NbVO3c3o1mt92k5KZsg1V3OtI4dlclCclCqT4jwwN4Oi325S7T5VNI8JlEF3BnwhkxP5xmYHn/
d_inevitable
  • 4,381
  • 2
  • 29
  • 48