56
56
* <p>
57
57
* The amount of work increases exponentially (2**log_rounds), so
58
58
* each increment is twice as much work. The default log_rounds is
59
- * 10, and the valid range is 4 to 31 .
59
+ * 10, and the valid range is 4 to 30 .
60
60
*
61
61
* @author Damien Miller
62
- * @version 0.3
62
+ * @version 0.4
63
63
*/
64
64
public class BCrypt {
65
65
// BCrypt parameters
@@ -336,7 +336,9 @@ public class BCrypt {
336
336
0xb74e6132 , 0xce77e25b , 0x578fdfe3 , 0x3ac372e6
337
337
};
338
338
339
- // bcrypt IV: "OrpheanBeholderScryDoubt"
339
+ // bcrypt IV: "OrpheanBeholderScryDoubt". The C implementation calls
340
+ // this "ciphertext", but it is really plaintext or an IV. We keep
341
+ // the name to make code comparison easier.
340
342
static private final int bf_crypt_ciphertext [] = {
341
343
0x4f727068 , 0x65616e42 , 0x65686f6c ,
342
344
0x64657253 , 0x63727944 , 0x6f756274
@@ -602,23 +604,24 @@ private void ekskey(byte data[], byte key[]) {
602
604
* @param salt the binary salt to hash with the password
603
605
* @param log_rounds the binary logarithm of the number
604
606
* of rounds of hashing to apply
607
+ * @param cdata the plaintext to encrypt
605
608
* @return an array containing the binary hashed password
606
609
*/
607
- private byte [] crypt_raw (byte password [], byte salt [], int log_rounds ) {
610
+ public byte [] crypt_raw (byte password [], byte salt [], int log_rounds ,
611
+ int cdata []) {
608
612
int rounds , i , j ;
609
- int cdata [] = (int [])bf_crypt_ciphertext .clone ();
610
613
int clen = cdata .length ;
611
614
byte ret [];
612
615
613
- if (log_rounds < 4 || log_rounds > 31 )
616
+ if (log_rounds < 4 || log_rounds > 30 )
614
617
throw new IllegalArgumentException ("Bad number of rounds" );
615
618
rounds = 1 << log_rounds ;
616
619
if (salt .length != BCRYPT_SALT_LEN )
617
620
throw new IllegalArgumentException ("Bad salt length" );
618
621
619
622
init_key ();
620
623
ekskey (salt , password );
621
- for (i = 0 ; i < rounds ; i ++) {
624
+ for (i = 0 ; i != rounds ; i ++) {
622
625
key (password );
623
626
key (salt );
624
627
}
@@ -679,14 +682,19 @@ public static String hashpw(String password, String salt) {
679
682
saltb = decode_base64 (real_salt , BCRYPT_SALT_LEN );
680
683
681
684
B = new BCrypt ();
682
- hashed = B .crypt_raw (passwordb , saltb , rounds );
685
+ hashed = B .crypt_raw (passwordb , saltb , rounds ,
686
+ (int [])bf_crypt_ciphertext .clone ());
683
687
684
688
rs .append ("$2" );
685
689
if (minor >= 'a' )
686
690
rs .append (minor );
687
691
rs .append ("$" );
688
692
if (rounds < 10 )
689
693
rs .append ("0" );
694
+ if (rounds > 30 ) {
695
+ throw new IllegalArgumentException (
696
+ "rounds exceeds maximum (30)" );
697
+ }
690
698
rs .append (Integer .toString (rounds ));
691
699
rs .append ("$" );
692
700
rs .append (encode_base64 (saltb , saltb .length ));
@@ -712,6 +720,10 @@ public static String gensalt(int log_rounds, SecureRandom random) {
712
720
rs .append ("$2a$" );
713
721
if (log_rounds < 10 )
714
722
rs .append ("0" );
723
+ if (log_rounds > 30 ) {
724
+ throw new IllegalArgumentException (
725
+ "log_rounds exceeds maximum (30)" );
726
+ }
715
727
rs .append (Integer .toString (log_rounds ));
716
728
rs .append ("$" );
717
729
rs .append (encode_base64 (rnd , rnd .length ));
@@ -747,6 +759,20 @@ public static String gensalt() {
747
759
* @return true if the passwords match, false otherwise
748
760
*/
749
761
public static boolean checkpw (String plaintext , String hashed ) {
750
- return (hashed .compareTo (hashpw (plaintext , hashed )) == 0 );
762
+ byte hashed_bytes [];
763
+ byte try_bytes [];
764
+ try {
765
+ String try_pw = hashpw (plaintext , hashed );
766
+ hashed_bytes = hashed .getBytes ("UTF-8" );
767
+ try_bytes = try_pw .getBytes ("UTF-8" );
768
+ } catch (UnsupportedEncodingException uee ) {
769
+ return false ;
770
+ }
771
+ if (hashed_bytes .length != try_bytes .length )
772
+ return false ;
773
+ byte ret = 0 ;
774
+ for (int i = 0 ; i < try_bytes .length ; i ++)
775
+ ret |= hashed_bytes [i ] ^ try_bytes [i ];
776
+ return ret == 0 ;
751
777
}
752
778
}
0 commit comments