@Override public String toString() { return "Credential{" + "salt=0x" + HexString.encodeHexString( salt ) + ", passwordHash=0x" + HexString.encodeHexString( passwordHash ) + '}'; }
private LegacyCredential deserializeCredentials( String part, int lineNumber ) throws FormatException { String[] split = part.split( credentialSeparator, -1 ); if ( split.length != 3 ) { throw new FormatException( format( "wrong number of credential fields [line %d]", lineNumber ) ); } if ( !split[0].equals( LegacyCredential.DIGEST_ALGO ) ) { throw new FormatException( format( "unknown digest \"%s\" [line %d]", split[0], lineNumber ) ); } byte[] decodedPassword = HexString.decodeHexString( split[1] ); byte[] decodedSalt = HexString.decodeHexString( split[2] ); return new LegacyCredential( decodedSalt, decodedPassword ); } }
protected String serialize( LegacyCredential cred ) { String encodedSalt = HexString.encodeHexString( cred.salt() ); String encodedPassword = HexString.encodeHexString( cred.passwordHash() ); return String.join( credentialSeparator, LegacyCredential.DIGEST_ALGO, encodedPassword, encodedSalt ); }
@Test void shouldDecodeStringToBytes() { byte[] result = HexString.decodeHexString( "00f34CEFFF3e02" ); byte[] expected = new byte[] {(byte) 0x00, (byte) 0xF3, (byte) 0x4C, (byte) 0xEF, (byte) 0xFF, (byte) 0x3E, (byte) 0x02 }; assertArrayEquals( expected, result ); }
@Test void shouldEncodeEmptyBytesToEmptyString() { String result = HexString.encodeHexString( new byte[]{} ); assertEquals( "", result ); }
@Test void shouldDecodeEmptyStringToEmptyBytes() { byte[] result = HexString.decodeHexString( "" ); assertArrayEquals( new byte[]{}, result ); } }
@Test void shouldEncodeBytesToString() { String result = HexString.encodeHexString( new byte[]{(byte) 0xFF, (byte) 0x94, (byte) 0x5C, (byte) 0x00, (byte) 0x3D} ); assertEquals( "FF945C003D", result ); }
private LegacyCredential deserializeCredentials( String part, int lineNumber ) throws FormatException { String[] split = part.split( credentialSeparator, -1 ); if ( split.length != 3 ) { throw new FormatException( format( "wrong number of credential fields [line %d]", lineNumber ) ); } if ( !split[0].equals( LegacyCredential.DIGEST_ALGO ) ) { throw new FormatException( format( "unknown digest \"%s\" [line %d]", split[0], lineNumber ) ); } byte[] decodedPassword = HexString.decodeHexString( split[1] ); byte[] decodedSalt = HexString.decodeHexString( split[2] ); return new LegacyCredential( decodedSalt, decodedPassword ); } }
public String asHex() { // Convert the flags to a byte-array, each // flag represented as a single bit. byte[] bits = new byte[flags.length / 8]; // Go over the flags, eight at a time to align // with sticking eight bits at a time into the // output array. for ( int i = 0; i < flags.length; i += 8 ) { bits[i / 8] = (byte)( (bit( i ) << 7) | (bit( i + 1 ) << 6) | (bit( i + 2 ) << 5) | (bit( i + 3 ) << 4) | (bit( i + 4 ) << 3) | (bit( i + 5 ) << 2) | (bit( i + 6 ) << 1) | (bit( i + 7 )) ) ; } return HexString.encodeHexString( bits ); }
@Override public String toString() { return "Credential{" + "salt=0x" + HexString.encodeHexString( salt ) + ", passwordHash=0x" + HexString.encodeHexString( passwordHash ) + '}'; }
protected String serialize( LegacyCredential cred ) { String encodedSalt = HexString.encodeHexString( cred.salt() ); String encodedPassword = HexString.encodeHexString( cred.passwordHash() ); return String.join( credentialSeparator, LegacyCredential.DIGEST_ALGO, encodedPassword, encodedSalt ); }
private static Path createAuthStore(String username, String password) throws IOException { // Until 3.4 there's org.neo4j.kernel.impl.security.Credential for both CE and Enterprise. // Since 3.5 there's a dedicated SystemGraphCredential for the enterprise edition. // We should monitor this for further releasese. ThreadLocalRandom random = ThreadLocalRandom.current(); byte[] saltedPassword = new byte[0]; byte[] salt = new byte[32]; random.nextBytes(salt); try { MessageDigest m = MessageDigest.getInstance(DIGEST_ALGO); m.update(salt); m.update(password.getBytes(StandardCharsets.UTF_8)); saltedPassword = m.digest(); } catch (NoSuchAlgorithmException e) { } String format = "%s:%s,%s,%s:"; // This is the record format from org.neo4j.server.security.auth.UserSerialization String record = String .format(format, username, DIGEST_ALGO, encodeHexString(saltedPassword), encodeHexString(salt)); Path authStore = Files .write(Files.createTempFile("neo4j", "credentials"), record.getBytes(StandardCharsets.UTF_8)); Runtime.getRuntime().addShutdownHook(new Thread(() -> { try { Files.deleteIfExists(authStore); } catch (IOException e) { } })); return authStore; }
public String asHex() { // Convert the flags to a byte-array, each // flag represented as a single bit. byte[] bits = new byte[flags.length / 8]; // Go over the flags, eight at a time to align // with sticking eight bits at a time into the // output array. for ( int i = 0; i < flags.length; i += 8 ) { bits[i / 8] = (byte)( (bit( i ) << 7) | (bit( i + 1 ) << 6) | (bit( i + 2 ) << 5) | (bit( i + 3 ) << 4) | (bit( i + 4 ) << 3) | (bit( i + 5 ) << 2) | (bit( i + 6 ) << 1) | (bit( i + 7 )) ) ; } return HexString.encodeHexString( bits ); }
public String asHex() { // Convert the flags to a byte-array, each // flag represented as a single bit. byte[] bits = new byte[flags.length / 8]; // Go over the flags, eight at a time to align // with sticking eight bits at a time into the // output array. for ( int i = 0; i < flags.length; i += 8 ) { bits[i / 8] = (byte)( (bit( i ) << 7) | (bit( i + 1 ) << 6) | (bit( i + 2 ) << 5) | (bit( i + 3 ) << 4) | (bit( i + 4 ) << 3) | (bit( i + 5 ) << 2) | (bit( i + 6 ) << 1) | (bit( i + 7 )) ) ; } return HexString.encodeHexString( bits ); }