当前位置: 首页 > 知识库问答 >
问题:

为什么我的PBKDF2散列方法返回不同的输出?

杜俊楚
2023-03-14

我为我的密码学初学者水平道歉
在我的项目中,我发现在将密码插入数据库之前需要对密码进行散列,因此我搜索了顶级散列算法,发现了PBKFD2和salt方法。

我这样做的方法是生成随机64char Salt并使用它来散列密码。然后将哈希密码和salt存储在我的数据库中。(注:注册时也会生成密码。这不是我的选择)

登录时,我的Servlet获取密码,然后用数据库中存储的salt散列它。但是我得到了不同的结果,这是我的代码。

 public static String generatePassword() {
          CharacterRule alphabets = new CharacterRule(EnglishCharacterData.Alphabetical);
          CharacterRule digits = new CharacterRule(EnglishCharacterData.Digit);
          

          PasswordGenerator passwordGenerator = new PasswordGenerator();
          String password = passwordGenerator.generatePassword(10, alphabets, digits);
          return password ; 
       }
       
       
       public static byte[] hashPassword( final char[] password, final byte[] salt, final int iterations, final int keyLength ) throws UnsupportedEncodingException {

            try {
                SecretKeyFactory skf = SecretKeyFactory.getInstance( "PBKDF2WithHmacSHA512" );
                PBEKeySpec spec = new PBEKeySpec( password, salt, iterations, keyLength );
                SecretKey key = skf.generateSecret( spec );
                byte[] res = key.getEncoded( );
                return res;
            } catch ( NoSuchAlgorithmException | InvalidKeySpecException e ) {
                throw new RuntimeException( e );
            }
        }
       
       public static HashMap<Integer,String> hashGeneeratedPassword(String password) throws UnsupportedEncodingException {
            HashMap<Integer,String> returnValues = new HashMap<Integer,String>() ; 
            int iterations = 20000;
            int keyLength = 512;
            char[] passwordChars = password.toCharArray();
            byte[] saltBytes = generateSalt() ; 

            byte[] hashedBytes = hashPassword(passwordChars, saltBytes, iterations, keyLength);
            String hashedString = HexUtils.toHexString(hashedBytes); 
            String saltString = HexUtils.toHexString(saltBytes) ;
            
            returnValues.put(1,hashedString); 
            returnValues.put(2, saltString);
            
            return returnValues ; 
        }
       
       private static byte[] generateSalt() {
            SecureRandom random = new SecureRandom();
            byte[] salt = new byte[32];
            random.nextBytes(salt);
            return salt;
        }
       
       public static String hashLoginPassword(String password,String salt) throws UnsupportedEncodingException {
            
            int iterations = 20000;
            int keyLength = 512;
            char[] passwordChars = password.toCharArray();
            byte[] saltBytes = salt.getBytes();

            byte[] hashedBytes = hashPassword(passwordChars, saltBytes, iterations, keyLength);
            String hashedString = HexUtils.toHexString(hashedBytes); 

            return hashedString ; 
        }

谢谢你花时间阅读我的帖子。

共有1个答案

法池暝
2023-03-14

解决方案:我用于转换字节[]salt和字节[]散列的工具出错。我用了HexUtil,一切都很好。

 类似资料:
  • 问题内容: 我运行了跟随脚本(java),它给了我奇怪的结果。有人可以帮忙解释吗? 记录结果(彼此不同): - - 背景 - - 我想将自己的keyGenrator用于@Cacheable批注(Spring和ehCache)。 在这种情况下,我发现缓存总是丢失的。 然后,我必须更改为: 谢谢 问题答案: 这是因为for 不会被覆盖。即使条目相同,也没有理由为什么的两个实例应该具有相同的值。 试试这

  • 问题内容: 我在dos.oracle.com上找到了这个 公共静态列表syncedList(列表列表) 返回由指定列表支持的同步(线程安全)列表。为了保证串行访问,至关重要的是,对后备列表的所有访问都必须通过返回的列表来完成。当用户遍历返回列表时,必须手动对其进行同步: 我的问题是:如果应该返回已经同步的列表,为什么我必须同步列表以对其进行迭代? 我只是在两个线程中访问列表:一个线程只是添加,另一

  • } 我得到了下面的结果。但是在这个结果中,高亮显示的行具有相同的列名,但是别名不同。为什么hibernate会得到相同的Cloumn? 冬眠:删除表,如果存在hibernate_sequence hibernate:删除表(如果存在)UserDetails Hibernate:如果存在,则删除表车辆Hibernate:创建表hibernate_sequence(next_val bigint)En

  • 问题内容: 问题 我有用于生成哈希的node.js模块。 最近,我注意到模块生成的哈希在新版本中有所不同: 码 Node.js v0.10.0 输出: Node.js v6.1.0 输出: 题 我想知道是什么导致了新版本中的问题,如何解决呢? 更新资料 GitHub上的类似问题: https://github.com/nodejs/node/issues/6813 https://github.c

  • 问题内容: 在下面的代码中,如果字符串在方法调用之前出现,为什么方法在字符串之前输出?为什么它会跳出输出方法的第一部分的形式,然后离开方法以输出字符串,然后返回到方法以输出方法的返回值? 码: 输出: 问题答案: 首先要注意的是,当对两个操作数使用a时,两个操作数之一是a ,表达式的结果是a 。 因此,在以下方法中调用表达式 您正在调用,因为它是type的变量。注意该方法如何接受单个参数。因此,

  • 问题内容: 由于在Java中使用了泛型,我最终不得不实现一个具有as返回类型的函数: 并且编译器要求我返回 一些东西 。现在我只是返回,但是我想知道这是否是好的编码实践… 我问的是 V oid,而不是 V oid。类, 而不是 保留关键字。 我也试过,,,,没有回报可言,但都不会在所有的工作。(出于或多或少明显的原因) 那么,如果函数的返回类型为,我应该返回什么呢? 该课程的一般用途是什么? 问题