簡體   English   中英

如何從JPasswordField Java加密/解密密碼

[英]How to encrypt/decrypt a password from a JPasswordField Java

這是我的問題,我正在一個用戶可以創建帳戶,用戶啟動程序,單擊注冊按鈕的系統上工作。 出現一個新頁面,他必須輸入他的信息(用戶名,密碼)。 然后,他的信息存儲到本地數據庫中。 問題是,當用戶創建他的帳戶時,他的信息存儲在DB中,但是密碼是字符串,因此每個人都可以看到密碼是什么。 我想先將密碼散列到我的Java程序中,然后將其存儲到DB中。 但是我不知道該怎么做,因為我使用“ Windows Builder”來做界面,所以用戶在JPasswordField中輸入密碼。 我不知道如何獲取用戶編寫的密碼,對其進行哈希處理並將其發送到數據庫。

現在,我有一個程序可以存儲所需的信息,並且我可以將一個單詞散列為不同類型的散列。 我還使用了salt方法,我認為這樣做對密碼更好,因為它們都不會具有相同的哈希碼。

存儲信息的代碼:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.awt.event.ActionEvent;

public class Register extends JFrame {

private JPanel contentPane;
private JTextField txtUsername;
private JPasswordField pwdPassword;
private JPasswordField pwdConfpassword;
private JButton btnSubmit;
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Register frame = new Register();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Register() {
    super("Register");
    conn = DatabaseConnection.connection();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    JLabel lblUsername = new JLabel("Username");
    lblUsername.setBounds(96, 68, 71, 14);
    contentPane.add(lblUsername);

    JLabel lblPassword = new JLabel("Password");
    lblPassword.setBounds(96, 93, 80, 14);
    contentPane.add(lblPassword);

    JLabel lblconfPassword = new JLabel("Confirm password");
    lblconfPassword.setBounds(97, 122, 91, 14);
    contentPane.add(lblconfPassword);

    txtUsername = new JTextField();
    txtUsername.setBounds(204, 65, 86, 20);
    contentPane.add(txtUsername);
    txtUsername.setColumns(10);

    pwdPassword = new JPasswordField();
    pwdPassword.setBounds(201, 90, 89, 20);
    contentPane.add(pwdPassword);

    pwdConfpassword = new JPasswordField();
    pwdConfpassword.setBounds(211, 119, 79, 20);
    contentPane.add(pwdConfpassword);

    btnSubmit = new JButton("Submit");
    btnSubmit.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            try {

                stmt = conn.createStatement();
                String RegUsername = txtUsername.getText();
                String RegPassword = pwdPassword.getText();
                String sql = "INSERT INTO account(Username, Password) VALUES('"+RegUsername+"', '"+RegPassword+"')";

                stmt.executeUpdate(sql);
                JOptionPane.showMessageDialog(null,"Account created");
            }catch(Exception e1) {
                JOptionPane.showMessageDialog(null,e1);
            }

        }
    });
    btnSubmit.setBounds(78, 202, 89, 23);
    contentPane.add(btnSubmit);
}

哈希密碼的代碼:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class hash {
public static void main(String[] args) throws Exception {

String Password = "Maria";
String algorithm = "MD5";
byte[] salt = createSalt();
System.out.println("test : " +generateHash(Password, algorithm, salt));
}
private static String generateHash(String Password, String algorithm,                                             byte[] salt) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance(algorithm);
digest.reset();
digest.update(salt);
byte[] hash = digest.digest(Password.getBytes());
return bytesToStringHex(hash);
}
private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToStringHex(byte[] bytes) {
char [] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length;j++) {
    int v = bytes[j] & 0xFF;
    hexChars[j * 2] = hexArray[v >>>4];
    hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
public static byte[] createSalt() {
    byte[] bytes = new byte[20];
    SecureRandom random = new SecureRandom();
    random.nextBytes(bytes);
    return bytes;
}
}

我的目標是用戶可以注冊,並且密碼存儲在數據庫中,但是密碼是在某種類型的哈希之后的哈希,並且他也可以使用自己的帳戶登錄,以便可以對密碼進行解密並與一個密碼進行比較。

真誠的,莫爾卡

首先,您不能訪問generateHash,因為它是私有的。 您將需要將其更改為公開。 然后,您可以將其掛接到actionPerformed方法中。 然后,只需將結果保存在數據庫的密碼行中即可。

其次,永遠不要使用MD5來哈希密碼。 您要使用bcrypt或其他安全算法。 這是一個示例。 https://www.stubbornjava.com/posts/hashing-passwords-in-java-with-bcrypt

最后,您似乎不知道自己在做什么(沒有冒犯性)。 如果在現實世界中,我強烈建議不要實施任何與安全相關的代碼。 容易犯錯誤,可能會造成災難性的后果。 如果是在現實世界中,請在陰影中請年長的人為您編寫。 如果不是針對現實世界的話,那么在我給您的示例的幫助下,請盡情享受您的內心世界。

將generateHash作為哈希類的公共方法,然后在將數據寫入數據庫之前調用它:

public void actionPerformed(ActionEvent e) {
        try {

            stmt = conn.createStatement();
            String RegUsername = txtUsername.getText();
            String RegPassword = hash.generateHash(pwdPassword.getText(),"sha-512");
            String sql = "INSERT INTO account(Username, Password) VALUES('"+RegUsername+"', '"+RegPassword+"')";

            stmt.executeUpdate(sql);
            JOptionPane.showMessageDialog(null,"Account created");
        }catch(Exception e1) {
            JOptionPane.showMessageDialog(null,e1);
        }

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM