汉克雷斯特。如何检查字节数组是否相等
Hamcrest. How to check byte array equals
创建管理员需要创建应用密码,不涉及数据库。管理员密码创建后,将保存在数据库中。按以下测试方法写入byte[]和读取同值into/from文件有问题
这个方法好吗?使用二进制数据有什么问题?
import org.apache.commons.io.FileUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.io.*;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import java.util.Random;
import static org.junit.Assert.assertEquals;
public class Passwords {
static byte[] salt;
static byte[] password_hash;
private static final Random RANDOM = new SecureRandom();
private static final int ITERATIONS = 10000;
private static final int KEY_LENGTH = 256;
static String password_file ="C:\Users\hp\IdeaProjects\pp20_hotel_v1\src\main\resources\app_password_hash";
static String salt_file = "C:\Users\hp\IdeaProjects\pp20_hotel_v1\src\main\resources\salt_hash";
public static byte[] getNextSalt() {
byte[] salt = new byte[16];
RANDOM.nextBytes(salt);
return salt;
}
private static void writeBinary(String path, byte[] arr){
File file = new File(path);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
FileUtils.writeByteArrayToFile(file, arr);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static byte[] hash(char[] password, byte[] salt) {
PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH);
Arrays.fill(password, Character.MIN_VALUE);
try {
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
return skf.generateSecret(spec).getEncoded();
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new AssertionError("Error while hashing a password: " + e.getMessage(), e);
} finally {
spec.clearPassword();
}
}
private static byte[] readBinary(String path){
File file = new File(path);
byte fileContent[] = null;
try {
fileContent = FileUtils.readFileToByteArray(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return fileContent;
}
@BeforeClass
public static void writeSaltAndPassword(){
String password = "12345678";
salt = getNextSalt();
password_hash = hash(password.toCharArray(), salt);
System.out.println("salt : "+salt);
System.out.println("password_hash : "+password_hash);
writeBinary(password_file, password_hash);
writeBinary(salt_file, salt);
}
@Test
public void checkPassword(){
byte[] actual_password_hash=readBinary(password_file);
assertEquals(password_hash, actual_password_hash);
}
}
问题就出在这里。
Hamcrest 不会逐个元素地检查 byte[]。
需要写:
for(int i=0; i<password_hash.length;i++){
if(password_hash[i]!=actual_password_hash[i]){
System.out.println(password_hash[i]!=actual_password_hash[i]);
return;
}
}
创建管理员需要创建应用密码,不涉及数据库。管理员密码创建后,将保存在数据库中。按以下测试方法写入byte[]和读取同值into/from文件有问题
这个方法好吗?使用二进制数据有什么问题?
import org.apache.commons.io.FileUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.io.*;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import java.util.Random;
import static org.junit.Assert.assertEquals;
public class Passwords {
static byte[] salt;
static byte[] password_hash;
private static final Random RANDOM = new SecureRandom();
private static final int ITERATIONS = 10000;
private static final int KEY_LENGTH = 256;
static String password_file ="C:\Users\hp\IdeaProjects\pp20_hotel_v1\src\main\resources\app_password_hash";
static String salt_file = "C:\Users\hp\IdeaProjects\pp20_hotel_v1\src\main\resources\salt_hash";
public static byte[] getNextSalt() {
byte[] salt = new byte[16];
RANDOM.nextBytes(salt);
return salt;
}
private static void writeBinary(String path, byte[] arr){
File file = new File(path);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
FileUtils.writeByteArrayToFile(file, arr);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static byte[] hash(char[] password, byte[] salt) {
PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH);
Arrays.fill(password, Character.MIN_VALUE);
try {
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
return skf.generateSecret(spec).getEncoded();
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new AssertionError("Error while hashing a password: " + e.getMessage(), e);
} finally {
spec.clearPassword();
}
}
private static byte[] readBinary(String path){
File file = new File(path);
byte fileContent[] = null;
try {
fileContent = FileUtils.readFileToByteArray(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return fileContent;
}
@BeforeClass
public static void writeSaltAndPassword(){
String password = "12345678";
salt = getNextSalt();
password_hash = hash(password.toCharArray(), salt);
System.out.println("salt : "+salt);
System.out.println("password_hash : "+password_hash);
writeBinary(password_file, password_hash);
writeBinary(salt_file, salt);
}
@Test
public void checkPassword(){
byte[] actual_password_hash=readBinary(password_file);
assertEquals(password_hash, actual_password_hash);
}
}
问题就出在这里。 Hamcrest 不会逐个元素地检查 byte[]。 需要写:
for(int i=0; i<password_hash.length;i++){
if(password_hash[i]!=actual_password_hash[i]){
System.out.println(password_hash[i]!=actual_password_hash[i]);
return;
}
}