- cfpassphrase/src/org/mindrot/jbcrypt/BCrypt.java
- master
- 27 KB
- 777
1// Copyright (c) 2006 Damien Miller <djm@mindrot.org>
2//
3// Permission to use, copy, modify, and distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15package org.mindrot.jbcrypt;
16
17import java.io.UnsupportedEncodingException;
18import java.security.SecureRandom;
19
20/**
21 * BCrypt implements OpenBSD-style Blowfish password hashing using
22 * the scheme described in "A Future-Adaptable Password Scheme" by
23 * Niels Provos and David Mazieres.
24 * <p>
25 * This password hashing system tries to thwart off-line password
26 * cracking using a computationally-intensive hashing algorithm,
27 * based on Bruce Schneier's Blowfish cipher. The work factor of
28 * the algorithm is parameterised, so it can be increased as
29 * computers get faster.
30 * <p>
31 * Usage is really simple. To hash a password for the first time,
32 * call the hashpw method with a random salt, like this:
33 * <p>
34 * <code>
35 * String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt()); <br />
36 * </code>
37 * <p>
38 * To check whether a plaintext password matches one that has been
39 * hashed previously, use the checkpw method:
40 * <p>
41 * <code>
42 * if (BCrypt.checkpw(candidate_password, stored_hash))<br />
43 * System.out.println("It matches");<br />
44 * else<br />
45 * System.out.println("It does not match");<br />
46 * </code>
47 * <p>
48 * The gensalt() method takes an optional parameter (log_rounds)
49 * that determines the computational complexity of the hashing:
50 * <p>
51 * <code>
52 * String strong_salt = BCrypt.gensalt(10)<br />
53 * String stronger_salt = BCrypt.gensalt(12)<br />
54 * </code>
55 * <p>
56 * The amount of work increases exponentially (2**log_rounds), so
57 * each increment is twice as much work. The default log_rounds is
58 * 10, and the valid range is 4 to 30.
59 *
60 * @author Damien Miller
61 * @version 0.2
62 */
63public class BCrypt {
64 // BCrypt parameters
65 private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10;
66 private static final int BCRYPT_SALT_LEN = 16;
67
68 // Blowfish parameters
69 private static final int BLOWFISH_NUM_ROUNDS = 16;
70
71 // Initial contents of key schedule
72 private static final int P_orig[] = {
73 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
74 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
75 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
76 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
77 0x9216d5d9, 0x8979fb1b
78 };
79 private static final int S_orig[] = {
80 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
81 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
82 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
83 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
84 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
85 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
86 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
87 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
88 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
89 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
90 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
91 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
92 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
93 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
94 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
95 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
96 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
97 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
98 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
99 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
100 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
101 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
102 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
103 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
104 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
105 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
106 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
107 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
108 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
109 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
110 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
111 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
112 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
113 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
114 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
115 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
116 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
117 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
118 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
119 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
120 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
121 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
122 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
123 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
124 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
125 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
126 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
127 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
128 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
129 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
130 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
131 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
132 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
133 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
134 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
135 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
136 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
137 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
138 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
139 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
140 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
141 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
142 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
143 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
144 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
145 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
146 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
147 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
148 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
149 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
150 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
151 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
152 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
153 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
154 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
155 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
156 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
157 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
158 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
159 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
160 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
161 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
162 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
163 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
164 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
165 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
166 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
167 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
168 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
169 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
170 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
171 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
172 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
173 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
174 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
175 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
176 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
177 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
178 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
179 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
180 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
181 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
182 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
183 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
184 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
185 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
186 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
187 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
188 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
189 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
190 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
191 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
192 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
193 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
194 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
195 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
196 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
197 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
198 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
199 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
200 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
201 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
202 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
203 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
204 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
205 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
206 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
207 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
208 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
209 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
210 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
211 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
212 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
213 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
214 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
215 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
216 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
217 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
218 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
219 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
220 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
221 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
222 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
223 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
224 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
225 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
226 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
227 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
228 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
229 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
230 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
231 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
232 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
233 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
234 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
235 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
236 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
237 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
238 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
239 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
240 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
241 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
242 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
243 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
244 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
245 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
246 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
247 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
248 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
249 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
250 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
251 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
252 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
253 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
254 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
255 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
256 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
257 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
258 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
259 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
260 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
261 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
262 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
263 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
264 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
265 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
266 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
267 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
268 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
269 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
270 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
271 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
272 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
273 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
274 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
275 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
276 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
277 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
278 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
279 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
280 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
281 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
282 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
283 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
284 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
285 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
286 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
287 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
288 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
289 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
290 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
291 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
292 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
293 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
294 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
295 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
296 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
297 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
298 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
299 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
300 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
301 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
302 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
303 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
304 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
305 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
306 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
307 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
308 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
309 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
310 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
311 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
312 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
313 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
314 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
315 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
316 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
317 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
318 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
319 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
320 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
321 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
322 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
323 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
324 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
325 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
326 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
327 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
328 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
329 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
330 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
331 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
332 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
333 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
334 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
335 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
336 };
337
338 // bcrypt IV: "OrpheanBeholderScryDoubt". The C implementation calls
339 // this "ciphertext", but it is really plaintext or an IV. We keep
340 // the name to make code comparison easier.
341 static private final int bf_crypt_ciphertext[] = {
342 0x4f727068, 0x65616e42, 0x65686f6c,
343 0x64657253, 0x63727944, 0x6f756274
344 };
345
346 // Table for Base64 encoding
347 static private final char base64_code[] = {
348 '.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
349 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
350 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
351 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
352 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
353 '6', '7', '8', '9'
354 };
355
356 // Table for Base64 decoding
357 static private final byte index_64[] = {
358 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
359 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
360 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
361 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
362 -1, -1, -1, -1, -1, -1, 0, 1, 54, 55,
363 56, 57, 58, 59, 60, 61, 62, 63, -1, -1,
364 -1, -1, -1, -1, -1, 2, 3, 4, 5, 6,
365 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
366 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
367 -1, -1, -1, -1, -1, -1, 28, 29, 30,
368 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
369 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
370 51, 52, 53, -1, -1, -1, -1, -1
371 };
372
373 // Expanded Blowfish key
374 private int P[];
375 private int S[];
376
377 /**
378 * Encode a byte array using bcrypt's slightly-modified base64
379 * encoding scheme. Note that this is *not* compatible with
380 * the standard MIME-base64 encoding.
381 *
382 * @param d the byte array to encode
383 * @param len the number of bytes to encode
384 * @return base64-encoded string
385 * @exception IllegalArgumentException if the length is invalid
386 */
387 private static String encode_base64(byte d[], int len)
388 throws IllegalArgumentException {
389 int off = 0;
390 StringBuffer rs = new StringBuffer();
391 int c1, c2;
392
393 if (len <= 0 || len > d.length)
394 throw new IllegalArgumentException ("Invalid len");
395
396 while (off < len) {
397 c1 = d[off++] & 0xff;
398 rs.append(base64_code[(c1 >> 2) & 0x3f]);
399 c1 = (c1 & 0x03) << 4;
400 if (off >= len) {
401 rs.append(base64_code[c1 & 0x3f]);
402 break;
403 }
404 c2 = d[off++] & 0xff;
405 c1 |= (c2 >> 4) & 0x0f;
406 rs.append(base64_code[c1 & 0x3f]);
407 c1 = (c2 & 0x0f) << 2;
408 if (off >= len) {
409 rs.append(base64_code[c1 & 0x3f]);
410 break;
411 }
412 c2 = d[off++] & 0xff;
413 c1 |= (c2 >> 6) & 0x03;
414 rs.append(base64_code[c1 & 0x3f]);
415 rs.append(base64_code[c2 & 0x3f]);
416 }
417 return rs.toString();
418 }
419
420 /**
421 * Look up the 3 bits base64-encoded by the specified character,
422 * range-checking againt conversion table
423 * @param x the base64-encoded value
424 * @return the decoded value of x
425 */
426 private static byte char64(char x) {
427 if ((int)x < 0 || (int)x > index_64.length)
428 return -1;
429 return index_64[(int)x];
430 }
431
432 /**
433 * Decode a string encoded using bcrypt's base64 scheme to a
434 * byte array. Note that this is *not* compatible with
435 * the standard MIME-base64 encoding.
436 * @param s the string to decode
437 * @param maxolen the maximum number of bytes to decode
438 * @return an array containing the decoded bytes
439 * @throws IllegalArgumentException if maxolen is invalid
440 */
441 private static byte[] decode_base64(String s, int maxolen)
442 throws IllegalArgumentException {
443 StringBuffer rs = new StringBuffer();
444 int off = 0, slen = s.length(), olen = 0;
445 byte ret[];
446 byte c1, c2, c3, c4, o;
447
448 if (maxolen <= 0)
449 throw new IllegalArgumentException ("Invalid maxolen");
450
451 while (off < slen - 1 && olen < maxolen) {
452 c1 = char64(s.charAt(off++));
453 c2 = char64(s.charAt(off++));
454 if (c1 == -1 || c2 == -1)
455 break;
456 o = (byte)(c1 << 2);
457 o |= (c2 & 0x30) >> 4;
458 rs.append((char)o);
459 if (++olen >= maxolen || off >= slen)
460 break;
461 c3 = char64(s.charAt(off++));
462 if (c3 == -1)
463 break;
464 o = (byte)((c2 & 0x0f) << 4);
465 o |= (c3 & 0x3c) >> 2;
466 rs.append((char)o);
467 if (++olen >= maxolen || off >= slen)
468 break;
469 c4 = char64(s.charAt(off++));
470 o = (byte)((c3 & 0x03) << 6);
471 o |= c4;
472 rs.append((char)o);
473 ++olen;
474 }
475
476 ret = new byte[olen];
477 for (off = 0; off < olen; off++)
478 ret[off] = (byte)rs.charAt(off);
479 return ret;
480 }
481
482 /**
483 * Blowfish encipher a single 64-bit block encoded as
484 * two 32-bit halves
485 * @param lr an array containing the two 32-bit half blocks
486 * @param off the position in the array of the blocks
487 */
488 private final void encipher(int lr[], int off) {
489 int i, n, l = lr[off], r = lr[off + 1];
490
491 l ^= P[0];
492 for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) {
493 // Feistel substitution on left word
494 n = S[(l >> 24) & 0xff];
495 n += S[0x100 | ((l >> 16) & 0xff)];
496 n ^= S[0x200 | ((l >> 8) & 0xff)];
497 n += S[0x300 | (l & 0xff)];
498 r ^= n ^ P[++i];
499
500 // Feistel substitution on right word
501 n = S[(r >> 24) & 0xff];
502 n += S[0x100 | ((r >> 16) & 0xff)];
503 n ^= S[0x200 | ((r >> 8) & 0xff)];
504 n += S[0x300 | (r & 0xff)];
505 l ^= n ^ P[++i];
506 }
507 lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1];
508 lr[off + 1] = l;
509 }
510
511 /**
512 * Cycically extract a word of key material
513 * @param data the string to extract the data from
514 * @param offp a "pointer" (as a one-entry array) to the
515 * current offset into data
516 * @return the next word of material from data
517 */
518 private static int streamtoword(byte data[], int offp[]) {
519 int i;
520 int word = 0;
521 int off = offp[0];
522
523 for (i = 0; i < 4; i++) {
524 word = (word << 8) | (data[off] & 0xff);
525 off = (off + 1) % data.length;
526 }
527
528 offp[0] = off;
529 return word;
530 }
531
532 /**
533 * Initialise the Blowfish key schedule
534 */
535 private void init_key() {
536 P = (int[])P_orig.clone();
537 S = (int[])S_orig.clone();
538 }
539
540 /**
541 * Key the Blowfish cipher
542 * @param key an array containing the key
543 */
544 private void key(byte key[]) {
545 int i;
546 int koffp[] = { 0 };
547 int lr[] = { 0, 0 };
548 int plen = P.length, slen = S.length;
549
550 for (i = 0; i < plen; i++)
551 P[i] = P[i] ^ streamtoword(key, koffp);
552
553 for (i = 0; i < plen; i += 2) {
554 encipher(lr, 0);
555 P[i] = lr[0];
556 P[i + 1] = lr[1];
557 }
558
559 for (i = 0; i < slen; i += 2) {
560 encipher(lr, 0);
561 S[i] = lr[0];
562 S[i + 1] = lr[1];
563 }
564 }
565
566 /**
567 * Perform the "enhanced key schedule" step described by
568 * Provos and Mazieres in "A Future-Adaptable Password Scheme"
569 * http://www.openbsd.org/papers/bcrypt-paper.ps
570 * @param data salt information
571 * @param key password information
572 */
573 private void ekskey(byte data[], byte key[]) {
574 int i;
575 int koffp[] = { 0 }, doffp[] = { 0 };
576 int lr[] = { 0, 0 };
577 int plen = P.length, slen = S.length;
578
579 for (i = 0; i < plen; i++)
580 P[i] = P[i] ^ streamtoword(key, koffp);
581
582 for (i = 0; i < plen; i += 2) {
583 lr[0] ^= streamtoword(data, doffp);
584 lr[1] ^= streamtoword(data, doffp);
585 encipher(lr, 0);
586 P[i] = lr[0];
587 P[i + 1] = lr[1];
588 }
589
590 for (i = 0; i < slen; i += 2) {
591 lr[0] ^= streamtoword(data, doffp);
592 lr[1] ^= streamtoword(data, doffp);
593 encipher(lr, 0);
594 S[i] = lr[0];
595 S[i + 1] = lr[1];
596 }
597 }
598
599 /**
600 * Perform the central password hashing step in the
601 * bcrypt scheme
602 * @param password the password to hash
603 * @param salt the binary salt to hash with the password
604 * @param log_rounds the binary logarithm of the number
605 * of rounds of hashing to apply
606 * @param cdata the plaintext to encrypt
607 * @return an array containing the binary hashed password
608 */
609 public byte[] crypt_raw(byte password[], byte salt[], int log_rounds,
610 int cdata[]) {
611 int rounds, i, j;
612 int clen = cdata.length;
613 byte ret[];
614
615 if (log_rounds < 4 || log_rounds > 30)
616 throw new IllegalArgumentException ("Bad number of rounds");
617 rounds = 1 << log_rounds;
618 if (salt.length != BCRYPT_SALT_LEN)
619 throw new IllegalArgumentException ("Bad salt length");
620
621 init_key();
622 ekskey(salt, password);
623 for (i = 0; i != rounds; i++) {
624 key(password);
625 key(salt);
626 }
627
628 for (i = 0; i < 64; i++) {
629 for (j = 0; j < (clen >> 1); j++)
630 encipher(cdata, j << 1);
631 }
632
633 ret = new byte[clen * 4];
634 for (i = 0, j = 0; i < clen; i++) {
635 ret[j++] = (byte)((cdata[i] >> 24) & 0xff);
636 ret[j++] = (byte)((cdata[i] >> 16) & 0xff);
637 ret[j++] = (byte)((cdata[i] >> 8) & 0xff);
638 ret[j++] = (byte)(cdata[i] & 0xff);
639 }
640 return ret;
641 }
642
643 /**
644 * Hash a password using the OpenBSD bcrypt scheme
645 * @param password the password to hash
646 * @param salt the salt to hash with (perhaps generated
647 * using BCrypt.gensalt)
648 * @return the hashed password
649 */
650 public static String hashpw(String password, String salt) {
651 BCrypt B;
652 String real_salt;
653 byte passwordb[], saltb[], hashed[];
654 char minor = (char)0;
655 int rounds, off = 0;
656 StringBuffer rs = new StringBuffer();
657
658 if (salt.charAt(0) != '$' || salt.charAt(1) != '2')
659 throw new IllegalArgumentException ("Invalid salt version");
660 if (salt.charAt(2) == '$')
661 off = 3;
662 else {
663 minor = salt.charAt(2);
664 if (minor != 'a' || salt.charAt(3) != '$')
665 throw new IllegalArgumentException ("Invalid salt revision");
666 off = 4;
667 }
668
669 // Extract number of rounds
670 if (salt.charAt(off + 2) > '$')
671 throw new IllegalArgumentException ("Missing salt rounds");
672 rounds = Integer.parseInt(salt.substring(off, off + 2));
673
674 real_salt = salt.substring(off + 3, off + 25);
675 try {
676 passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8");
677 } catch (UnsupportedEncodingException uee) {
678 throw new AssertionError("UTF-8 is not supported");
679 }
680
681 saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);
682
683 B = new BCrypt();
684 hashed = B.crypt_raw(passwordb, saltb, rounds,
685 (int[])bf_crypt_ciphertext.clone());
686
687 rs.append("$2");
688 if (minor >= 'a')
689 rs.append(minor);
690 rs.append("$");
691 if (rounds < 10)
692 rs.append("0");
693 if (rounds > 30) {
694 throw new IllegalArgumentException(
695 "rounds exceeds maximum (30)");
696 }
697 rs.append(Integer.toString(rounds));
698 rs.append("$");
699 rs.append(encode_base64(saltb, saltb.length));
700 rs.append(encode_base64(hashed,
701 bf_crypt_ciphertext.length * 4 - 1));
702 return rs.toString();
703 }
704
705 /**
706 * Generate a salt for use with the BCrypt.hashpw() method
707 * @param log_rounds the log2 of the number of rounds of
708 * hashing to apply - the work factor therefore increases as
709 * 2**log_rounds.
710 * @param random an instance of SecureRandom to use
711 * @return an encoded salt value
712 */
713 public static String gensalt(int log_rounds, SecureRandom random) {
714 StringBuffer rs = new StringBuffer();
715 byte rnd[] = new byte[BCRYPT_SALT_LEN];
716
717 random.nextBytes(rnd);
718
719 rs.append("$2a$");
720 if (log_rounds < 10)
721 rs.append("0");
722 if (log_rounds > 30) {
723 throw new IllegalArgumentException(
724 "log_rounds exceeds maximum (30)");
725 }
726 rs.append(Integer.toString(log_rounds));
727 rs.append("$");
728 rs.append(encode_base64(rnd, rnd.length));
729 return rs.toString();
730 }
731
732 /**
733 * Generate a salt for use with the BCrypt.hashpw() method
734 * @param log_rounds the log2 of the number of rounds of
735 * hashing to apply - the work factor therefore increases as
736 * 2**log_rounds.
737 * @return an encoded salt value
738 */
739 public static String gensalt(int log_rounds) {
740 return gensalt(log_rounds, new SecureRandom());
741 }
742
743 /**
744 * Generate a salt for use with the BCrypt.hashpw() method,
745 * selecting a reasonable default for the number of hashing
746 * rounds to apply
747 * @return an encoded salt value
748 */
749 public static String gensalt() {
750 return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS);
751 }
752
753 /**
754 * Check that a plaintext password matches a previously hashed
755 * one
756 * @param plaintext the plaintext password to verify
757 * @param hashed the previously-hashed password
758 * @return true if the passwords match, false otherwise
759 */
760 public static boolean checkpw(String plaintext, String hashed) {
761 byte hashed_bytes[];
762 byte try_bytes[];
763 try {
764 String try_pw = hashpw(plaintext, hashed);
765 hashed_bytes = hashed.getBytes("UTF-8");
766 try_bytes = try_pw.getBytes("UTF-8");
767 } catch (UnsupportedEncodingException uee) {
768 return false;
769 }
770 if (hashed_bytes.length != try_bytes.length)
771 return false;
772 byte ret = 0;
773 for (int i = 0; i < try_bytes.length; i++)
774 ret |= hashed_bytes[i] ^ try_bytes[i];
775 return ret == 0;
776 }
777}