SHAUtils工具类 提供5种SHA的算法和加盐处理
import android.support.annotation.Nullable;
import android.support.annotation.StringDef;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Random;
/**
* SHA 工具类
*/
class SHAUtils {
public final static String SHA1 = "sha-1";
public final static String SHA224 = "sha-224";
public final static String SHA256 = "sha-256";
public final static String SHA384 = "sha-384";
public final static String SHA512 = "sha-512";
@StringDef({SHA1, SHA224, SHA256, SHA384, SHA512})
@interface SHAType {
}
/**
* Sha加密
*
* @param string 加密字符串
* @return SHA加密结果字符串
*/
public static String SHA(String string, @Nullable @SHAType String type) {
if (TextUtils.isEmpty(string)) return "";
if (TextUtils.isEmpty(type)) type = SHA256;
try {
MessageDigest md5 = MessageDigest.getInstance(type);
byte[] bytes = md5.digest((string).getBytes());
String result = "";
for (byte b : bytes) {
String temp = Integer.toHexString(b & 0xff);
if (temp.length() == 1) {
temp = "0" + temp;
}
result += temp;
}
return result;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
*
* @param shaStr 要加密的文本
* @param type 含有加盐的HashMap:salt sha
* @return
*/
public static HashMap<String,String> SHASalt(String shaStr, @Nullable @SHAType String type) {
HashMap<String,String> resultSalt = new HashMap<>();
if (TextUtils.isEmpty(shaStr)) return resultSalt;
if (TextUtils.isEmpty(type)) type = SHA256;
String salt = generateSalt();
shaStr = shaStr + salt;
try {
MessageDigest md5 = MessageDigest.getInstance(type);
byte[] bytes = md5.digest((shaStr).getBytes());
String result = "";
for (byte b : bytes) {
String temp = Integer.toHexString(b & 0xff);
if (temp.length() == 1) {
temp = "0" + temp;
}
result += temp;
}
resultSalt.put("salt",salt);
resultSalt.put("sha",result);
return resultSalt;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return resultSalt;
}
/**
* 生成16位随机盐
*
* @return
*/
private static String generateSalt() {
// 生成一个16位的随机盐数
Random random = new Random();
StringBuilder sBuilder = new StringBuilder(16);
sBuilder.append(random.nextInt(99999999)).append(random.nextInt(99999999));
int len = sBuilder.length();
if (len < 16) {
for (int i = 0; i < 16 - len; i++) {
sBuilder.append("0");
}
}
return sBuilder.toString();
}
//加盐处理
/**
* 验证加盐后是否和原密码一致
*
* @param string 原密码
* @param md5str 加密之后的密码
* @return boolean true表示和原密码一致 false表示和原密码不一致
*/
public static boolean getSaltverifySHA(String string,String salt, @Nullable @SHAType String type, String md5str) {
return SHA(string + salt, type).equals(String.valueOf(md5str));
}
}
里面用到的工具判断类
public class TextUtils {
public static boolean isEmpty(String str) {
return null == str || str.isEmpty();
}
}
MD5Utils工具类,提供32位 16位的加密算法,和32位的加盐处理
import android.support.annotation.NonNull;
import android.support.annotation.StringDef;
import java.security.MessageDigest;
import java.util.Random;
class MD5Utils {
public final static String MD5_16 = "16";
public final static String MD5_32 = "32";
@StringDef({MD5_16, MD5_32})
@interface MD5Type {
}
/**
* byte[]字节数组 转换成 十六进制字符串
*
* @param arr 要转换的byte[]字节数组
* @return String 返回十六进制字符串
*/
private static String hex(byte[] arr) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < arr.length; ++i) {
sb.append(Integer.toHexString((arr[i] & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString();
}
/**
* MD5加密,并把结果由字节数组转换成十六进制字符串
*
* @param str 要加密的内容
* @return String 返回加密后的十六进制字符串
*/
private static String getMD5(String str) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(str.getBytes("utf-8"));
return hex(digest);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.toString());
return "";
}
}
/**
* MD5加密,并把结果由字节数组转换成十六进制字符串
*
* @param str 要加密的内容
* @return String 返回加密后的十六进制字符串
*/
public static String getMD5(String str, @NonNull @MD5Type String md5Type) {
if (md5Type == MD5_32) {
return getMD5(str);
}
return getMD5(str).substring(8, 24);
}
/**
* 生成含有随机盐的密码
*
* @param md5str 要加密的文本
* @return String 含有随机盐的加密数据
*/
public static String getSaltMD5(String md5str) {
// 生成一个16位的随机盐数
Random random = new Random();
StringBuilder sBuilder = new StringBuilder(16);
sBuilder.append(random.nextInt(99999999)).append(random.nextInt(99999999));
int len = sBuilder.length();
if (len < 16) {
for (int i = 0; i < 16 - len; i++) {
sBuilder.append("0");
}
}
// 生成最终的加密盐
String salt = sBuilder.toString();
md5str = getMD5(md5str + salt);
char[] cs = new char[48];
for (int i = 0; i < 48; i += 3) {
cs[i] = md5str.charAt(i / 3 * 2);
char c = salt.charAt(i / 3);
cs[i + 1] = c;
cs[i + 2] = md5str.charAt(i / 3 * 2 + 1);
}
return String.valueOf(cs);
}
/**
* 验证加盐后是否和原密码一致
*
* @param password 原密码
* @param md5str 加密之后的密码
* @return boolean true表示和原密码一致 false表示和原密码不一致
*/
public static boolean getSaltverifyMD5(String password, String md5str) {
char[] cs1 = new char[32];
char[] cs2 = new char[16];
for (int i = 0; i < 48; i += 3) {
cs1[i / 3 * 2] = md5str.charAt(i);
cs1[i / 3 * 2 + 1] = md5str.charAt(i + 2);
cs2[i / 3] = md5str.charAt(i + 1);
}
String salt = new String(cs2);
return getMD5(password + salt).equals(String.valueOf(cs1));
}
}