代码之家  ›  专栏  ›  技术社区  ›  kristheman

从mysql数据库存储和检索salt

  •  2
  • kristheman  · 技术社区  · 8 年前

    我有一个passwordencryptionservice,在那里我散列我的密码,并将它们与散列密码所用的salt一起保存在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());
        }
    }
    

    现在我有一个单独的方法来检索salt,并登录person,我应该将salt保存在另一个表中,还是可以保存在user对象中?我应该将它保存为varbinary还是只保存为普通的varchar?

    1 回复  |  直到 8 年前
        1
  •  2
  •   The Impaler    8 年前

    如果这是家庭作业,那么可以将它们保存为varchar或binary。不管你喜欢什么,老师都可以。

    现在,为了生产,我把散列保存为 binary 作为 varchar ,我(个人)更喜欢二进制。作为二进制文件,我将它们都保存为单个(连接)列,或作为两个单独的列(salt&hash)。

    收益 瓦查尔 :

    • 它很容易调试,备份,打印,比较,以防你需要它。
    • 连接起来很容易把它的各个部分分开。所有字符串函数都可用。
    • 即使是最环保的开发人员也知道如何管理(连接、子字符串等)字符串。

    利益 二元的 :

    • 不需要在字符串和字节之间来回编码。base64或hexa编码需要更多的编码,或者使用非标准库。
    • 很多开发人员并不熟悉 [var]binary 或 blob 数据类型列。
    • 许多sql工具不能很好地显示二进制列,这使得成为bug或者仅仅检查它是否做了正确的事情变得更加困难。

    除此之外,我更喜欢 [var]二进制 因为它的Java编码更少。