使用保存在系统文件中的加密值验证来自控制台的值
verify values from the console with the encrypted values saved in the systems file
自从昨天第一次发帖以来,我学到了很多东西。所以我现在要做的是实现用户控制台输入而不是给定值,用粗体写,加密,将它们保存在文件中,然后继续使用保存在文件中的加密值验证下一个用户输入,直到正确或正确到 10 倍。
String openPwd = "my password is datasecurity";
String openUser = "a user is ME";
第一个问题是:我可以在 class 的相同主要方法中实现第二次用户输入和验证吗?
此外,我使用两种加密方式 AES 对值进行加密(现在我知道这不是最安全的加密方式),并且由于多种原因,一种使用散列和盐的加密方式将是最安全的选择。此外,我将密码和密钥保存在系统文件中,因为设置数据库对于这项任务来说太耗时了。
第二个问题是:如果我不在 dbms 中保存密码和用户名,而是在系统文件中,我可以使用 PBKDF2 和盐代替 AES 加密吗?加密案例和 PBKDF2 加盐的验证过程有何不同?
public class PasswordEncryption {
public static final String AES = "AES";
public static String encrypt(String value, File keyFile)
throws GeneralSecurityException, IOException {
if (!keyFile.exists()) {
KeyGenerator keyGen = KeyGenerator
.getInstance(PasswordEncryption.AES);
keyGen.init(128);
SecretKey sk = keyGen.generateKey();
FileWriter fw = new FileWriter(keyFile);
fw.write(byteArrayToHexString(sk.getEncoded()));
fw.flush();
fw.close();
}
SecretKeySpec sks = getSecretKeySpec(keyFile);
Cipher cipher = Cipher.getInstance(PasswordEncryption.AES);
cipher.init(Cipher.ENCRYPT_MODE, sks, cipher.getParameters());
byte[] encrypted = cipher.doFinal(value.getBytes());
return byteArrayToHexString(encrypted);
}
public static String decrypt(String message, File keyFile)
throws GeneralSecurityException, IOException {
SecretKeySpec sks = getSecretKeySpec(keyFile);
Cipher cipher = Cipher.getInstance(PasswordEncryption.AES);
cipher.init(Cipher.DECRYPT_MODE, sks);
byte[] decrypted = cipher.doFinal(hexStringToByteArray(message));
return new String(decrypted);
}
private static SecretKeySpec getSecretKeySpec(File keyFile)
throws NoSuchAlgorithmException, IOException {
byte[] key = readKeyFile(keyFile);
SecretKeySpec sks = new SecretKeySpec(key, PasswordEncryption.AES);
return sks;
}
private static byte[] readKeyFile(File keyFile)
throws FileNotFoundException {
@SuppressWarnings("resource")
Scanner scanner = new Scanner(keyFile).useDelimiter("\Z");
String keyValue = scanner.next();
scanner.close();
return hexStringToByteArray(keyValue);
}
private static String byteArrayToHexString(byte[] b) {
StringBuffer sb = new StringBuffer(b.length * 2);
for (int i = 0; i < b.length; i++) {
int v = b[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
private static byte[] hexStringToByteArray(String s) {
byte[] b = new byte[s.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(s.substring(index, index + 2), 16);
b[i] = (byte) v;
}
return b;
}
public static void main(String[] args) throws Exception {
final String KEY_FILE = "/Users/xxx/key";
final String PASSWORD_FILE = "/Users/xxx/properties";
String openPwd = "my password is datasecurity";
String openUser = "a user is ME";
Properties p1 = new Properties();
String encryptedPwd = PasswordEncryption.encrypt(openPwd, new File(
KEY_FILE));
String encryptedUser = PasswordEncryption.encrypt(openUser, new File(
KEY_FILE));
p1.put("password",encryptedPwd);
p1.put("user",encryptedUser);
p1.store(new FileWriter(PASSWORD_FILE),"");
// ==================
Properties p2 = new Properties();
p2.load(new FileReader(PASSWORD_FILE));
encryptedPwd = p2.getProperty("password");
encryptedUser = p2.getProperty("user");
System.out.println(encryptedPwd);
System.out.println(encryptedUser);
System.out.println(PasswordEncryption.decrypt(encryptedPwd, new File(
KEY_FILE)));
System.out.println(PasswordEncryption.decrypt(encryptedUser, new File(
KEY_FILE)));
}
}
有两种简单的方法可以做到这一点。第一个是在您的第一个 class 中创建一个 static
class 级别变量,其中包含 encryptedPwd
的值。要制作 class 级别变量,您可以这样定义它:
public class FirstClass {
public static String encryptedPwd = "";
public static void main(String[] args){
...
FirstClass.encryptedPwd = encryptedPwd; //Set the class level variable equal to the encrypted password
...
}
}
然后您可以使用 Authenticate
class 访问它:
if (FirstClass.encryptedPwd.equals(inputHash)) //Getting the password variable in Authenticate class
或者您也可以创建一个静态方法来访问它,这样您就可以将变量保持私有。
public static String getPassword(){ //Static Method inside your first class that returns the encrypted password
return encryptedPwd;
}
if(FirstClass.getPassword().equals(inputHash)) //Method call in Authenticate class
还有其他选择,但这取决于您在做什么以及您想要的项目设计
自从昨天第一次发帖以来,我学到了很多东西。所以我现在要做的是实现用户控制台输入而不是给定值,用粗体写,加密,将它们保存在文件中,然后继续使用保存在文件中的加密值验证下一个用户输入,直到正确或正确到 10 倍。
String openPwd = "my password is datasecurity";
String openUser = "a user is ME";
第一个问题是:我可以在 class 的相同主要方法中实现第二次用户输入和验证吗?
此外,我使用两种加密方式 AES 对值进行加密(现在我知道这不是最安全的加密方式),并且由于多种原因,一种使用散列和盐的加密方式将是最安全的选择。此外,我将密码和密钥保存在系统文件中,因为设置数据库对于这项任务来说太耗时了。
第二个问题是:如果我不在 dbms 中保存密码和用户名,而是在系统文件中,我可以使用 PBKDF2 和盐代替 AES 加密吗?加密案例和 PBKDF2 加盐的验证过程有何不同?
public class PasswordEncryption {
public static final String AES = "AES";
public static String encrypt(String value, File keyFile)
throws GeneralSecurityException, IOException {
if (!keyFile.exists()) {
KeyGenerator keyGen = KeyGenerator
.getInstance(PasswordEncryption.AES);
keyGen.init(128);
SecretKey sk = keyGen.generateKey();
FileWriter fw = new FileWriter(keyFile);
fw.write(byteArrayToHexString(sk.getEncoded()));
fw.flush();
fw.close();
}
SecretKeySpec sks = getSecretKeySpec(keyFile);
Cipher cipher = Cipher.getInstance(PasswordEncryption.AES);
cipher.init(Cipher.ENCRYPT_MODE, sks, cipher.getParameters());
byte[] encrypted = cipher.doFinal(value.getBytes());
return byteArrayToHexString(encrypted);
}
public static String decrypt(String message, File keyFile)
throws GeneralSecurityException, IOException {
SecretKeySpec sks = getSecretKeySpec(keyFile);
Cipher cipher = Cipher.getInstance(PasswordEncryption.AES);
cipher.init(Cipher.DECRYPT_MODE, sks);
byte[] decrypted = cipher.doFinal(hexStringToByteArray(message));
return new String(decrypted);
}
private static SecretKeySpec getSecretKeySpec(File keyFile)
throws NoSuchAlgorithmException, IOException {
byte[] key = readKeyFile(keyFile);
SecretKeySpec sks = new SecretKeySpec(key, PasswordEncryption.AES);
return sks;
}
private static byte[] readKeyFile(File keyFile)
throws FileNotFoundException {
@SuppressWarnings("resource")
Scanner scanner = new Scanner(keyFile).useDelimiter("\Z");
String keyValue = scanner.next();
scanner.close();
return hexStringToByteArray(keyValue);
}
private static String byteArrayToHexString(byte[] b) {
StringBuffer sb = new StringBuffer(b.length * 2);
for (int i = 0; i < b.length; i++) {
int v = b[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
private static byte[] hexStringToByteArray(String s) {
byte[] b = new byte[s.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(s.substring(index, index + 2), 16);
b[i] = (byte) v;
}
return b;
}
public static void main(String[] args) throws Exception {
final String KEY_FILE = "/Users/xxx/key";
final String PASSWORD_FILE = "/Users/xxx/properties";
String openPwd = "my password is datasecurity";
String openUser = "a user is ME";
Properties p1 = new Properties();
String encryptedPwd = PasswordEncryption.encrypt(openPwd, new File(
KEY_FILE));
String encryptedUser = PasswordEncryption.encrypt(openUser, new File(
KEY_FILE));
p1.put("password",encryptedPwd);
p1.put("user",encryptedUser);
p1.store(new FileWriter(PASSWORD_FILE),"");
// ==================
Properties p2 = new Properties();
p2.load(new FileReader(PASSWORD_FILE));
encryptedPwd = p2.getProperty("password");
encryptedUser = p2.getProperty("user");
System.out.println(encryptedPwd);
System.out.println(encryptedUser);
System.out.println(PasswordEncryption.decrypt(encryptedPwd, new File(
KEY_FILE)));
System.out.println(PasswordEncryption.decrypt(encryptedUser, new File(
KEY_FILE)));
}
}
有两种简单的方法可以做到这一点。第一个是在您的第一个 class 中创建一个 static
class 级别变量,其中包含 encryptedPwd
的值。要制作 class 级别变量,您可以这样定义它:
public class FirstClass {
public static String encryptedPwd = "";
public static void main(String[] args){
...
FirstClass.encryptedPwd = encryptedPwd; //Set the class level variable equal to the encrypted password
...
}
}
然后您可以使用 Authenticate
class 访问它:
if (FirstClass.encryptedPwd.equals(inputHash)) //Getting the password variable in Authenticate class
或者您也可以创建一个静态方法来访问它,这样您就可以将变量保持私有。
public static String getPassword(){ //Static Method inside your first class that returns the encrypted password
return encryptedPwd;
}
if(FirstClass.getPassword().equals(inputHash)) //Method call in Authenticate class
还有其他选择,但这取决于您在做什么以及您想要的项目设计