【问题标题】:Converting plaintext passwords to bycrypt in MySQL and/or java在 MySQL 和/或 java 中将明文密码转换为 bcrypt
【发布时间】:2013-09-10 22:04:29
【问题描述】:

我继承了一个项目,其中密码以明文形式存储在数据库的表中。如果我要转换为 MD5,我会做类似的事情

UPDATE users SET encrypted_password = MD5(password);

我使用的是 java BCrypt 类而不是 MD5。该表有约 300 万用户。是否有一种最佳方式将每个明文密码加密到新的“encrypted_pa​​ssword”列中。

我能想到的唯一方法是遍历每个用户的 ResultSet,选择明文密码,bcrypt,然后更新行。有人告诉我,这需要半个永恒。有更快的吗?

【问题讨论】:

    标签: java mysql sql bcrypt


    【解决方案1】:

    我认为这可能是唯一的方法,而且确实需要很长时间,但我最终只是编写了一个简单的类来遍历每一行并 BCrypt 明文密码并存储它。出于理智,我在 BCrypting 之后检查了匹配是否良好:我从未遇到任何不匹配。 Encryption 类只是我与许多其他加密方法一起使用的实际类的一个片段,为了清楚起见,我只包含了相关方法。如果对任何人有帮助,代码如下:

    public class Bcrypter {
    
        public static void main(String args []) {
    
            int lower = Integer.parseInt(args[0]);
            int upper = Integer.parseInt(args[1]);
    
            Connection conn = null;
            PreparedStatement pstmt = null;
            ResultSet rs = null;
    
            int row = 0;
            try {
                conn = Database.getConnection();
                pstmt = conn.prepareStatement("SELECT id, user_pass, user_pass_bcrypt FROM users ORDER BY id LIMIT ?, ?",
                        ResultSet.TYPE_SCROLL_INSENSITIVE,
                        ResultSet.CONCUR_UPDATABLE);
                pstmt.setInt(1, lower);
                pstmt.setInt(2, upper);
                rs = pstmt.executeQuery();
    
                while (rs.next()) {
    
                    String user_pass = rs.getString("user_pass");
                    String user_pass_encrypted = Encryption.encrypt(user_pass);
    
                    if (Encryption.isMatch(user_pass, user_pass_encrypted)) {
                        rs.updateString("user_pass_bcrypt", user_pass_encrypted);
                        rs.updateRow();
    
                        if (++row % 10000 == 0) {
                            System.out.println(row);
                        }
    
                    } else {
                        System.out.println("Mismatch " + user_pass);
                    }
                }
                System.out.print("DONE");
    
            } catch (SQLException e) {
                e.printStackTrace();
                System.out.print(e);
            } finally {
                Database.closeConnection(conn, pstmt, rs);
            }
        }
    }
    
    
    public final class Encryption {
    
        private Encryption() {
            // can't instantiate
        }
    
        /**
         * Encrypts a password. The gensalt() method's default param is
         * 10 but it's lowered here, assuming better performance.
         */
        public static String encrypt (String plainPassword) {
            return BCrypt.hashpw(plainPassword, BCrypt.gensalt(5));
        }
    
        /**
         * Checks whether a plaintext password matches one that has been
         * hashed previously
         */
        public static Boolean isMatch(String plainPassword, String hashedPassword) {
            return (BCrypt.checkpw(plainPassword, hashedPassword));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-04-23
      • 2014-01-09
      • 2011-05-30
      • 2019-01-09
      • 2011-02-26
      • 2019-09-05
      • 1970-01-01
      • 2013-07-08
      • 2013-06-23
      相关资源
      最近更新 更多