API調取
方法 | 補充說明 |
---|---|
getMD5 | 獲得MD5摘要 |
getSHA1 | 獲得SHA1摘要 |
getSHA256 | 獲得SHA256摘要 |
getSHA512 | 獲得SHA512摘要 |
getHmacMD5 | 獲得HmacMD5摘要 |
getHmacSHA1 | 獲得HmacSHA1摘要 |
getHmacSHA256 | 獲得HmacSHA256摘要 |
getHmacSHA512 | 獲得HmacSHA512摘要 |
getPBKDF2 | 默認迭代54次,產生32位密鑰 |
getRandomSalt | 獲得一個定長的鹽 |
注意:
- 不適用於SHA384等非長度的方法。如有需要,請重寫
toHex()
方法- 默認加鹽方式爲
"msg"+"salt"
,如需自定義請重寫addSalt
方法- 精簡版代碼中只包含MD5相關算法,可以參照該方法填充其它數字摘要算法。參考此處:完整摘要算法工具類Java代碼封裝
精簡版的JAVA代碼
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
public class MDBuilder {
// 散列算法
public static String getMD5(String msg, String salt){
return MDBuilder.buildMD(msg, "MD5", salt);
}
// 哈希算法
public static String getHmacMD5(String msg, String key, String salt){
return MDBuilder.buildHmacMD(msg, "HmacMD5", key, salt);
}
// 產生具體的編碼
private static String buildMD(String msg, String algs, String salt){
String retult="";
try{
MessageDigest md = MessageDigest.getInstance(algs);
byte[] buff = md.digest(addSalt(msg,salt).getBytes());
retult = toHex(buff);
}catch (Exception e){
e.printStackTrace();
}
return retult;
}
private static String buildHmacMD(String msg, String algs, String key, String salt) {
String result="";
try{
SecretKey sk = new SecretKeySpec(key.getBytes(),algs);
Mac mac = Mac.getInstance(algs);
mac.init(sk);
byte[] buff = mac.doFinal(addSalt(msg, salt).getBytes());
result = toHex(buff);
}catch (Exception e){
e.printStackTrace();
}
return result;
}
// 對鹽的添加方式
private static String addSalt(String msg, String salt){
return msg+salt;
}
// 迭代散列
private static final int PBKDF2_ITERATIONS = 54;
private static final int HASH_BIT_SIZE = 32 * 4;
/** @link https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SecretKeyFactory */
private static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";
public static String getPBKDF2(String msg, String salt, int iterations){
String result="";
try{
KeySpec spec = new PBEKeySpec(msg.toCharArray(), salt.getBytes(), iterations, HASH_BIT_SIZE);
SecretKeyFactory f = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
result = toHex(f.generateSecret(spec).getEncoded());
}catch (Exception e){
e.printStackTrace();
}
return result;
}
//將128位的二進制序列轉爲32位的16進制編碼
private static String toHex(byte[] bytes) {
StringBuilder md5str = new StringBuilder();
for (byte aByte : bytes) {
int temp = aByte;
if (temp < 0) temp += 256; // 0x8* 在經過toHexString轉化時,會被轉爲ffffff8*,需要+256保證其正值
if (temp < 16) md5str.append("0"); // 0x05 轉化會變成 5,缺少一位0
md5str.append(Integer.toHexString(temp));
}
return md5str.toString();
}
// 產生一個指定種子的Strong鹽
public static String getRandomSalt(int length, Long seed){
String salt = "default";
try{
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
if(seed!=null)random.setSeed(seed);
byte[] bytes = new byte[length / 2];
random.nextBytes(bytes);
//將byte數組轉換爲16進制的字符串
salt = DatatypeConverter.printHexBinary(bytes);
}catch (Exception e){
e.printStackTrace();
}
return salt;
}
}
完整代碼
參考此處:完整摘要算法工具類Java代碼封裝