SecretKeyFactory.getInstance(" PBKDF2WithHmacSHA512")抛出抛出:NoSuchAlgorithmException抛出、getIn

2023-09-11 05:17:31 作者:没心没肺

在研究和一些工作,我终于能哈希盐一点点密码现在有一个问题,这是对我的心目中,我已经使用了SHA-1的方法,我想尝试使用SHA512,因为我是告诉它的更好(更安全),所以,以下是我的code它有点所有的地方,但我认为它融为一体prehensible这样:

 公共类安全
{
   //调用一些参数,以后可能变化
   公共静态最后弦乐算法=PBKDF2WithHmacSHA1;
   公共静态最终诠释saltbytesize = 24;
   公共静态最终诠释hashbytesize = 24;
   公共静态最终诠释迭代= 1000;
   公共静态最终诠释iIndex = 0;
   公共静态最终诠释SINDEX = 1;
   公共静态最终诠释pbkIndex = 2;

   公共静态用户passwordHash(用户用户)抛出抛出:NoSuchAlgorithmException,
                                                       InvalidKeySpecException
   {
      SecureRandom的SR =新的SecureRandom();

      byte []的鲜红斑痣=新的字节[saltbytesize]

      sR.nextBytes(PWS);
      byte []的威尔斯亲王医院= PBKDF2(user.getPassword()toCharArray(),鲜红斑痣,迭代,hashbytesize。);

      user.setPassword(toHex(威尔斯));

      byte []的SAS =新的字节[saltbytesize]

      sR.nextBytes(SAS);

      byte []的SAH = PBKDF2(user.getsA()toCharArray(),SAS,迭代,hashbytesize。);

      user.setsA(toHex(SAH));

      user.setUserhash(PWS);

      user.setSahash(SAS);

      返回用户;
   }

   公共静态布尔hashpassword(字符串用户名,字符串密码,用户的用户)
   抛出抛出:NoSuchAlgorithmException,
          InvalidKeySpecException
   {
      byte []的PWS = user.getUserhash();

      byte []的威尔斯亲王医院= PBKDF2(password.toCharArray(),鲜红斑痣,迭代,hashbytesize);

      字符串搜索= toHex(威尔斯)+用户名;

      串搜寻= user.getPassword()+ user.getUsername();

      如果(searcher.equals(搜索))
      {
         返回true;
      }
      返回false;
   }

   私有静态byte []的PBKDF2(的char []密码,byte []的盐,
                                INT迭代,诠释字节)
      抛出抛出:NoSuchAlgorithmException,InvalidKeySpecException
   {
      PBEKeySpec规格=新PBEKeySpec(口令,盐,迭代,字节* 8);
      SecretKeyFactory SKF = SecretKeyFactory.getInstance(算法);
      返回skf.generateSecret(SPEC).getEn codeD();
   }

   私有静态字符串toHex(byte []数组)
   {
      BigInteger的BI =新的BigInteger(1,阵列);

      字符串十六进制= bi.toString(16);

      INT paddingLength =(array.length * 2) -  hex.length();

      如果(paddingLength大于0)
         返回的String.Format(%0+ paddingLength +d的,0)+六角;
      其他
         返回十六进制;
   }
}
 

这就是我的code,但我一直没能作出这样的SHA512,我已经尝试过公共静态最后弦乐算法=PBKDF2WithHmacSHA512但这似乎不是是正确的字符串算法,因为它引发了没有这样的算法例外。

我也欢迎任何改变,将使得code更好。

如上所述! 的code相关的一些线(S)

                                  

公共静态最后弦乐算法=PBKDF2WithHmacSHA512<<<<<

                        解决方案

这是不可能的开箱即用

在OpenJDK实现中仅提供了一个 PBKDF2HmacSHA1Factory.java 其中有HMACSHA1消化哈日codeD。据我测试时,Oracle JDK是不是在这个意义上的不同。

什么,你所要做的就是导出 PBKDF2HmacSHA1Factory (来吧,这是打开!)和参数添加到它的构造。你可以避开创建自己的提供的一塌糊涂,只是初始化和使用你的工厂如下:

  PBKDF_SecretKeyFactory KF =新PBKDF_SecretKeyFactory(HmacSHA512);
KeySpec KS =新PBEKeySpec(口令,盐,迭代,bitlen);
字节键[] = kf.engineGenerateSecret(KS).getEn codeD();
 
维秘秀2016年 主题 Secret Angel

After a little bit of research and some work I finally was able to hash salt the password now there is a question which is on my mind I have used the SHA1 method and I would like to try to use the SHA512 because I was told it's better (more secure) so the following is my code its a little bit all over the place but I think its comprehensible so:

public class Safety
{
   //calling some parameters for possible later changes
   public static final String algorithm = "PBKDF2WithHmacSHA1";
   public static final int saltbytesize = 24;
   public static final int hashbytesize = 24;
   public static final int iterations = 1000;
   public static final int iIndex = 0;
   public static final int sIndex = 1;
   public static final int pbkIndex = 2;

   public static Users passwordHash(Users user) throws NoSuchAlgorithmException,
                                                       InvalidKeySpecException
   {
      SecureRandom sR = new SecureRandom();

      byte[] pws = new byte[saltbytesize];

      sR.nextBytes(pws);
      byte[] pwh = pbkdf2(user.getPassword().toCharArray(), pws, iterations, hashbytesize);

      user.setPassword(toHex(pwh));

      byte[] sas = new byte[saltbytesize];

      sR.nextBytes(sas);

      byte[] sah = pbkdf2(user.getsA().toCharArray(), sas, iterations, hashbytesize);

      user.setsA(toHex(sah));

      user.setUserhash(pws);

      user.setSahash(sas);

      return user;
   }

   public static boolean hashpassword(String username, String password, Users user)
   throws NoSuchAlgorithmException,
          InvalidKeySpecException
   {
      byte[] pws = user.getUserhash();

      byte[] pwh = pbkdf2(password.toCharArray(), pws, iterations, hashbytesize);

      String searcher = toHex(pwh) + username;

      String searched = user.getPassword() + user.getUsername();

      if (searcher.equals(searched))
      {
         return true;
      }
      return false;
   }

   private static byte[] pbkdf2(char[] password, byte[] salt,
                                int iterations, int bytes)
      throws NoSuchAlgorithmException, InvalidKeySpecException
   {
      PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
      SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
      return skf.generateSecret(spec).getEncoded();
   }

   private static String toHex(byte[] array)
   {
      BigInteger bi = new BigInteger(1, array);

      String hex = bi.toString(16);

      int paddingLength = (array.length * 2) - hex.length();

      if (paddingLength > 0)
         return String.format("%0" + paddingLength + "d", 0) + hex;
      else
         return hex;
   }
}

So that's my code, however, I have not been able to make that SHA512 and I have already tried public static final String algorithm = "PBKDF2WithHmacSHA512" but that doesn't seem to be the right string for the algorithm since it throws the no such algorithm exception.

I also welcome any changes that would make the code better.

as stated above! relevant few line(s) of code

public static final String algorithm = "PBKDF2WithHmacSHA512"<<<<<

解决方案

That is not possible out of the box

The OpenJDK implementation does only provide a PBKDF2HmacSHA1Factory.java which has the "HmacSHA1" digest harcoded. As far as I tested, the Oracle JDK is not different in that sense.

What you have to do is derive the PBKDF2HmacSHA1Factory (come on, it is open!) and add a parameter to its constructor. You may avoid the mess of creating your own Provider, and just initialize and use your factory as follows:

PBKDF_SecretKeyFactory kf = new PBKDF_SecretKeyFactory("HmacSHA512");
KeySpec ks = new PBEKeySpec(password,salt,iterations,bitlen);
byte key[] = kf.engineGenerateSecret(ks).getEncoded();