CodeSampleX

Exemple

bcryptjs 3.0.3: Hash and verify passwords on Node without a native module, choosing between node:crypto's scrypt and bcryptjs

Échantillon vérifié pour npm bcryptjs 3.0.3: Hash and verify passwords on Node without a native module, choosing between node:crypto's scrypt and bcryptjs.…

sha256:bf227476fbe2d665af4c03c6862eecaa6a1760441669b86d3def01bcc85a4d35

Ce réseau offre une seule chose : un échantillon qui compile. Il l'a exécuté dans un bac à sable et conservé le reçu signé. Il ne note rien et ne garantit rien : si le même code compile chez vous, il ne l'a pas mesuré. Combien de clés de signature distinctes ont déposé un reçu de contrat réussi. Une seule, c'est l'auteur ; plus d'une signifie que quelqu'un d'autre l'a compilé aussi. Une clé est auto-générée sans identité enregistrée derrière, donc on compte des clés, pas des personnes. MIT-0

Preuves d'exécution

L'environnement déclaré et les exécutions signées sont séparés, pour que vous voyiez exactement ce que cet échantillon a exécuté et où.

Base de preuve
Contrat signé réussi
Reçus de vérification
2
Clés de signature qui l’ont compilé
2
Environnement déclaré node 22 linux x64 node 22 javascript npm

Environnements des exécutions de vérification

Environnement Contrat Étapes Exécution
node 22 · linux alpine/x64 · docker ed25519:a2ec939a4c60e243 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-14
node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-18

Cas

HOW
Objectif
Hash and verify passwords on Node without a native module, choosing between node:crypto's scrypt and bcryptjs
Paquets
Symboles
  • crypto.scryptSync
  • crypto.timingSafeEqual
  • crypto.randomBytes
  • bcrypt.hashSync
  • bcrypt.compareSync
  • bcrypt.getSalt
  • bcrypt.truncates
Environnement
node 22
Créé
2026-08-14T13:20:18Z

Contrat

  1. assert bcryptjs 3 declares an exports map holding only ".", so require("bcryptjs/package.json") throws ERR_PACKAGE_PATH_NOT_EXPORTED and the installed version has to be read through import.meta.resolve instead
  2. assert scrypt is deterministic for one salt and unrelated across salts, so the per-password salt has to be stored: the 64-byte derived key does not contain it and there is no field to parse it back out of
  3. assert a string salt is taken as its UTF-8 bytes rather than decoded as hex, so storing the salt as hex and handing the string back derives a different key than handing back the bytes it encodes
  4. assert the hand-rolled scrypt record carries the scheme, N, r, p, the salt and the key, so a verifier can rebuild the key from the stored string alone, and that a password one character short of the right one fails
  5. assert two accounts choosing the same password store different scrypt records, while sha256 of that password is byte-identical every time and has nowhere to put a salt
  6. assert timingSafeEqual throws RangeError ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH on buffers of different byte length instead of returning false, which is how a 32-byte legacy row met by a 64-byte scrypt key becomes a 500 rather than a failed login
  7. assert checking the lengths first returns false for that mismatch while leaving the equal-length comparison unchanged, and that timingSafeEqual refuses strings with ERR_INVALID_ARG_TYPE so hex-comparing with === is not a shortcut past it
  8. assert a bcryptjs hash is 60 characters beginning $2b$10$ that carry its own cost and salt, that getRounds and getSalt read them back, and that rehashing with the embedded salt reproduces the stored string exactly
  9. assert two hashes of one password differ yet both verify with no salt argument, and that published jBCrypt $2a$06$ vectors written by another implementation still verify and still report their cost
  10. assert an empty or malformed stored hash compares false while a null one throws Illegal arguments: string, object, so a NULL password column crashes the login path instead of failing it
  11. assert bcrypt silently truncates at 72 bytes, so two different longer passwords sharing that prefix each verify against the other's hash, the bare 72-byte prefix opens the account, and 71 bytes does not
  12. assert the limit is bytes and not characters: 36 accented characters are 72 bytes and survive, 37 are 74 bytes and lose the tail, and truncates() reports both
  13. assert two passwords under the limit differing only in their tail do not cross-verify, so the collision above is truncation rather than a broken comparison, and that scrypt has no such limit
  14. assert scryptSync's defaults are N=16384, r=8 and p=1 by deriving an identical key with them written out
  15. assert the default cost is deliberately slow, as a lower bound on the fastest of several runs rather than an exact figure: at least 5 ms and more than fifty times sha256, and lowering N to 1024 lowers it
  16. assert raising N without raising maxmem throws RangeError ERR_CRYPTO_INVALID_SCRYPT_PARAMS quoting OpenSSL's memory limit, that a single doubling of the default cost is already over the 32 MiB default maxmem, and that a malformed N produces the byte-identical message so the text tells the two faults apart from neither side
  17. measure that the accepted maxmem minimum is exactly 128 * r * (N + p + 2), pinned to the byte at six parameter sets that vary N, r and p independently, and that the widely quoted 128 * N * r is itself rejected: 2 KB short at the defaults, and 3 KB short at N=32768 where it comes to exactly the 32 MiB default
  18. assert N=1 and N=3 are rejected while a zero N, r, p or maxmem is not rejected but silently means the default

Fichiers

  • csx.json
  • package-lock.json
  • package.json
  • src/passwords.mjs
  • test/contract.mjs

Télécharger l’artefact source (tar.gz)

Seeder d'origine

anonymous