yescrypt icon indicating copy to clipboard operation
yescrypt copied to clipboard

Support for programming languages

Open logix11 opened this issue 1 year ago • 8 comments

I am having difficulties confirming whether some programming languages (most notably--PHP) support yescrypt. Can the maintainers of this awesome project give us insights?

logix11 avatar Dec 16 '24 11:12 logix11

We have native yescrypt code for Go https://pkg.go.dev/github.com/openwall/yescrypt-go https://github.com/openwall/yescrypt-go but in other languages you'd currently access yescrypt by calling the system-provided crypt(3) function (or its corresponding thread-safe alternatives), as long as the system uses recent enough libxcrypt.

PHP used to call the system crypt(3) from its own PHP crypt() function, and perhaps also from password_verify(), when it couldn't recognize the hash type on its own. However, now that I try and test via https://3v4l.org/JdV0s it fails for yescrypt on all versions (and curiously it even segfaults on PHP 4.3.0 to 5.2.17) - I don't know whether this is specific to how that online service is setup (perhaps recent libxcrypt never available in it?) or it just doesn't work anywhere. Someone should try locally on a system with PHP and libxcrypt.

Edit: I just tried on the same Fedora system where the Perl example below works - unfortunately, in PHP it fails. Indeed, the distro-provided php binary isn't even linked against the system's libcrypt here. So maybe no luck calling into the system-provided yescrypt via PHP these days. There's still the option to invoke a separate program written in C, perhaps passing the data via stdin/stdout, or via the environment and stdout.

<?php
echo crypt('openwall', '$y$j9T$AAt9R641xPvCI9nXw1HHW/'), "\n";
echo password_verify('openwall', '$y$j9T$AAt9R641xPvCI9nXw1HHW/$cuQRBMN3N/f8IcmVN.4YrZ1bHMOiLOoz9/XQMKV/v0A'), "\n";
echo password_verify('rasmuslerdorf', '$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a'), "\n";
$ php yescrypt-test.php 
$y6rtnfhVV7JI

1

(The last line is a successful test with bcrypt, to make show what a successful check would have looked like.)

Here's a working example I have with Perl on Fedora:

#!/usr/bin/perl
print crypt('openwall', '$y$j9T$AAt9R641xPvCI9nXw1HHW/'), "\n";
$ ./yescrypt-test.pl 
$y$j9T$AAt9R641xPvCI9nXw1HHW/$cuQRBMN3N/f8IcmVN.4YrZ1bHMOiLOoz9/XQMKV/v0A

If your company or organization is in a position to fund the effort, we'd like to try and get native yescrypt support into upstream PHP proper, including into its modern password_hash / password_verify API. There's already our MD5 and bcrypt code in PHP, so we have positive experience contributing to PHP.

solardiz avatar Dec 16 '24 19:12 solardiz

Understood, mister @solardiz. I will write a simple bash script with pipes and ensure that this process is secure enough.
As for funding, I do not think (we) can (currently) afford to fund it; however, I will keep your suggestion in mind, and if (I) see (myself) or (my organization) capable of funding this project, then I will contact the OpenWall organization, Insh'Allah. Be cheerful.
Best regards,
L. M. Oukaci.

logix11 avatar Dec 17 '24 04:12 logix11

Just that I have published Node.js / WASM bindings for Yescrypt so that you could use them on Browser and Node.js as a replacement of PBKDF2 / Scrypt which is available on their webcrypto API https://github.com/cpuchain/yescrypt-js

With some example page here

https://cpuchain.github.io/yescrypt-js/wasm/example.html

cpuchainorg avatar Jun 08 '25 13:06 cpuchainorg

Thank you very much @cpuchainorg! Regarding the example page, I think it'd help if you start printing the hash encodings returned by yescrypt(). Since we currently don't have an API to encode a pre-computed hash (maybe it's something for us to add here), you could add a choice whether to compute KDF (then compute and print the hash value like you do now) or hash (then compute and print the hash string). Edit: also, for the KDF compute/print 32 bytes, which is the typical size (you currently print 16).

In other news, yescrypt recently got a Rust implementation by @newpavlov https://github.com/RustCrypto/password-hashes/tree/master/yescrypt

I should probably add mentions of / links to these to the yescrypt homepage.

solardiz avatar Jun 08 '25 13:06 solardiz

@solardiz Hello, yes think that I have missed some details and now they are fixed ( KDF outputs 32 bytes, and have exposed hash functions as it could be tried on web version https://cpuchain.github.io/yescrypt-js/wasm/example.html ).

Would be a good thing if we have resources listed to help implementing those.

cpuchainorg avatar Jun 09 '25 11:06 cpuchainorg

@cpuchainorg Thank you! This seems to work mostly correctly, but the hex input isn't working right (not yet implemented? the setting seems ignored). Also, it'd help to be able to specify salt in base64 (for copy-paste from existing yescrypt hash encodings, or alternatively need a way to specify the entire setting string like $y$j9T$e8R9q85ZuzUkArEUurdtS.). For the defaults, I suggest N=4096 r=32. And maybe expose p and t inputs (your current defaults of 1 and 0 for those are correct)?

solardiz avatar Jun 09 '25 15:06 solardiz

@solardiz Yes, the hex input was inherited from scrypt-js UI http://ricmoo.github.io/scrypt-js/ ( actually I copied the one ) but I have made it functional now.

https://github.com/cpuchain/yescrypt-js/commit/dd0ad676a23b6d31e5a697d226739984bac6386a

Also, I have made the N value 4096 by default and exported p and t inputs as well ( and yes 1 and 0 are the default value for those https://github.com/cpuchain/yescrypt-js/blob/main/wasm/src/index.ts#L129 ).

Strange thing is that think there should be some extra function to decode the base64 string used for Yescrypt as atob function seems not working with the string that you have gave it to me https://github.com/cpuchain/yescrypt-js/blob/main/wasm/src/utils.ts#L5, or is it not base64?

cpuchainorg avatar Jun 09 '25 18:06 cpuchainorg

@cpuchainorg Thanks. Yes, it was a think-o on my part that ability to specify salt in base64 would have helped for this - it doesn't, because indeed crypt()'s encoding is a different base 64 encoding, not the RFC base64. And yes, we're missing an exported parameter decode function in this tree - something I've been meaning to add for a variety of use cases.

solardiz avatar Jun 09 '25 20:06 solardiz