001//Copyright (c) 2006 Damien Miller <djm@mindrot.org>
002//
003//Permission to use, copy, modify, and distribute this software for any
004//purpose with or without fee is hereby granted, provided that the above
005//copyright notice and this permission notice appear in all copies.
006//
007//THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
008//WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
009//MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
010//ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
011//WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
012//ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
013//OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
014
015package org.apache.directory.api.ldap.model.password;
016
017
018import java.io.UnsupportedEncodingException;
019import java.security.SecureRandom;
020
021
022/**
023* BCrypt implements OpenBSD-style Blowfish password hashing using
024* the scheme described in "A Future-Adaptable Password Scheme" by
025* Niels Provos and David Mazieres.
026* <p>
027* This password hashing system tries to thwart off-line password
028* cracking using a computationally-intensive hashing algorithm,
029* based on Bruce Schneier's Blowfish cipher. The work factor of
030* the algorithm is parameterised, so it can be increased as
031* computers get faster.
032* <p>
033* Usage is really simple. To hash a password for the first time,
034* call the hashpw method with a random salt, like this:
035* <p>
036* <code>
037* String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt()); <br />
038* </code>
039* <p>
040* To check whether a plaintext password matches one that has been
041* hashed previously, use the checkpw method:
042* <p>
043* <code>
044* if (BCrypt.checkpw(candidate_password, stored_hash))<br />
045* &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("It matches");<br />
046* else<br />
047* &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("It does not match");<br />
048* </code>
049* <p>
050* The gensalt() method takes an optional parameter (log_rounds)
051* that determines the computational complexity of the hashing:
052* <p>
053* <code>
054* String strong_salt = BCrypt.gensalt(10)<br />
055* String stronger_salt = BCrypt.gensalt(12)<br />
056* </code>
057* <p>
058* The amount of work increases exponentially (2**log_rounds), so 
059* each increment is twice as much work. The default log_rounds is
060* 10, and the valid range is 4 to 30.
061*
062* @author Damien Miller
063* @version 0.2
064*/
065public class BCrypt
066{
067    // BCrypt parameters
068    private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10;
069    private static final int BCRYPT_SALT_LEN = 16;
070
071    // Blowfish parameters
072    private static final int BLOWFISH_NUM_ROUNDS = 16;
073
074    // Initial contents of key schedule
075    private static final int[] P_ORIG =
076        {
077            0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
078            0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
079            0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
080            0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
081            0x9216d5d9, 0x8979fb1b
082        };
083
084    private static final int[] S_ORIG =
085        {
086            0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
087            0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
088            0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
089            0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
090            0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
091            0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
092            0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
093            0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
094            0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
095            0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
096            0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
097            0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
098            0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
099            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}