[{"data":1,"prerenderedAt":547},["ShallowReactive",2],{"navigation_docs":3,"-algorithms-bcrypt":244,"-algorithms-bcrypt-surround":544},[4,52],{"title":5,"path":6,"stem":7,"children":8,"icon":51},"Guide","\u002Fguide","1.guide\u002F01.index",[9,11,15,19,23,27,31,35,39,43,47],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Hashing","\u002Fguide\u002Fhashing","1.guide\u002F02.hashing",{"title":16,"path":17,"stem":18},"HMAC and verify","\u002Fguide\u002Fverify","1.guide\u002F03.verify",{"title":20,"path":21,"stem":22},"Salted KDFs","\u002Fguide\u002Fkdf","1.guide\u002F04.kdf",{"title":24,"path":25,"stem":26},"Length extension","\u002Fguide\u002Fextend","1.guide\u002F05.extend",{"title":28,"path":29,"stem":30},"Identify a hash","\u002Fguide\u002Fidentify","1.guide\u002F06.identify",{"title":32,"path":33,"stem":34},"Search for a transform","\u002Fguide\u002Fsearch","1.guide\u002F07.search",{"title":36,"path":37,"stem":38},"CLI","\u002Fguide\u002Fcli","1.guide\u002F08.cli",{"title":40,"path":41,"stem":42},"Agents","\u002Fguide\u002Fagents","1.guide\u002F09.agents",{"title":44,"path":45,"stem":46},"Custom algorithms","\u002Fguide\u002Fcustom","1.guide\u002F10.custom",{"title":48,"path":49,"stem":50},"Playground","\u002Fguide\u002Fplayground","1.guide\u002F11.playground","i-lucide-book-open",{"title":53,"path":54,"stem":55,"children":56,"icon":243},"Algorithms","\u002Falgorithms","2.algorithms\u002F00.index",[57,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123,127,131,135,139,143,147,151,155,159,163,167,171,175,179,183,187,191,195,199,203,207,211,215,219,223,227,231,235,239],{"title":58,"path":54,"stem":55},"Every algorithm",{"title":60,"path":61,"stem":62},"SHA-256","\u002Falgorithms\u002Fsha256","2.algorithms\u002F01.sha256",{"title":64,"path":65,"stem":66},"SHA-384","\u002Falgorithms\u002Fsha384","2.algorithms\u002F02.sha384",{"title":68,"path":69,"stem":70},"SHA-512","\u002Falgorithms\u002Fsha512","2.algorithms\u002F03.sha512",{"title":72,"path":73,"stem":74},"SHA-224","\u002Falgorithms\u002Fsha224","2.algorithms\u002F04.sha224",{"title":76,"path":77,"stem":78},"SHA-512\u002F224","\u002Falgorithms\u002Fsha512-224","2.algorithms\u002F05.sha512-224",{"title":80,"path":81,"stem":82},"SHA-512\u002F256","\u002Falgorithms\u002Fsha512-256","2.algorithms\u002F06.sha512-256",{"title":84,"path":85,"stem":86},"SHA-512Half","\u002Falgorithms\u002Fsha512-half","2.algorithms\u002F07.sha512-half",{"title":88,"path":89,"stem":90},"SHA3-256","\u002Falgorithms\u002Fsha3-256","2.algorithms\u002F08.sha3-256",{"title":92,"path":93,"stem":94},"SHA3-512","\u002Falgorithms\u002Fsha3-512","2.algorithms\u002F09.sha3-512",{"title":96,"path":97,"stem":98},"Keccak-256","\u002Falgorithms\u002Fkeccak256","2.algorithms\u002F10.keccak256",{"title":100,"path":101,"stem":102},"BLAKE2b","\u002Falgorithms\u002Fblake2b","2.algorithms\u002F11.blake2b",{"title":104,"path":105,"stem":106},"BLAKE2b-256","\u002Falgorithms\u002Fblake2b-256","2.algorithms\u002F12.blake2b-256",{"title":108,"path":109,"stem":110},"BLAKE2b-224","\u002Falgorithms\u002Fblake2b-224","2.algorithms\u002F13.blake2b-224",{"title":112,"path":113,"stem":114},"BLAKE2s","\u002Falgorithms\u002Fblake2s","2.algorithms\u002F14.blake2s",{"title":116,"path":117,"stem":118},"BLAKE3","\u002Falgorithms\u002Fblake3","2.algorithms\u002F15.blake3",{"title":120,"path":121,"stem":122},"BLAKE-256","\u002Falgorithms\u002Fblake256","2.algorithms\u002F16.blake256",{"title":124,"path":125,"stem":126},"RIPEMD-160","\u002Falgorithms\u002Fripemd160","2.algorithms\u002F17.ripemd160",{"title":128,"path":129,"stem":130},"RIPEMD-320","\u002Falgorithms\u002Fripemd320","2.algorithms\u002F18.ripemd320",{"title":132,"path":133,"stem":134},"HASH160","\u002Falgorithms\u002Fhash160","2.algorithms\u002F19.hash160",{"title":136,"path":137,"stem":138},"HASH256","\u002Falgorithms\u002Fhash256","2.algorithms\u002F20.hash256",{"title":140,"path":141,"stem":142},"Whirlpool","\u002Falgorithms\u002Fwhirlpool","2.algorithms\u002F21.whirlpool",{"title":144,"path":145,"stem":146},"MD5","\u002Falgorithms\u002Fmd5","2.algorithms\u002F22.md5",{"title":148,"path":149,"stem":150},"MD4","\u002Falgorithms\u002Fmd4","2.algorithms\u002F23.md4",{"title":152,"path":153,"stem":154},"MD2","\u002Falgorithms\u002Fmd2","2.algorithms\u002F24.md2",{"title":156,"path":157,"stem":158},"NTLM","\u002Falgorithms\u002Fntlm","2.algorithms\u002F25.ntlm",{"title":160,"path":161,"stem":162},"SHA-1","\u002Falgorithms\u002Fsha1","2.algorithms\u002F26.sha1",{"title":164,"path":165,"stem":166},"SHA-0","\u002Falgorithms\u002Fsha0","2.algorithms\u002F27.sha0",{"title":168,"path":169,"stem":170},"RIPEMD-128","\u002Falgorithms\u002Fripemd128","2.algorithms\u002F28.ripemd128",{"title":172,"path":173,"stem":174},"RIPEMD-256","\u002Falgorithms\u002Fripemd256","2.algorithms\u002F29.ripemd256",{"title":176,"path":177,"stem":178},"HAVAL","\u002Falgorithms\u002Fhaval","2.algorithms\u002F30.haval",{"title":180,"path":181,"stem":182},"Tiger","\u002Falgorithms\u002Ftiger","2.algorithms\u002F31.tiger",{"title":184,"path":185,"stem":186},"CRC-32","\u002Falgorithms\u002Fcrc32","2.algorithms\u002F32.crc32",{"title":188,"path":189,"stem":190},"CRC-64","\u002Falgorithms\u002Fcrc64","2.algorithms\u002F33.crc64",{"title":192,"path":193,"stem":194},"CRC-24","\u002Falgorithms\u002Fcrc24","2.algorithms\u002F34.crc24",{"title":196,"path":197,"stem":198},"CRC-16\u002FXMODEM","\u002Falgorithms\u002Fcrc16-xmodem","2.algorithms\u002F35.crc16-xmodem",{"title":200,"path":201,"stem":202},"Adler-32","\u002Falgorithms\u002Fadler32","2.algorithms\u002F36.adler32",{"title":204,"path":205,"stem":206},"xxHash","\u002Falgorithms\u002Fxxhash","2.algorithms\u002F37.xxhash",{"title":208,"path":209,"stem":210},"FNV-1a (64-bit)","\u002Falgorithms\u002Ffnv1a","2.algorithms\u002F38.fnv1a",{"title":212,"path":213,"stem":214},"scrypt","\u002Falgorithms\u002Fscrypt","2.algorithms\u002F39.scrypt",{"title":216,"path":217,"stem":218},"PBKDF2","\u002Falgorithms\u002Fpbkdf2","2.algorithms\u002F40.pbkdf2",{"title":220,"path":221,"stem":222},"HKDF","\u002Falgorithms\u002Fhkdf","2.algorithms\u002F41.hkdf",{"title":224,"path":225,"stem":226},"EVP_BytesToKey","\u002Falgorithms\u002Fevp-bytestokey","2.algorithms\u002F42.evp-bytestokey",{"title":228,"path":229,"stem":230},"Argon2id","\u002Falgorithms\u002Fargon2id","2.algorithms\u002F43.argon2id",{"title":232,"path":233,"stem":234},"Argon2i","\u002Falgorithms\u002Fargon2i","2.algorithms\u002F44.argon2i",{"title":236,"path":237,"stem":238},"Argon2d","\u002Falgorithms\u002Fargon2d","2.algorithms\u002F45.argon2d",{"title":240,"path":241,"stem":242},"bcrypt","\u002Falgorithms\u002Fbcrypt","2.algorithms\u002F46.bcrypt","i-lucide-library",{"id":245,"title":240,"body":246,"description":538,"extension":539,"links":540,"meta":541,"navigation":449,"path":241,"seo":542,"stem":242,"__hash__":543},"docs\u002F2.algorithms\u002F46.bcrypt.md",{"type":247,"value":248,"toc":536},"minimark",[249,252,256,356,375,382,392,416,423,529,532],[250,251],"algorithm-facts",{"name":240},[253,254,255],"p",{},"bcrypt is old. Provos and Mazières built it for OpenBSD in 1999, and it still sits in plenty of password tables. The trick is Blowfish's key setup. It's slow, so bcrypt runs it 2^cost times and calls that a feature. Fair enough.",[257,258,263],"pre",{"className":259,"code":260,"language":261,"meta":262,"style":262},"language-ts shiki shiki-themes hashes hashes hashes","const result = create(\"bcrypt\").hash(\"password\", {\n  salt: \"73616c7473616c7473616c7473616c74\",\n  cost: 4,\n});\nresult.digest;\n\u002F\u002F \"9f72647acd4f9f84df28e21dca2617f0cd69df0b4d8fcb\"\nresult.options.crypt;\n\u002F\u002F \"$2b$04$a0DqbFLfZFPxWUvya0Dqb.l1HicqzNl2RdIMGbwgWV6Kzn1urLh6q\"\n","ts","",[264,265,266,307,319,325,331,337,344,350],"code",{"__ignoreMap":262},[267,268,271,275,279,282,286,289,293,296,299,301,304],"span",{"class":269,"line":270},"line",1,[267,272,274],{"class":273},"skH_V","const",[267,276,278],{"class":277},"s38Sx"," result ",[267,280,281],{"class":273},"=",[267,283,285],{"class":284},"sK71F"," create",[267,287,288],{"class":277},"(",[267,290,292],{"class":291},"shU9J","\"bcrypt\"",[267,294,295],{"class":277},").",[267,297,298],{"class":284},"hash",[267,300,288],{"class":277},[267,302,303],{"class":291},"\"password\"",[267,305,306],{"class":277},", {\n",[267,308,310,313,316],{"class":269,"line":309},2,[267,311,312],{"class":277},"  salt: ",[267,314,315],{"class":291},"\"73616c7473616c7473616c7473616c74\"",[267,317,318],{"class":277},",\n",[267,320,322],{"class":269,"line":321},3,[267,323,324],{"class":277},"  cost: 4,\n",[267,326,328],{"class":269,"line":327},4,[267,329,330],{"class":277},"});\n",[267,332,334],{"class":269,"line":333},5,[267,335,336],{"class":277},"result.digest;\n",[267,338,340],{"class":269,"line":339},6,[267,341,343],{"class":342},"scIB-","\u002F\u002F \"9f72647acd4f9f84df28e21dca2617f0cd69df0b4d8fcb\"\n",[267,345,347],{"class":269,"line":346},7,[267,348,349],{"class":277},"result.options.crypt;\n",[267,351,353],{"class":269,"line":352},8,[267,354,355],{"class":342},"\u002F\u002F \"$2b$04$a0DqbFLfZFPxWUvya0Dqb.l1HicqzNl2RdIMGbwgWV6Kzn1urLh6q\"\n",[253,357,358,359,362,363,366,367,370,371,374],{},"The salt is ",[264,360,361],{},"saltsaltsaltsalt"," in hex. bcrypt takes exactly 16 bytes, no more and no less. Leave it out and 16 random bytes come back in ",[264,364,365],{},"result.options",". The digest is the 23 bytes the string carries after its salt. Want the thing a database or ",[264,368,369],{},".htpasswd"," stores? That's ",[264,372,373],{},"crypt",".",[253,376,377,378,381],{},"Each step of ",[264,379,380],{},"cost"," doubles the work. The default is 12, OWASP asks for at least 10. The page above runs cost 4, the lowest there is, so the tab doesn't sit and think. Tool calls stop at 16.",[253,383,384,385,388,389,391],{},"Here's where this package parts ways with OpenBSD. A password past 72 bytes is an error. OpenBSD, crypt_blowfish and ",[264,386,387],{},"htpasswd"," just drop the rest. So any password with the same first 72 bytes passes, and nobody tells you. Python's ",[264,390,240],{}," 5.0 refuses too, which feels like the right call.",[253,393,394,397,398,401,402,405,406,408,409,411,412,415],{},[264,395,396],{},"$2a$",", ",[264,399,400],{},"$2b$"," and ",[264,403,404],{},"$2y$"," hash the same under that limit. A hash ",[264,407,387],{}," wrote as ",[264,410,404],{}," checks out with the same salt and cost. ",[264,413,414],{},"$2x$"," is the odd one: crypt_blowfish's old sign bug, and this package doesn't run it.",[253,417,418,419,422],{},"Checking a hash from a dump or a config file in your own code? ",[264,420,421],{},"@agntn\u002Fhashes\u002Fbcrypt"," has the bytes and the string as plain functions:",[257,424,426],{"className":259,"code":425,"language":261,"meta":262,"style":262},"import { bcrypt, bcryptString } from \"@agntn\u002Fhashes\u002Fbcrypt\";\n\nconst text = new TextEncoder();\nconst salt = text.encode(\"saltsaltsaltsalt\");\nconst digest = bcrypt(text.encode(\"password\"), salt, 4);\nbcryptString(salt, 4, digest);\n\u002F\u002F the same $2b$ string as above\n",[264,427,428,445,451,469,492,516,524],{"__ignoreMap":262},[267,429,430,433,436,439,442],{"class":269,"line":270},[267,431,432],{"class":273},"import",[267,434,435],{"class":277}," { bcrypt, bcryptString } ",[267,437,438],{"class":273},"from",[267,440,441],{"class":291}," \"@agntn\u002Fhashes\u002Fbcrypt\"",[267,443,444],{"class":277},";\n",[267,446,447],{"class":269,"line":309},[267,448,450],{"emptyLinePlaceholder":449},true,"\n",[267,452,453,455,458,460,463,466],{"class":269,"line":321},[267,454,274],{"class":273},[267,456,457],{"class":277}," text ",[267,459,281],{"class":273},[267,461,462],{"class":273}," new",[267,464,465],{"class":284}," TextEncoder",[267,467,468],{"class":277},"();\n",[267,470,471,473,476,478,481,484,486,489],{"class":269,"line":327},[267,472,274],{"class":273},[267,474,475],{"class":277}," salt ",[267,477,281],{"class":273},[267,479,480],{"class":277}," text.",[267,482,483],{"class":284},"encode",[267,485,288],{"class":277},[267,487,488],{"class":291},"\"saltsaltsaltsalt\"",[267,490,491],{"class":277},");\n",[267,493,494,496,499,501,504,507,509,511,513],{"class":269,"line":333},[267,495,274],{"class":273},[267,497,498],{"class":277}," digest ",[267,500,281],{"class":273},[267,502,503],{"class":284}," bcrypt",[267,505,506],{"class":277},"(text.",[267,508,483],{"class":284},[267,510,288],{"class":277},[267,512,303],{"class":291},[267,514,515],{"class":277},"), salt, 4);\n",[267,517,518,521],{"class":269,"line":339},[267,519,520],{"class":284},"bcryptString",[267,522,523],{"class":277},"(salt, 4, digest);\n",[267,525,526],{"class":269,"line":346},[267,527,528],{"class":342},"\u002F\u002F the same $2b$ string as above\n",[253,530,531],{},"No default cost and no random salt here. You pass all three. A salt of the wrong size or a cost outside 4 to 31 throws before Blowfish starts.",[533,534,535],"style",{},"html pre.shiki code .skH_V, html code.shiki .skH_V{--shiki-light:var(--shiki-token-keyword);--shiki-default:var(--shiki-token-keyword);--shiki-dark:var(--shiki-token-keyword)}html pre.shiki code .s38Sx, html code.shiki .s38Sx{--shiki-light:var(--ui-text-highlighted);--shiki-default:var(--ui-text-highlighted);--shiki-dark:var(--ui-text-highlighted)}html pre.shiki code .sK71F, html code.shiki .sK71F{--shiki-light:var(--shiki-token-function);--shiki-default:var(--shiki-token-function);--shiki-dark:var(--shiki-token-function)}html pre.shiki code .shU9J, html code.shiki .shU9J{--shiki-light:var(--shiki-token-string);--shiki-default:var(--shiki-token-string);--shiki-dark:var(--shiki-token-string)}html pre.shiki code .scIB-, html code.shiki .scIB-{--shiki-light:var(--shiki-token-comment);--shiki-default:var(--shiki-token-comment);--shiki-dark:var(--shiki-token-comment)}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":262,"searchDepth":309,"depth":309,"links":537},[],"The OpenBSD password hash from 1999. Blowfish key setup on repeat and the crypt string comes back with every result","md",null,{},{"title":240,"description":538},"OMyat4zPZW_f7-oIpBWbzd3x7JTgB5cVMO8MTSWEUxA",[545,540],{"title":236,"path":237,"stem":238,"description":546,"children":-1},"Argon2 with memory reads that follow the data. The fastest to hurt a GPU and the wrong pick when someone shares the machine",1791911608869]