Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
80,000 Plaintext Passwords: An Open Source Love...
Search
T.J. Schuck
June 26, 2014
Programming
1.2k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
80,000 Plaintext Passwords: An Open Source Love Story in Three Acts
T.J. Schuck
June 26, 2014
Other Decks in Programming
See All in Programming
Foundry Localでエージェント開発
seosoft
0
180
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
140
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
300
Building an Out-of-Order CPU
latte72
1
750
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
5
1.5k
Swift愛好会と私(ウホーイ) / Swift Fan Club and Uhooi
uhooi
0
150
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
700
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
6.2k
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
210
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
2.7k
Jetpack Compose メカニズム
skydoves
0
110
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
140
Featured
See All Featured
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
430
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
410
Designing for Performance
lara
611
70k
Building Adaptive Systems
keathley
44
3.2k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
The Invisible Side of Design
smashingmag
301
52k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
67
58k
30 Presentation Tips
portentint
PRO
1
390
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
Transcript
80,000 Plaintext Passwords @tjschuck
Act I
mallory@local$ ′
None
T.J. Schuck @tjschuck
HARVEST getHarvest.com
I am not a Security Expert™
mallory@local$ ′
Layers Layers Layers Layers
mallory@local$ perl haxor.pl ′
mallory@local$ perl haxor.pl ! +------+-----------------------+------------+ | id | email |
password | +------+-----------------------+------------+ | 6125 |
[email protected]
| honeyd | | 6126 |
[email protected]
| blowfish | | 6127 |
[email protected]
| peppercorn | | 6128 |
[email protected]
| md1947 | +------+-----------------------+------------+
“But…”
mallory@local$ perl haxor.pl ! +------+-----------------------+------------+ | id | email |
password | +------+-----------------------+------------+ | 6125 |
[email protected]
| honeyd | | 6126 |
[email protected]
| blowfish | | 6127 |
[email protected]
| peppercorn | | 6128 |
[email protected]
| md1947 | +------+-----------------------+------------+
mallory@local$ perl haxor.pl ! +------+-----------------------+------------+ | id | email |
password | +------+-----------------------+------------+ | 6125 |
[email protected]
| ubarlq | | 6126 |
[email protected]
| oybjsvfu | | 6127 |
[email protected]
| crccrepbea | | 6128 |
[email protected]
| zq1947 | +------+-----------------------+------------+
Encryption is reversible
Hashing is irreversible
None
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘secret1234’) => bdfc2db0aa599f5919e565c328216a51
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘secret1234’) => bdfc2db0aa599f5919e565c328216a51 => 18ad6448e70b7b0254cad4d77653f2d7
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘secret1234’) => bdfc2db0aa599f5919e565c328216a51 => 18ad6448e70b7b0254cad4d77653f2d7 ?
Hashing is deterministic
None
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f
Hashing is deterministic (but not obvious)
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f !
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f ! hash(‘Peppercorn’) => b8bfa4f1b72ee60755a71dbdf0700fe9
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f ! hash(‘Peppercorn’) => b8bfa4f1b72ee60755a71dbdf0700fe9
=> b8bfa4f1b72ee60755a71dbdf0700fe8
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f ! hash(‘Peppercorn’) => b8bfa4f1b72ee60755a71dbdf0700fe9
=> b8bfa4f1b72ee60755a71dbdf0700fe8 ?
mallory@local$ perl haxor.pl ! +------+-----------------------+----------------------------------+ | id | email |
password | +------+-----------------------+----------------------------------+ | 6125 |
[email protected]
| 6ee717a4bc91d99170ce0d0922ab6c43 | | 6126 |
[email protected]
| b258a419ddbc13d92b8e7fc25c2b9d6c | | 6127 |
[email protected]
| 6a58d0ad2619df7d7fabc2603b79063f | | 6128 |
[email protected]
| 0304432f4c8080781f1b210c6b92b12f | +------+-----------------------+----------------------------------+
Hashing is deterministic
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f
None
Rainbow Tables
mallory@local$ perl haxor.pl ! +------+-----------------------+----------------------------------+ | id | email |
password | +------+-----------------------+----------------------------------+ | 6125 |
[email protected]
| 6ee717a4bc91d99170ce0d0922ab6c43 | | 6126 |
[email protected]
| b258a419ddbc13d92b8e7fc25c2b9d6c | | 6127 |
[email protected]
| 6a58d0ad2619df7d7fabc2603b79063f | | 6128 |
[email protected]
| 0304432f4c8080781f1b210c6b92b12f | +------+-----------------------+----------------------------------+
None
6a58d0ad2619df7d7fabc2603b79063f
None
None
Defeating the Rainbow
hash(‘peppercorn’) => 6a58d0ad2619df7d7fabc2603b79063f
hash(‘peppercorn-tc5gplQopZ617zRQ8h9pAg’) => c5dde1b5cc0e6d89bda0f5e350bda319
None
WE DID IT!
(no we didn’t)
Proof of Concept
peppercorn
pepper8 pepper83 pepper88 pepper99 ! pepperdog pepperi1 peppermint peppermint1 pepperoni
pepperpepper peppers peppers4 peppi123 peppone pepsi pepsi1 pepsi123 pepsi2006 pepsi5 pepsi78bottle pepsicat pepsico pepsii pepsimax pepsione pepsis12 pequot per12fect peralta1 peppercorn
un1v3r53 1q2w#E$R fkg7h4f3v6
SALTING
SALTING
hash(‘peppercorn-tc5gplQopZ617zRQ8h9pAg’) => c5dde1b5cc0e6d89bda0f5e350bda319 hash(‘peppercorn-R1XrmmZVRedKMTE9nlIy9Q’) => fc5ad4a64796506086424af78f57df9d
mallory@local$ perl haxor.pl ! +------+----------------------------------+------------------------+ | id | password |
salt | +------+----------------------------------+------------------------+ | 6125 | 5b5f47a49cdd4386611ee0a63577eccd | CeVDwwrT7saa_cY2rV_qng | | 6126 | a50f4854739e10773c99d5576dbb2f73 | rRWjkN4ioELXIPpQ6aDY4w | | 6127 | 94c91484c8bb05113b28f9da2b7ea624 | XvALmgae9uUGmpikd8sohg | | 6128 | 5d2ee837249e9340624b12e653c5e4a3 | D-ZUYoaSadkCze1fPibbgg | +------+----------------------------------+------------------------+
This is pretty good…
This is pretty good… for 1976.
None
None
None
None
bcrypt ✓ One-way hash ✓ Pre-image resistant ✓ Deterministic ✓
Built-in per-password salts
Eksblowfish
Adaptive Cost
mallory@local$ perl haxor.pl ! +-----------------------+--------------------------------------------------------------+ | email | password |
+-----------------------+--------------------------------------------------------------+ |
[email protected]
| $2a$10$1ObnU/cPb3AjVU5iu8ntfe77xO83roRhoJMyBqYhlq5ZMMbHCcELK | |
[email protected]
| $2a$10$CelbCnmBjJez5ego4w.mbusfnZGOn/lRhLjrr37R0iUCr1UIC6ZyC | |
[email protected]
| | |
[email protected]
| $2a$10$9WLufYmucbh.yaTHKKUuUeihbcA3hBUiI.XiW7ygmaYcYXtl4MBKy | +-----------------------+--------------------------------------------------------------+ $ 2a 10 LrfFlMh6Yc7JWKlpRwVjUuPCOPU5574fXAVrvLZRFT87cT55oLBEe $ $
$ 2a 10 LrfFlMh6Yc7JWKlpRwVjUuPCOPU5574fXAVrvLZRFT87cT55oLBEe $ $
$ 2a 10 LrfFlMh6Yc7JWKlpRwVjUu PCOPU5574fXAVrvLZRFT87cT55oLBEe $ $
$ 2a 10 LrfFlMh6Yc7JWKlpRwVjUu PCOPU5574fXAVrvLZRFT87cT55oLBEe $ $
$ 2a 10 LrfFlMh6Yc7JWKlpRwVjUu PCOPU5574fXAVrvLZRFT87cT55oLBEe $ $
$ 2a 10 LrfFlMh6Yc7JWKlpRwVjUu PCOPU5574fXAVrvLZRFT87cT55oLBEe $ $
$ 2a 10 LrfFlMh6Yc7JWKlpRwVjUu PCOPU5574fXAVrvLZRFT87cT55oLBEe $ $
$ 2a 10 LrfFlMh6Yc7JWKlpRwVjUu PCOPU5574fXAVrvLZRFT87cT55oLBEe $ $ “Cost”
None
bcrypt(‘peppercorn’, 10) =>
bcrypt(‘peppercorn’, 10) => $2a$10$41JmpddjOSEGWU099uQx7O7Y1EiQMTRQFZCcFqFMlYWekR5pj9xFi
bcrypt(‘peppercorn’, 10) => $2a$10$41JmpddjOSEGWU099uQx7O7Y1EiQMTRQFZCcFqFMlYWekR5pj9xFi bcrypt(‘peppercorn’, 10) =>
bcrypt(‘peppercorn’, 10) => $2a$10$41JmpddjOSEGWU099uQx7O7Y1EiQMTRQFZCcFqFMlYWekR5pj9xFi bcrypt(‘peppercorn’, 10) => $2a$10$8ONmT2oiKPoPn/KQTrvHq.gWTnqQ5p.T13lw.lCm9d.QoqIZzbHPS
bcrypt(‘peppercorn’, 10) => $2a$10$41JmpddjOSEGWU099uQx7O7Y1EiQMTRQFZCcFqFMlYWekR5pj9xFi bcrypt(‘peppercorn’, 10) => $2a$10$8ONmT2oiKPoPn/KQTrvHq.gWTnqQ5p.T13lw.lCm9d.QoqIZzbHPS bcrypt(‘peppercorn’, 14)
=>
bcrypt(‘peppercorn’, 10) => $2a$10$41JmpddjOSEGWU099uQx7O7Y1EiQMTRQFZCcFqFMlYWekR5pj9xFi bcrypt(‘peppercorn’, 10) => $2a$10$8ONmT2oiKPoPn/KQTrvHq.gWTnqQ5p.T13lw.lCm9d.QoqIZzbHPS bcrypt(‘peppercorn’, 14)
=> $2a$14$4US.NV/qyRkctl.LaYvNzOln70yIaqGfJeMq1deb/bPJMMmtcxOU.
bcrypt(‘peppercorn’, 10) => $2a$10$41JmpddjOSEGWU099uQx7O7Y1EiQMTRQFZCcFqFMlYWekR5pj9xFi bcrypt(‘peppercorn’, 10) => $2a$10$8ONmT2oiKPoPn/KQTrvHq.gWTnqQ5p.T13lw.lCm9d.QoqIZzbHPS bcrypt(‘peppercorn’, 14)
=> $2a$14$4US.NV/qyRkctl.LaYvNzOln70yIaqGfJeMq1deb/bPJMMmtcxOU.
bcrypt(‘peppercorn’, 10) => $2a$10$41JmpddjOSEGWU099uQx7O7Y1EiQMTRQFZCcFqFMlYWekR5pj9xFi bcrypt(‘peppercorn’, 10) => $2a$10$8ONmT2oiKPoPn/KQTrvHq.gWTnqQ5p.T13lw.lCm9d.QoqIZzbHPS bcrypt(‘peppercorn’, 14)
=> $2a$14$4US.NV/qyRkctl.LaYvNzOln70yIaqGfJeMq1deb/bPJMMmtcxOU. 0.0656 seconds
bcrypt(‘peppercorn’, 10) => $2a$10$41JmpddjOSEGWU099uQx7O7Y1EiQMTRQFZCcFqFMlYWekR5pj9xFi bcrypt(‘peppercorn’, 10) => $2a$10$8ONmT2oiKPoPn/KQTrvHq.gWTnqQ5p.T13lw.lCm9d.QoqIZzbHPS bcrypt(‘peppercorn’, 14)
=> $2a$14$4US.NV/qyRkctl.LaYvNzOln70yIaqGfJeMq1deb/bPJMMmtcxOU. 0.0656 seconds 0.0657 seconds
bcrypt(‘peppercorn’, 10) => $2a$10$41JmpddjOSEGWU099uQx7O7Y1EiQMTRQFZCcFqFMlYWekR5pj9xFi bcrypt(‘peppercorn’, 10) => $2a$10$8ONmT2oiKPoPn/KQTrvHq.gWTnqQ5p.T13lw.lCm9d.QoqIZzbHPS bcrypt(‘peppercorn’, 14)
=> $2a$14$4US.NV/qyRkctl.LaYvNzOln70yIaqGfJeMq1deb/bPJMMmtcxOU. 0.0656 seconds 0.0657 seconds 1.0481 seconds
Cost Seconds 9 0.0344 10 0.0656 11 0.1333 12 0.2646
13 0.5236 14 1.0481 15 2.1645 16 4.2801
“Well, actually…”
The Fix
def authenticate(plaintext_password)! if old_hashing_method(plaintext_password) == password_digest! self! end! end
def authenticate(plaintext_password)! if BCrypt::Password.new(password_digest) == plaintext_password! self! end! end
def authenticate(plaintext_password)! return unless convert_old_hash_to_bcrypt(plaintext_password)! ! if BCrypt::Password.new(password_digest) == plaintext_password!
self! end! end
def convert_old_hash_to_bcrypt(plaintext_password)! return true if BCrypt::Password.valid_hash?(password_digest)! ! if old_hashing_method(plaintext_password) ==
password_digest! update_column :password_digest,! BCrypt::Password.create(plaintext_password)! end! end
None
None
None
—Act II—
Fat Binary Gems —Act II— You make the rockin’ world
go ’round
bcrypt-ruby github.com/codahale/bcrypt-ruby
None
None
None
None
None
None
None
None
None
None
None
None
None
None
Well shit.
None
None
rake-compiler-dev-box with Rubies, GCC, JDK, MinGW…
None
LOLOLOLOL NO.
None
rake-compiler#79
Act III
Act III Luis Lavena
None
• One-Click Ruby Installer for Windows
• One-Click Ruby Installer for Windows • Ruby core
• One-Click Ruby Installer for Windows • Ruby core •
Ruby Hero (2010)
• One-Click Ruby Installer for Windows • Ruby core •
Ruby Hero (2010) • rake-compiler
rake-compiler-dev-box#2
None
None
None
None
None
@luislavena <3 <3 <3
Find your Luis
“Be the Luis you wish to see in the world”
What have we learned?
1. Just use bcrypt
2. Distribute a dev box
3. Release, collaborate, iterate
Thank You @tjschuck getHarvest.com