Java 操作 SHA1 加密和解密
一、引入依赖包
Maven
<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.11</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.8.1</version> </dependency>
Gradle
compile('org.apache.commons:commons-lang3:3.8.1')
compile('commons-codec:commons-codec:1.11')二、编写 Java 代码实战
新建 secrity 包放入 Digests.java、Encodes.java 和 Exceptions.java 工具类
Digests.java
package com.example.utils.secrity;
import org.apache.commons.lang3.Validate;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.SecureRandom;
public class Digests {
private static final String SHA1 = "SHA-1";
private static final String MD5 = "MD5";
private static SecureRandom random = new SecureRandom();
public Digests() {
}
public static byte[] sha1(byte[] input) {
return digest(input, "SHA-1", (byte[])null, 1);
}
public static byte[] sha1(byte[] input, byte[] salt) {
return digest(input, "SHA-1", salt, 1);
}
public static byte[] sha1(byte[] input, byte[] salt, int iterations) {
return digest(input, "SHA-1", salt, iterations);
}
private static byte[] digest(byte[] input, String algorithm, byte[] salt, int iterations) {
try {
MessageDigest digest = MessageDigest.getInstance(algorithm);
if (salt != null) {
digest.update(salt);
}
byte[] result = digest.digest(input);
for(int i = 1; i < iterations; ++i) {
digest.reset();
result = digest.digest(result);
}
return result;
} catch (GeneralSecurityException var7) {
throw Exceptions.unchecked(var7);
}
}
public static byte[] generateSalt(int numBytes) {
Validate.isTrue(numBytes > 0, "numBytes argument must be a positive integer (1 or larger)", (long)numBytes);
byte[] bytes = new byte[numBytes];
random.nextBytes(bytes);
return bytes;
}
public static byte[] md5(InputStream input) throws IOException {
return digest(input, "MD5");
}
public static byte[] sha1(InputStream input) throws IOException {
return digest(input, "SHA-1");
}
private static byte[] digest(InputStream input, String algorithm) throws IOException {
try {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
int bufferLength = 8192;
byte[] buffer = new byte[bufferLength];
for(int read = input.read(buffer, 0, bufferLength); read > -1; read = input.read(buffer, 0, bufferLength)) {
messageDigest.update(buffer, 0, read);
}
return messageDigest.digest();
} catch (GeneralSecurityException var6) {
throw Exceptions.unchecked(var6);
}
}
}Encodes.java
package com.example.utils.secrity;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.tomcat.util.codec.binary.Base64;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
public class Encodes {
private static final String DEFAULT_URL_ENCODING = "UTF-8";
private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
public Encodes() {
}
public static String encodeHex(byte[] input) {
return Hex.encodeHexString(input);
}
public static byte[] decodeHex(String input) {
try {
return Hex.decodeHex(input.toCharArray());
} catch (DecoderException var2) {
throw Exceptions.unchecked(var2);
}
}
public static String encodeBase64(byte[] input) {
return Base64.encodeBase64String(input);
}
public static String encodeUrlSafeBase64(byte[] input) {
return Base64.encodeBase64URLSafeString(input);
}
public static byte[] decodeBase64(String input) {
return Base64.decodeBase64(input);
}
public static String encodeBase62(byte[] input) {
char[] chars = new char[input.length];
for (int i = 0; i < input.length; ++i) {
chars[i] = BASE62[(input[i] & 255) % BASE62.length];
}
return new String(chars);
}
public static String escapeHtml(String html) {
return StringEscapeUtils.escapeHtml4(html);
}
public static String unescapeHtml(String htmlEscaped) {
return StringEscapeUtils.unescapeHtml4(htmlEscaped);
}
public static String escapeXml(String xml) {
return StringEscapeUtils.escapeXml(xml);
}
public static String unescapeXml(String xmlEscaped) {
return StringEscapeUtils.unescapeXml(xmlEscaped);
}
public static String urlEncode(String part) {
try {
return URLEncoder.encode(part, "UTF-8");
} catch (UnsupportedEncodingException var2) {
throw Exceptions.unchecked(var2);
}
}
public static String urlDecode(String part) {
try {
return URLDecoder.decode(part, "UTF-8");
} catch (UnsupportedEncodingException var2) {
throw Exceptions.unchecked(var2);
}
}
}Exceptions.java
package com.example.utils.secrity;
import java.io.PrintWriter;
import java.io.StringWriter;
public class Exceptions {
public Exceptions() {
}
public static RuntimeException unchecked(Throwable ex) {
return ex instanceof RuntimeException ? (RuntimeException) ex : new RuntimeException(ex);
}
public static String getStackTraceAsString(Throwable ex) {
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
return stringWriter.toString();
}
public static String getErrorMessageWithNestedException(Throwable ex) {
Throwable nestedException = ex.getCause();
return ex.getMessage() + " nested exception is " + nestedException.getClass().getName() + ":" + nestedException.getMessage();
}
public static Throwable getRootCause(Throwable ex) {
Throwable cause;
while ((cause = ex.getCause()) != null) {
ex = cause;
}
return ex;
}
public static boolean isCausedBy(Exception ex, Class... causeExceptionClasses) {
for (Object cause = ex; cause != null; cause = ((Throwable) cause).getCause()) {
Class[] arr$ = causeExceptionClasses;
int len$ = causeExceptionClasses.length;
for (int i$ = 0; i$ < len$; ++i$) {
Class<? extends Exception> causeClass = arr$[i$];
if (causeClass.isInstance(cause)) {
return true;
}
}
}
return false;
}
}三、测试
新建 EncryptSha1Util.java
package com.example.utils;
import com.example.utils.secrity.Digests;
import com.example.utils.secrity.Encodes;
/**
* HexSHA1 散列加密解密(不可逆)
*
* 此处演示的盐值为 加密密码的前16位字符
*/
public class EncryptSha1Util {
public static final String HASH_ALGORITHM = "SHA-1";
public static final int HASH_INTERATIONS = 1024;
public static final int SALT_SIZE = 8;
/**
* @param plainPassword
* @return password 加密密码(生成安全的密码,生成随机的16位salt并经过1024次 sha-1 hash)
*/
public static String entryptPassword(String plainPassword) {
byte[] salt = Digests.generateSalt(SALT_SIZE);
byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
return Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword);
}
/**
* @param plainPassword
* @param password
* @return boolean 解密判断密码是否正确
*/
public static boolean validatePassword(String plainPassword, String password) {
byte[] salt = Encodes.decodeHex(password.substring(0, 16));
byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
return password.equals(Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword));
}
public static void main(String[] args) {
String pwd = entryptPassword("Chengxumiao");
System.out.println(pwd);
System.out.println(validatePassword("Chengxumiao", pwd));
}
}四、小结
如果你的项目中引用到了,如下两个包,那么上面的创建 Digests.java、Encodes.java 和 Exceptions.java 步骤即可省略了。
这是因为,这三个java类的内容,就是在下面的两个包中,拷贝出来的。
<dependency> <groupId>io.springside</groupId> <artifactId>springside-core</artifactId> <version>4.3.0-RELEASE</version> </dependency> <dependency> <groupId>io.springside</groupId> <artifactId>springside-utils</artifactId> <version>4.3.0-RELEASE</version> </dependency>
未经允许请勿转载:程序喵 » Java 操作 SHA1 加密和解密
程序喵