public static String hashpw ( String password , String salt ) { BCrypt B ; String real_salt ; byte [ ] passwordb , saltb , hashed ; char minor = ( char ) 0 ; int rounds , off ; StringBuffer rs = new StringBuffer ( ) ; if ( salt . charAt ( 0 ) != ' ' || salt . charAt ( 1 ) != ' ' ) { throw new IllegalArgumentException ( "Invalid salt version" ) ; } if ( salt . charAt ( 2 ) == ' ' ) { off = 3 ; } else { minor = salt . charAt ( 2 ) ; if ( minor != ' ' || salt . charAt ( 3 ) != ' ' ) { throw new IllegalArgumentException ( "Invalid salt revision" ) ; } off = 4 ; } // Extract number of rounds if ( salt . charAt ( off + 2 ) > ' ' ) { throw new IllegalArgumentException ( "Missing salt rounds" ) ; } rounds = Integer . parseInt ( salt . substring ( off , off + 2 ) ) ; real_salt = salt . substring ( off + 3 , off + 25 ) ; try { passwordb = ( password + ( minor >= ' ' ? "\000" : "" ) ) . getBytes ( "UTF-8" ) ; } catch ( UnsupportedEncodingException uee ) { throw new AssertionError ( "UTF-8 is not supported" ) ; } saltb = decode_base64 ( real_salt , BCRYPT_SALT_LEN ) ; B = new BCrypt ( ) ; hashed = B . crypt_raw ( passwordb , saltb , rounds , ( int [ ] ) bf_crypt_ciphertext . clone ( ) ) ; rs . append ( "$2" ) ; if ( minor >= ' ' ) { rs . append ( minor ) ; } rs . append ( ' ' ) ; if ( rounds < 10 ) { rs . append ( ' ' ) ; } if ( rounds > 30 ) { throw new IllegalArgumentException ( "rounds exceeds maximum (30)" ) ; } rs . append ( rounds ) . append ( ' ' ) . append ( encode_base64 ( saltb , saltb . length ) ) . append ( encode_base64 ( hashed , bf_crypt_ciphertext . length * 4 - 1 ) ) ; return rs . toString ( ) ; }
Hash a password using the OpenBSD bcrypt scheme .