git ssb

0+

dangerousbeans / %aPBe2k3ugtjBr4rrsU1…



Tree: a1c41622dfe104ad5b01768ae941647bf9b96a69

Files: a1c41622dfe104ad5b01768ae941647bf9b96a69 / ext / jruby / BCrypt.java

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

Built with git-ssb-web