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