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