【问题标题】:Storing and retrieving salt from a MySQL database从 MySQL 数据库中存储和检索盐
【发布时间】:2019-10-01 23:47:11
【问题描述】:

我有一个 PasswordEncryptionService,我在其中散列我的密码并将它们与用于散列它们的盐一起保存在我的 MySQL 数据库中。我将我的密码和我的 Salt 都保存为字节数组,我听说我可以将它们保存为 SQL 数据库中的 varbinary 类型。

这是我的代码:

 //this method is used to retrieve the salt when a user is logging in 
 public static byte[] getSaltMethod(String username, String password) throws SQLException, LoginSampleException {

    try {

        Connection con = Connector.connection();

        String SQL = "SELECT * from Users.Salt WHERE email = ?, password = ?";

        PreparedStatement statement = con.prepareStatement(SQL);
        statement.setString(1, username);
        statement.setString(2, password);

        ResultSet set = statement.executeQuery();

        while (set.next()) {

            // vi skal ikke have en blolb her alligevel
            byte[] salt = set.getBytes("salt");
            //release the blob and free up memory. (since JDBC 4.0)
            /* jeg er i tivil om denne skal være her*/

            return salt;

        }

    } catch (SQLException ex) {
        Conf.MYLOGGER.log(Level.SEVERE, null, ex);
        throw new LoginSampleException(ex.getSQLState());
    }
    return null;

}



//this method is used to save the user along with the salt when a user is signing up

 public static void createUser(User user) throws LoginSampleException, NoSuchAlgorithmException 
{
    try {
        PasswordEncryptionService PE = new PasswordEncryptionService();
        byte[] salt = PE.generateSalt();
        Connection con = Connector.connection();
        String SQL = "INSERT INTO Users (email, password, phone, post, adress, role, salt) VALUES (?, ?, ?, ?, ?, ?, ?)";
        PreparedStatement ps = con.prepareStatement(SQL, Statement.RETURN_GENERATED_KEYS);
        ps.setString(1, user.getEmail());
        ps.setString(2, user.getPassword());
        ps.setString(3, user.getPhonenumber());
        ps.setString(4, user.getPostalCode());
        ps.setString(5, user.getAddress());
        ps.setString(6, user.getRole());
        ps.setBytes(7, salt);
        ps.executeUpdate();
        ResultSet ids = ps.getGeneratedKeys();
        ids.next();
        int id = ids.getInt(1);
        user.setId(id);
    } catch (SQLException ex) {
        throw new LoginSampleException(ex.getMessage());
    }
}

现在我有一个单独的方法来检索盐和登录人,我应该将盐保存在不同的表中,还是可以保存在用户对象中?我应该将其保存为 varbinary 还是仅保存为常规 varchar?

【问题讨论】:

    标签: java sql salt


    【解决方案1】:

    如果这是家庭作业,那么您可以将它们保存为 varchar 或二进制文件。哪个老师喜欢就行。

    现在,为了生产,我将哈希值保存为binaryvarchar,我(个人)更喜欢二进制。作为二进制文件,我将它们保存为单个(连接)列或两个单独的列(盐和哈希)。

    varchar 的好处:

    • 很容易调试、备份、打印和比较,以备不时之需。
    • 很容易连接和分离其部分。所有字符串函数都可用。
    • 即使是最环保的开发人员也了解如何管理(连接、子字符串等)字符串。

    binary 的优点/缺点:

    • 无需在Stringbyte[] 之间来回编码。 Base64 或 hexa 编码需要更多编码,或使用非标准库。
    • 许多开发人员不熟悉[var]binaryblob 数据类型列。
    • 许多 SQL 工具不能很好地显示二进制列,这使得调试变得更加困难,或者只是检查它是否在做正确的事情。

    除此之外,我更喜欢 [var]binary,因为它的 java 编码更少。

    【讨论】:

    • 代码有什么不同,我应该使用varbinary还是varchar,还是代码一样??
    • 相同的代码。使用 varchar 时,您需要添加将哈希从二进制转换为字符串的额外步骤(使用 Base 64 或普通 hexa)。
    猜你喜欢
    • 1970-01-01
    • 2011-12-30
    • 2012-09-15
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 2012-09-11
    相关资源
    最近更新 更多