java 如何在数据库中存储密码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2963620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 23:42:34  来源:igfitidea点击:

how to store passwords in database?

javapasswordshash

提问by rgksugan

I use jsp and servlets in my web application. i need to store passwords in the database. I found that hashing will be the best way to do that. I used this code to do it.

我在我的 Web 应用程序中使用了 jsp 和 servlet。我需要将密码存储在数据库中。我发现散列将是最好的方法。我用这段代码来做到这一点。

                <%@page import="com.jSurvey.entity.*"    %>
    <%@page import="java.security.MessageDigest" %>
    <%@page import="java.security.NoSuchAlgorithmException" %>
    <%@page import="java.math.BigInteger" %>
    <%@page import="com.jSurvey.controller.*" %>
    <%@page import="sun.misc.BASE64Encoder" %>
    <%try {
                    String user = request.getParameter("Username");
                    String pass = request.getParameter("Password1");
                    String name = request.getParameter("Name");
                    String mail = request.getParameter("email");
                    String phone = request.getParameter("phone");
                    String add1 = request.getParameter("address1");
                    String add2 = request.getParameter("address2");
                    String country = request.getParameter("country");
                    Login login = new Login();
                    Account account = new Account();

                    login.setId(user);
                    login.setPassword(pass);
                    if (!(add1.equals(""))) {
                        account.setAddress1(add1);
                    }
                    if (!(add2.equals(""))) {
                        account.setAddress2(add2);
                    }
                    if (!(country.equals(""))) {
                        account.setCountry(country);
                    }
                    account.setId(user);
                    account.setMail_id(mail);
                    if (!(phone.equals(""))) {
                        account.setPhone_no(Long.parseLong(phone));
                    }
                    account.setName(name);
                    java.security.MessageDigest d = null;
                    d = java.security.MessageDigest.getInstance("SHA-1");
                    d.reset();
                    d.update(pass.getBytes("UTF-8"));
                    byte b[] = d.digest();
                    String tmp = (new BASE64Encoder()).encode(b);

                    account.setPassword(tmp);
                    account.setPrivilege(1);
                    LoginJpaController logcon = new LoginJpaController();
                    AccountJpaController acccon = new AccountJpaController();
                    logcon.create(login);
                    acccon.create(account);
                    session.setAttribute("user", user);
                    response.sendRedirect("dashboard.jsp");
                } catch (NumberFormatException ex) {
                    out.println("Invalid data");
                }
    %>

When i tried to print the value of tmp, i get some other value.i guess its the hash value of the password. But when i persist this data to the database the original password gets saved there other than the value in tmp..

当我尝试打印 tmp 的值时,我得到了一些其他值。我猜它是密码的哈希值。但是当我将此数据保存到数据库时,原始密码会保存在那里,而不是 tmp 中的值。

I am using java derby as the database.

我使用 java derby 作为数据库。

What is the problem???

问题是什么???

采纳答案by Bozho

  1. Add salt. For example append the email to the password before hashing. This will prevent the usage of rainbow tables
  2. Make sure you use tmpin your INSERTquery, rather than the original password.
  3. Don't use BASE64Encoder. It is part of Sun's internal libraries and is subject to change. Use commons-codecBase64
  1. 加入。例如,在散列之前将电子邮件附加到密码。这将阻止使用彩虹表
  2. 确保您tmpINSERT查询中使用,而不是原始密码。
  3. 不要使用BASE64Encoder. 它是 Sun 内部库的一部分,可能会发生变化。使用公共编解码器Base64

回答by krico

Apache has a commons library, namely Commons Codec, that makes it easier to encode the password. It will do the entire job for you.

Apache 有一个公共库,即Commons Codec,它可以更容易地对密码进行编码。它将为您完成整个工作。

import org.apache.commons.codec.digest.DigestUtils;

String pw = DigestUtils.sha256Hex(password);

Or if you want base64:

或者如果你想要 base64:

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.binary.Base64;

byte[] pwBytes = DigestUtils.sha(password);
String b64Pass = Base64.encodeBase64String(pwBytes);

回答by HZhang

Try this it should work.

试试这个它应该工作。

    import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5 {

public static void main(String[] args) {
    try{
        MessageDigest alg = MessageDigest.getInstance("MD5");
        String password = "123456";
        alg.reset();
        alg.update(password.getBytes());
        byte[] msgDigest = alg.digest();

        BigInteger number = new BigInteger(1,msgDigest);

        String str = number.toString(16);
        System.out.println(str);

    }catch(NoSuchAlgorithmException e){
        e.printStackTrace();
    }

}

}

}