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