如何加密/解密来自 JPasswordField Java 的密码

Posted

技术标签:

【中文标题】如何加密/解密来自 JPasswordField Java 的密码【英文标题】:How to encrypt/decrypt a password from a JPasswordField Java 【发布时间】:2019-05-25 21:15:24 【问题描述】:

这是我的问题,我正在开发一个用户可以创建帐户的系统,用户启动一个程序,然后单击注册按钮。出现一个新页面,他必须输入他的信息(用户名,密码)。然后他的信息被存储到本地数据库中。问题是当用户创建他的帐户时,他的信息存储在数据库中,但密码是字符串,所以每个人都可以看到密码是什么。我想先将密码散列到我的 java 程序中,然后将其存储到数据库中。但我不明白怎么做,因为我使用“Windows Builder”来做界面,所以用户在 JPasswordField 中输入他的密码。不知道怎么获取用户写的密码,hash,发给DB。

现在我有一个程序可以存储我需要的信息,并且我有一个程序可以将一个单词散列成不同类型的散列。我也使用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;


我的目标是用户可以注册并且他的密码存储在数据库中,但是密码是遵循某种类型的哈希的哈希,他也可以用他的帐户登录,这样密码就可以被解密并与那个比较加密。

真诚地, 莫尔卡

【问题讨论】:

欢迎来到 Stack Overflow!请带上tour,环顾四周,并通读help center,尤其是How do I ask a good question? 和What topics can I ask about here?。 参见***上的Cryptographic hash function 和Salt (cryptography)。 【参考方案1】:

首先,您无法访问 generateHash,因为它是私有的。您需要将其更改为公开。然后你可以将它挂接到 actionPerformed 方法中。然后将结果保存在数据库的密码行中。

第二,永远不要使用 MD5 对密码进行哈希处理。您想使用 bcrypt 或其他安全算法。这是一个如何做到这一点的例子。 https://www.stubbornjava.com/posts/hashing-passwords-in-java-with-bcrypt

最后,你似乎不知道自己在做什么(无意冒犯)。如果适用于现实世界,我强烈建议不要实施任何与安全相关的代码。很容易犯错,而且会造成灾难性的后果。如果它是针对现实世界的,请让更资深的人为你写它,而你却在模仿他们。如果它不适合现实世界,那么请借助我给您的示例,尽情享受。

【讨论】:

感谢您的回答。我会把它改成公开的。好的,我将尝试按照您发送给我的教程进行操作。我是一般编程的初学者。我正在做的是一个学校项目,我们没有关于编程和java的此类课程。我使用 Java 是因为我们做的事情很少,但不是因为我喜欢它或者我知道如何使用 Java。我会按照教程进行,如果事情不顺利,我会回来。此致,莫尔卡【参考方案2】:

将 generateHash 设为 hash 类的公共方法,然后在将数据写入数据库之前调用它:

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

    

【讨论】:

以上是关于如何加密/解密来自 JPasswordField Java 的密码的主要内容,如果未能解决你的问题,请参考以下文章

解密来自MagTek iDynamo加密读卡器的数据

java中RSA用私钥加密公钥解密问题

SSL:客户端如何解密来自服务器的消息

使用php mcrypt加密解密

使用php mcrypt加密解密

在Java中生成和使用两个密钥进行加密和解密