简体   繁体   English

使用Java中的SHA-256算法比较使用相同盐的两个哈希密码,Spring安全吗?

[英]Compare two hashed password using same salt using SHA-256 algorith in Java, Spring security?

I need some guidance on the scenario where I need to check the password coming from UI form (ie, Authentication object) which I need to hashed using SHA-256 + constant salt (before making comparison) and password coming from DB (DB also has hashed password + salt) using Spring Security. 对于需要检查来自UI表单(即Authentication对象)的密码的场景,我需要一些指导,我需要使用SHA-256 + constant salt (在进行比较之前)和来自数据库的密码(数据库也具有哈希密码+ salt)使用Spring Security。

I am looking to compare these two different hashed value generated using same SALT value. 我正在寻找比较使用相同SALT值生成的这两个不同的哈希值。 How we can do it in java? 我们如何在Java中做到这一点? Could anyone please share me a sample code? 谁能给我分享示例代码?

You could simply compare the two password strings passwordA.equals(passwordB) ... 您可以简单地比较两个密码字符串passwordA.equals(passwordB) ...

This has some security shortcomings: 这有一些安全缺陷:

  1. Passwords should not be handled as strings, but as char or byte arrays: see here why 密码不应以字符串形式处理,而应以char或字节数组形式处理: 请参阅此处的原因

  2. An Equal comparison is (theoretically) vulnerable to a timing-attack: see a discussion about a solution in java 相等比较(理论上)容易受到定时攻击的影响: 请参阅有关Java解决方案的讨论

  3. It might be wise to use standard-tool to do security related things (even when they seem to be simple). 使用标准工具来进行与安全性相关的事情(即使它们看起来很简单)可能是明智的。 Spring security has a ton of tools that can do that for you. Spring Security有大量可以帮助您完成此任务的工具。 Have a look at BCryptPasswordEncoder for example. BCryptPasswordEncoder为例。 Using well tested and maintained frameworks for security purposes is always a good idea. 为安全起见,使用经过良好测试和维护的框架始终是一个好主意。

      BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String hashedPassword = passwordEncoder.encode(password); ... boolean result = passwordEncoder.matches(rawPassword, hashedPassword); 

Also : Use a proper Algorithm for Password-Hashing! 另外 :使用正确的密码哈希算法! See this Answer on SO for some proposals 有关一些建议,请参见此答复。

SHA-256 is not one of them. SHA-256不是其中之一。 Spring Security gives you the right tools for the jobs, so you could just use them. Spring Security为您提供了正确的作业工具,因此您可以使用它们。

It looks to me you're looking to compare two separate hashed values created using same salt. 在我看来,您正在寻找比较使用相同salt创建的两个单独的哈希值。 Am I right ? 我对吗 ? If yes, so here is the sample program taking a reference from https://ashishpshukla.wordpress.com/2010/07/02/sample-java-code-for-password-encryption-using-secure-hash-algorithm-sha-256/ 如果是,那么以下示例程序是从https://ashishpshukla.wordpress.com/2010/07/02/sample-java-code-for-password-encryption-using-secure-hash-algorithm-sha引用的示例程序-256 /

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class PasswordEncoder {
    private static PasswordEncoder instance;
    private final static int ITERATION_COUNT = 5;

    private PasswordEncoder() {  }

    public static synchronized PasswordEncoder getInstance() {
        if (instance == null) {
            PasswordEncoder returnPasswordEncoder = new PasswordEncoder();
            return returnPasswordEncoder;
        }
        else
            return instance;
    }

    public synchronized String encode(String password, String saltKey)throws NoSuchAlgorithmException, IOException {
        String encodedPassword = null;
        byte[] salt = base64ToByte(saltKey);

        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.reset();
        digest.update(salt);

        byte[] btPass = digest.digest(password.getBytes("UTF-8"));
        for (int i = 0; i < ITERATION_COUNT; i++) {
            digest.reset();
            btPass = digest.digest(btPass);
        }

        encodedPassword = byteToBase64(btPass);
        return encodedPassword;
    }

    private byte[] base64ToByte(String str) throws IOException {
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] returnbyteArray = decoder.decodeBuffer(str);
        return returnbyteArray;
    }

    private String byteToBase64(byte[] bt) {
        BASE64Encoder endecoder = new BASE64Encoder();
        String returnString = endecoder.encode(bt);
        return returnString;
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
        String password = "Secrete@343";
        String saltKey = "PveFT7isDjGYFTaYhc2Fzw==";
        String hash1,hash2 = null;

        // Assume from UI
        PasswordEncoder encoder1 = PasswordEncoder.getInstance();
        hash1 = encoder1.encode(password, saltKey);
        System.out.println(hash1);

        // Assume the same present in db
        PasswordEncoder encoder2 = PasswordEncoder.getInstance();
        hash2 = encoder2.encode(password, saltKey);
        System.out.println(hash2);

        if(hash1.equalsIgnoreCase(hash2))
            System.out.println("Both hash Matches..");
        else
            System.out.println("Hash matches fails..");
    }
}

The output: 输出:

8WgbLik5EbdtJY4OWm2ZQ0tHiU2lmvXNVrPhFDz3W2Y=
8WgbLik5EbdtJY4OWm2ZQ0tHiU2lmvXNVrPhFDz3W2Y=
Both hash Matches..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM