Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
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
AI時代のPHPer生存戦略 ~「言語、もうなんでもよくない?」に本気で向き合う~
vivion
0
300
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
590
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
210
仕様書を書く前にハーネスを作る - Agent Native開発は「探索を速く、判定を固く」
gotalab555
4
1.6k
AI時代、エンジニアはどう育つのか -未経験エンジニアの成長を間近で見て考えたこと-
thasu0123
0
220
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
140
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
150
React本体のコードリーディング
high_g_engineer
1
140
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
480
メールのエイリアス機能を履き違えない
isshinfunada
0
230
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.8k
プロポーザルを書いてもらう
pvcresin
0
280
Featured
See All Featured
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
170
Measuring & Analyzing Core Web Vitals
bluesmoon
9
950
Ruling the World: When Life Gets Gamed
codingconduct
0
290
Making the Leap to Tech Lead
cromwellryan
135
10k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
360
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
230
Believing is Seeing
oripsolob
1
180
Designing for Performance
lara
611
70k
Prompt Engineering for Job Search
mfonobong
0
400
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
360
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
Six Lessons from altMBA
skipperchong
29
4.4k
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