java加密工具_Java版密码加密工具

1 importjava.security.SecureRandom;2 importjavax.crypto.spec.PBEKeySpec;3 importjavax.crypto.SecretKeyFactory;4 importjava.security.NoSuchAlgorithmException;5 importjava.security.spec.InvalidKeySpecException;6 importjavax.xml.bind.DatatypeConverter;7

8 public classPasswordStorage9 {10

11 @SuppressWarnings("serial")12 static public class InvalidHashException extendsException {13 publicInvalidHashException(String message) {14 super(message);15 }16 publicInvalidHashException(String message, Throwable source) {17 super(message, source);18 }19 }20

21 @SuppressWarnings("serial")22 static public class CannotPerformOperationException extendsException {23 publicCannotPerformOperationException(String message) {24 super(message);25 }26 publicCannotPerformOperationException(String message, Throwable source) {27 super(message, source);28 }29 }30

31 public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";32

33 //These constants may be changed without breaking existing hashes.

34 public static final int SALT_BYTE_SIZE = 24;35 public static final int HASH_BYTE_SIZE = 18;36 public static final int PBKDF2_ITERATIONS = 64000;37

38 //These constants define the encoding and may not be changed.

39 public static final int HASH_SECTIONS = 5;40 public static final int HASH_ALGORITHM_INDEX = 0;41 public static final int ITERATION_INDEX = 1;42 public static final int HASH_SIZE_INDEX = 2;43 public static final int SALT_INDEX = 3;44 public static final int PBKDF2_INDEX = 4;45

46 public staticString createHash(String password)47 throwsCannotPerformOperationException48 {49 returncreateHash(password.toCharArray());50 }51

52 public static String createHash(char[] password)53 throwsCannotPerformOperationException54 {55 //Generate a random salt

56 SecureRandom random = newSecureRandom();57 byte[] salt = new byte[SALT_BYTE_SIZE];58 random.nextBytes(salt);59

60 //Hash the password

61 byte[] hash =pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);62 int hashSize =hash.length;63

64 //format: algorithm:iterations:hashSize:salt:hash

65 String parts = "sha1:" +

66 PBKDF2_ITERATIONS +

67 ":" + hashSize +

68 ":" +

69 toBase64(salt) +

70 ":" +

71 toBase64(hash);72 returnparts;73 }74

75 public static booleanverifyPassword(String password, String correctHash)76 throwsCannotPerformOperationException, InvalidHashException77 {78 returnverifyPassword(password.toCharArray(), correctHash);79 }80

81 public static boolean verifyPassword(char[] password, String correctHash)82 throwsCannotPerformOperationException, InvalidHashException83 {84 //Decode the hash into its parameters

85 String[] params = correctHash.split(":");86 if (params.length !=HASH_SECTIONS) {87 throw newInvalidHashException(88 "Fields are missing from the password hash."

89 );90 }91

92 //Currently, Java only supports SHA1.

93 if (!params[HASH_ALGORITHM_INDEX].equals("sha1")) {94 throw newCannotPerformOperationException(95 "Unsupported hash type."

96 );97 }98

99 int iterations = 0;100 try{101 iterations =Integer.parseInt(params[ITERATION_INDEX]);102 } catch(NumberFormatException ex) {103 throw newInvalidHashException(104 "Could not parse the iteration count as an integer.",105 ex106 );107 }108

109 if (iterations < 1) {110 throw newInvalidHashException(111 "Invalid number of iterations. Must be >= 1."

112 );113 }114

115

116 byte[] salt = null;117 try{118 salt =fromBase64(params[SALT_INDEX]);119 } catch(IllegalArgumentException ex) {120 throw newInvalidHashException(121 "Base64 decoding of salt failed.",122 ex123 );124 }125

126 byte[] hash = null;127 try{128 hash =fromBase64(params[PBKDF2_INDEX]);129 } catch(IllegalArgumentException ex) {130 throw newInvalidHashException(131 "Base64 decoding of pbkdf2 output failed.",132 ex133 );134 }135

136

137 int storedHashSize = 0;138 try{139 storedHashSize =Integer.parseInt(params[HASH_SIZE_INDEX]);140 } catch(NumberFormatException ex) {141 throw newInvalidHashException(142 "Could not parse the hash size as an integer.",143 ex144 );145 }146

147 if (storedHashSize !=hash.length) {148 throw newInvalidHashException(149 "Hash length doesn't match stored hash length."

150 );151 }152

153 //Compute the hash of the provided password, using the same salt,154 //iteration count, and hash length

155 byte[] testHash =pbkdf2(password, salt, iterations, hash.length);156 //Compare the hashes in constant time. The password is correct if157 //both hashes match.

158 returnslowEquals(hash, testHash);159 }160

161 private static boolean slowEquals(byte[] a, byte[] b)162 {163 int diff = a.length ^b.length;164 for(int i = 0; i < a.length && i < b.length; i++)165 diff |= a[i] ^b[i];166 return diff == 0;167 }168

169 private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, intbytes)170 throwsCannotPerformOperationException171 {172 try{173 PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);174 SecretKeyFactory skf =SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);175 returnskf.generateSecret(spec).getEncoded();176 } catch(NoSuchAlgorithmException ex) {177 throw newCannotPerformOperationException(178 "Hash algorithm not supported.",179 ex180 );181 } catch(InvalidKeySpecException ex) {182 throw newCannotPerformOperationException(183 "Invalid key spec.",184 ex185 );186 }187 }188

189 private static byte[] fromBase64(String hex)190 throwsIllegalArgumentException191 {192 returnDatatypeConverter.parseBase64Binary(hex);193 }194

195 private static String toBase64(byte[] array)196 {197 returnDatatypeConverter.printBase64Binary(array);198 }199

200 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值