简体   繁体   English

如何从JPasswordField Java加密/解密密码

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

here's my problem, I am working on a system where user can create an account, the user launches a program, he clicks on the register button. 这是我的问题,我正在一个用户可以创建帐户,用户启动程序,单击注册按钮的系统上工作。 A new page appears and he has to enter his information(username, password). 出现一个新页面,他必须输入他的信息(用户名,密码)。 Then his information is stored into a local DB. 然后,他的信息存储到本地数据库中。 The problem is when a user create his account his information is stored in DB but the password is a String so everyone can see what the password it is . 问题是,当用户创建他的帐户时,他的信息存储在DB中,但是密码是字符串,因此每个人都可以看到密码是什么。 I want to hash the password into my java program first then store it into DB. 我想先将密码散列到我的Java程序中,然后将其存储到DB中。 But I don't understand how to that because I use "Windows Builder" to do the interface, so the user enter his password in a JPasswordField. 但是我不知道该怎么做,因为我使用“ Windows Builder”来做界面,所以用户在JPasswordField中输入密码。 I don't know how to obtain the password that the user wrote, hash it, and send it to the DB. 我不知道如何获取用户编写的密码,对其进行哈希处理并将其发送到数据库。

For now I have a program where I can store the information I need, and I have a program where I can hash a word into different types of hash. 现在,我有一个程序可以存储所需的信息,并且我可以将一个单词散列为不同类型的散列。 I also use the salt method I saw it's better for the password, none of them will have the same hash code. 我还使用了salt方法,我认为这样做对密码更好,因为它们都不会具有相同的哈希码。

The code to store information : 存储信息的代码:

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);
}

The code to hash password : 哈希密码的代码:

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;
}
}

My goal is that the user can register and his password is stored in the DB but the password is hash following a certain type of hash and also he can log in with his account so the password can be decrypt and compare with the one encrypt. 我的目标是用户可以注册,并且密码存储在数据库中,但是密码是在某种类型的哈希之后的哈希,并且他也可以使用自己的帐户登录,以便可以对密码进行解密并与一个密码进行比较。

Sincerely, Molka 真诚的,莫尔卡

First thing, you can't access the generateHash since it is private. 首先,您不能访问generateHash,因为它是私有的。 You will need to change it to public. 您将需要将其更改为公开。 Then you can hook it into the actionPerformed method. 然后,您可以将其挂接到actionPerformed方法中。 Then just save the result in the password row in your database. 然后,只需将结果保存在数据库的密码行中即可。

Second never use MD5 for hashing of passwords. 其次,永远不要使用MD5来哈希密码。 You want to use bcrypt or another secure algorithm. 您要使用bcrypt或其他安全算法。 Here is an example how to do that. 这是一个示例。 https://www.stubbornjava.com/posts/hashing-passwords-in-java-with-bcrypt https://www.stubbornjava.com/posts/hashing-passwords-in-java-with-bcrypt

Lastly, you do not seem to know what you are doing (no offense). 最后,您似乎不知道自己在做什么(没有冒犯性)。 I would strongly advise against implementing any security-related code if it is for the real world. 如果在现实世界中,我强烈建议不要实施任何与安全相关的代码。 It is easy to make a mistake and it can have disastrous effects. 容易犯错误,可能会造成灾难性的后果。 If it is for the real world ask someone more senior to write it for you while you shadow them. 如果是在现实世界中,请在阴影中请年长的人为您编写。 If it is not for the real world then hack away to your heart's content with the help of the example I gave you. 如果不是针对现实世界的话,那么在我给您的示例的帮助下,请尽情享受您的内心世界。

make generateHash a public method of hash class then just call it up before writing the data to database: 将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