[{"data":1,"prerenderedAt":678},["ShallowReactive",2],{"guide-md5-security-vulnerabilities":3},{"id":4,"title":5,"body":6,"date":670,"description":671,"extension":672,"meta":673,"navigation":122,"path":674,"readingTime":119,"seo":675,"stem":676,"__hash__":677},"guides\u002Fguides\u002Fmd5-security-vulnerabilities.md","MD5 Security Vulnerabilities Explained in Depth",{"type":7,"value":8,"toc":649},"minimark",[9,14,18,21,25,30,33,37,40,51,54,58,61,148,152,155,159,162,166,169,173,176,262,266,349,352,356,360,363,496,500,503,537,541,544,601,605,627,631,640,645],[10,11,13],"h2",{"id":12},"md5-from-standard-to-security-liability","MD5: From Standard to Security Liability",[15,16,17],"p",{},"MD5 (Message-Digest Algorithm 5) produces a 128-bit hash value, typically displayed as a 32-character hexadecimal string. Designed by Ronald Rivest in 1991 as a successor to MD4, it became the default hash function for checksums, password storage, and digital signatures.",[15,19,20],{},"Today, MD5 is cryptographically broken. Multiple practical attacks can find collisions — two different inputs producing the same hash — in seconds. Understanding these vulnerabilities helps you choose the right algorithm for each situation.",[10,22,24],{"id":23},"collision-attacks","Collision Attacks",[26,27,29],"h3",{"id":28},"what-is-a-collision","What Is a Collision?",[15,31,32],{},"A collision occurs when two distinct inputs produce the same hash output. For a secure 128-bit hash, finding a collision by brute force should require approximately 2^64 operations. MD5 collisions can be found in under a second on a modern laptop.",[26,34,36],{"id":35},"how-collision-attacks-work","How Collision Attacks Work",[15,38,39],{},"MD5 processes input in 512-bit blocks using a Merkle-Damgard construction. Each block's output feeds into the next block's computation. Collision attacks exploit weaknesses in the compression function to find two messages that diverge at a particular block but produce identical intermediate state values:",[41,42,47],"pre",{"className":43,"code":45,"language":46},[44],"language-text","Message A: [Block 1] [Block 2a] [Block 3]\nMessage B: [Block 1] [Block 2b] [Block 3]\n\nWhere Block 2a ≠ Block 2b, but MD5(Block 1 + Block 2a) = MD5(Block 1 + Block 2b)\n","text",[48,49,45],"code",{"__ignoreMap":50},"",[15,52,53],{},"Once the intermediate states match, appending identical suffix blocks preserves the collision.",[26,55,57],{"id":56},"practical-impact","Practical Impact",[15,59,60],{},"In 2008, researchers created a rogue CA certificate using an MD5 collision. They generated two certificate signing requests with different identities but the same MD5 hash. The legitimate certificate was signed by a trusted CA, and the attacker's certificate — with the same hash — inherited that trust.",[41,62,66],{"className":63,"code":64,"language":65,"meta":50,"style":50},"language-bash shiki shiki-themes github-light github-dark","# Demonstrating a collision (using a collision generator tool)\n# Two different files with the same MD5 hash\n$ md5sum message-a.bin message-b.bin\n79054025255fb1a26e4bc422aef54eb4  message-a.bin\n79054025255fb1a26e4bc422aef54eb4  message-b.bin\n\n$ diff message-a.bin message-b.bin\nBinary files differ\n","bash",[48,67,68,77,83,100,109,117,124,136],{"__ignoreMap":50},[69,70,73],"span",{"class":71,"line":72},"line",1,[69,74,76],{"class":75},"sJ8bj","# Demonstrating a collision (using a collision generator tool)\n",[69,78,80],{"class":71,"line":79},2,[69,81,82],{"class":75},"# Two different files with the same MD5 hash\n",[69,84,86,90,94,97],{"class":71,"line":85},3,[69,87,89],{"class":88},"sScJk","$",[69,91,93],{"class":92},"sZZnC"," md5sum",[69,95,96],{"class":92}," message-a.bin",[69,98,99],{"class":92}," message-b.bin\n",[69,101,103,106],{"class":71,"line":102},4,[69,104,105],{"class":88},"79054025255fb1a26e4bc422aef54eb4",[69,107,108],{"class":92},"  message-a.bin\n",[69,110,112,114],{"class":71,"line":111},5,[69,113,105],{"class":88},[69,115,116],{"class":92},"  message-b.bin\n",[69,118,120],{"class":71,"line":119},6,[69,121,123],{"emptyLinePlaceholder":122},true,"\n",[69,125,127,129,132,134],{"class":71,"line":126},7,[69,128,89],{"class":88},[69,130,131],{"class":92}," diff",[69,133,96],{"class":92},[69,135,99],{"class":92},[69,137,139,142,145],{"class":71,"line":138},8,[69,140,141],{"class":88},"Binary",[69,143,144],{"class":92}," files",[69,146,147],{"class":92}," differ\n",[10,149,151],{"id":150},"preimage-attacks","Preimage Attacks",[15,153,154],{},"A preimage attack finds an input that hashes to a specific target value. This is harder than finding a collision. For a secure 128-bit hash, preimage resistance should require 2^128 operations.",[26,156,158],{"id":157},"current-status","Current Status",[15,160,161],{},"Theoretical preimage attacks against MD5 exist but remain impractical. The best published attack requires approximately 2^123.4 operations — faster than brute force but still computationally infeasible. However, this margin shrinks as analysis improves.",[26,163,165],{"id":164},"second-preimage-attacks","Second Preimage Attacks",[15,167,168],{},"A second preimage attack finds a different input that produces the same hash as a given input. This differs from a collision attack because the target hash is fixed. Current attacks remain theoretical for full MD5, but reduced-round variants are vulnerable.",[10,170,172],{"id":171},"when-md5-is-still-acceptable","When MD5 Is Still Acceptable",[15,174,175],{},"Not every use of MD5 is a security risk. The vulnerabilities matter only when an attacker can exploit collisions.",[177,178,179,195],"table",{},[180,181,182],"thead",{},[183,184,185,189,192],"tr",{},[186,187,188],"th",{},"Use Case",[186,190,191],{},"Safe?",[186,193,194],{},"Reason",[196,197,198,210,220,231,241,251],"tbody",{},[183,199,200,204,207],{},[201,202,203],"td",{},"File integrity verification (accidental corruption)",[201,205,206],{},"Yes",[201,208,209],{},"No adversary crafting collisions",[183,211,212,215,217],{},[201,213,214],{},"Non-security checksums (deduplication, caching)",[201,216,206],{},[201,218,219],{},"Collisions extremely rare in practice",[183,221,222,225,228],{},[201,223,224],{},"Password storage",[201,226,227],{},"No",[201,229,230],{},"Rainbow tables and speed make it trivial",[183,232,233,236,238],{},[201,234,235],{},"Digital signatures",[201,237,227],{},[201,239,240],{},"Collision attacks forge signatures",[183,242,243,246,248],{},[201,244,245],{},"SSL\u002FTLS certificates",[201,247,227],{},[201,249,250],{},"Industry standards prohibit MD5",[183,252,253,256,259],{},[201,254,255],{},"Content-addressable storage",[201,257,258],{},"Risky",[201,260,261],{},"Dedicated attacker could create collisions",[10,263,265],{"id":264},"md5-vs-sha-256-practical-comparison","MD5 vs SHA-256: Practical Comparison",[177,267,268,281],{},[180,269,270],{},[183,271,272,275,278],{},[186,273,274],{},"Property",[186,276,277],{},"MD5",[186,279,280],{},"SHA-256",[196,282,283,297,310,323,336],{},[183,284,285,291,294],{},[201,286,287],{},[288,289,290],"strong",{},"Hash length",[201,292,293],{},"128 bits",[201,295,296],{},"256 bits",[183,298,299,304,307],{},[201,300,301],{},[288,302,303],{},"Collision resistance",[201,305,306],{},"Broken",[201,308,309],{},"No known attacks",[183,311,312,317,320],{},[201,313,314],{},[288,315,316],{},"Speed (Node.js)",[201,318,319],{},"~600 MB\u002Fs",[201,321,322],{},"~400 MB\u002Fs",[183,324,325,330,333],{},[201,326,327],{},[288,328,329],{},"Output size",[201,331,332],{},"32 hex chars",[201,334,335],{},"64 hex chars",[183,337,338,343,346],{},[201,339,340],{},[288,341,342],{},"NIST status",[201,344,345],{},"Deprecated",[201,347,348],{},"Approved",[15,350,351],{},"The speed difference is minor compared to the security gap. SHA-256 is the minimum recommended hash function for any security-sensitive application.",[10,353,355],{"id":354},"migrating-away-from-md5","Migrating Away from MD5",[26,357,359],{"id":358},"for-password-storage","For Password Storage",[15,361,362],{},"Migrate to Argon2id or bcrypt. These are purpose-built for passwords with built-in salting and adjustable work factors:",[41,364,368],{"className":365,"code":366,"language":367,"meta":50,"style":50},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F Instead of MD5\nconst crypto = require('crypto');\nconst hash = crypto.createHash('md5').update(password).digest('hex');\n\n\u002F\u002F Use bcrypt\nconst bcrypt = require('bcrypt');\nconst hash = await bcrypt.hash(password, 12); \u002F\u002F cost factor 12\n","javascript",[48,369,370,375,401,440,444,449,467],{"__ignoreMap":50},[69,371,372],{"class":71,"line":72},[69,373,374],{"class":75},"\u002F\u002F Instead of MD5\n",[69,376,377,381,385,388,391,395,398],{"class":71,"line":79},[69,378,380],{"class":379},"szBVR","const",[69,382,384],{"class":383},"sj4cs"," crypto",[69,386,387],{"class":379}," =",[69,389,390],{"class":88}," require",[69,392,394],{"class":393},"sVt8B","(",[69,396,397],{"class":92},"'crypto'",[69,399,400],{"class":393},");\n",[69,402,403,405,408,410,413,416,418,421,424,427,430,433,435,438],{"class":71,"line":85},[69,404,380],{"class":379},[69,406,407],{"class":383}," hash",[69,409,387],{"class":379},[69,411,412],{"class":393}," crypto.",[69,414,415],{"class":88},"createHash",[69,417,394],{"class":393},[69,419,420],{"class":92},"'md5'",[69,422,423],{"class":393},").",[69,425,426],{"class":88},"update",[69,428,429],{"class":393},"(password).",[69,431,432],{"class":88},"digest",[69,434,394],{"class":393},[69,436,437],{"class":92},"'hex'",[69,439,400],{"class":393},[69,441,442],{"class":71,"line":102},[69,443,123],{"emptyLinePlaceholder":122},[69,445,446],{"class":71,"line":111},[69,447,448],{"class":75},"\u002F\u002F Use bcrypt\n",[69,450,451,453,456,458,460,462,465],{"class":71,"line":119},[69,452,380],{"class":379},[69,454,455],{"class":383}," bcrypt",[69,457,387],{"class":379},[69,459,390],{"class":88},[69,461,394],{"class":393},[69,463,464],{"class":92},"'bcrypt'",[69,466,400],{"class":393},[69,468,469,471,473,475,478,481,484,487,490,493],{"class":71,"line":126},[69,470,380],{"class":379},[69,472,407],{"class":383},[69,474,387],{"class":379},[69,476,477],{"class":379}," await",[69,479,480],{"class":393}," bcrypt.",[69,482,483],{"class":88},"hash",[69,485,486],{"class":393},"(password, ",[69,488,489],{"class":383},"12",[69,491,492],{"class":393},"); ",[69,494,495],{"class":75},"\u002F\u002F cost factor 12\n",[26,497,499],{"id":498},"for-file-checksums","For File Checksums",[15,501,502],{},"Replace MD5 with SHA-256 for any verification where tampering is a concern:",[41,504,506],{"className":63,"code":505,"language":65,"meta":50,"style":50},"# Old\nmd5sum release.tar.gz\n\n# New\nsha256sum release.tar.gz\n",[48,507,508,513,521,525,530],{"__ignoreMap":50},[69,509,510],{"class":71,"line":72},[69,511,512],{"class":75},"# Old\n",[69,514,515,518],{"class":71,"line":79},[69,516,517],{"class":88},"md5sum",[69,519,520],{"class":92}," release.tar.gz\n",[69,522,523],{"class":71,"line":85},[69,524,123],{"emptyLinePlaceholder":122},[69,526,527],{"class":71,"line":102},[69,528,529],{"class":75},"# New\n",[69,531,532,535],{"class":71,"line":111},[69,533,534],{"class":88},"sha256sum",[69,536,520],{"class":92},[26,538,540],{"id":539},"for-legacy-systems","For Legacy Systems",[15,542,543],{},"If you cannot replace MD5 immediately, add a HMAC construction to strengthen it:",[41,545,547],{"className":365,"code":546,"language":367,"meta":50,"style":50},"const hmac = crypto.createHmac('sha256', secretKey);\nhmac.update(data);\nconst result = hmac.digest('hex');\n",[48,548,549,571,581],{"__ignoreMap":50},[69,550,551,553,556,558,560,563,565,568],{"class":71,"line":72},[69,552,380],{"class":379},[69,554,555],{"class":383}," hmac",[69,557,387],{"class":379},[69,559,412],{"class":393},[69,561,562],{"class":88},"createHmac",[69,564,394],{"class":393},[69,566,567],{"class":92},"'sha256'",[69,569,570],{"class":393},", secretKey);\n",[69,572,573,576,578],{"class":71,"line":79},[69,574,575],{"class":393},"hmac.",[69,577,426],{"class":88},[69,579,580],{"class":393},"(data);\n",[69,582,583,585,588,590,593,595,597,599],{"class":71,"line":85},[69,584,380],{"class":379},[69,586,587],{"class":383}," result",[69,589,387],{"class":379},[69,591,592],{"class":393}," hmac.",[69,594,432],{"class":88},[69,596,394],{"class":393},[69,598,437],{"class":92},[69,600,400],{"class":393},[10,602,604],{"id":603},"key-takeaways","Key Takeaways",[606,607,608,612,615,618,621,624],"ul",{},[609,610,611],"li",{},"MD5 collision attacks are practical and take under a second on modern hardware",[609,613,614],{},"Preimage attacks against MD5 remain theoretical but the margin is shrinking",[609,616,617],{},"MD5 is safe for non-adversarial checksums like accidental corruption detection",[609,619,620],{},"Never use MD5 for password storage, digital signatures, or certificates",[609,622,623],{},"SHA-256 is the minimum standard for security-sensitive hashing",[609,625,626],{},"For passwords specifically, use Argon2id or bcrypt instead of any general-purpose hash",[10,628,630],{"id":629},"try-it-yourself","Try It Yourself",[15,632,633,634,639],{},"Compare MD5 and SHA-256 side by side with our free ",[635,636,638],"a",{"href":637},"\u002Ftools\u002Fhash-calculator","Hash Calculator",". Enter any text to see both hash outputs instantly — all processing happens locally in your browser, so your data stays private.",[15,641,642],{},[635,643,644],{"href":637},"Try the Hash Calculator →",[646,647,648],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":50,"searchDepth":79,"depth":79,"links":650},[651,652,657,661,662,663,668,669],{"id":12,"depth":79,"text":13},{"id":23,"depth":79,"text":24,"children":653},[654,655,656],{"id":28,"depth":85,"text":29},{"id":35,"depth":85,"text":36},{"id":56,"depth":85,"text":57},{"id":150,"depth":79,"text":151,"children":658},[659,660],{"id":157,"depth":85,"text":158},{"id":164,"depth":85,"text":165},{"id":171,"depth":79,"text":172},{"id":264,"depth":79,"text":265},{"id":354,"depth":79,"text":355,"children":664},[665,666,667],{"id":358,"depth":85,"text":359},{"id":498,"depth":85,"text":499},{"id":539,"depth":85,"text":540},{"id":603,"depth":79,"text":604},{"id":629,"depth":79,"text":630},"2026-05-28","Understand why MD5 is no longer secure. Learn about collision attacks, preimage attacks, and when MD5 is still safe to use.","md",{"immutable":122},"\u002Fguides\u002Fmd5-security-vulnerabilities",{"title":5,"description":671},"guides\u002Fmd5-security-vulnerabilities","kmgasjIKCqL5iC-i8cPRBOW9akG0PuRlyImTBwjMGTE",1780401335280]