package cn.timer.api.callback.esign.service; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.Base64.Encoder; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; /*** * * @Description: 摘要加密算法辅助类 * @Team: 公有云技术支持小组 * @Author: 天云小生 * @Date: 2018年01月14日 */ public class DigestHelper { /*** * 获取请求签名值 * * @param data * 加密前数据 * @param key * 密钥 * @param algorithm * HmacMD5 HmacSHA1 HmacSHA256 HmacSHA384 HmacSHA512 * @param encoding * 编码格式 * @return HMAC加密后16进制字符串 * @throws Exception */ public static String getSignature(String data, String key, String algorithm, String encoding) { Mac mac = null; try { mac = Mac.getInstance(algorithm); SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(encoding), algorithm); mac.init(secretKey); mac.update(data.getBytes(encoding)); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); System.out.println("获取Signature签名信息异常:" + e.getMessage()); return null; } catch (UnsupportedEncodingException e) { e.printStackTrace(); System.out.println("获取Signature签名信息异常:" + e.getMessage()); return null; } catch (InvalidKeyException e) { e.printStackTrace(); System.out.println("获取Signature签名信息异常:" + e.getMessage()); return null; } return byte2hex(mac.doFinal()); } /*** * 计算文件的Content-MD5 * * @param filePath * @return */ public static String getContentMD5(String filePath) { Encoder encoder = Base64.getEncoder(); // 获取文件MD5的二进制数组(128位) byte[] bytes = getFileMD5Bytes128(filePath); // 对文件MD5的二进制数组进行base64编码(而不是对32位的16进制字符串进行编码) return encoder.encodeToString(bytes); } /*** * 获取文件MD5-二进制数组(128位) * * @param filePath * @return * @throws IOException */ public static byte[] getFileMD5Bytes128(String filePath) { FileInputStream fis = null; byte[] md5Bytes = null; try { File file = new File(filePath); fis = new FileInputStream(file); MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] buffer = new byte[1024]; int length = -1; while ((length = fis.read(buffer, 0, 1024)) != -1) { md5.update(buffer, 0, length); } md5Bytes = md5.digest(); fis.close(); } catch (FileNotFoundException e) { System.out.println(e.getMessage()); e.printStackTrace(); } catch (NoSuchAlgorithmException e) { System.out.println(e.getMessage()); e.printStackTrace(); } catch (IOException e) { System.out.println(e.getMessage()); e.printStackTrace(); } return md5Bytes; } /*** * 获取文件SHA256-十六进制字符串(原文SHA256摘要) * * @param filePath * @return * @throws IOException */ public static String getFileSHA256(String filePath) { FileInputStream fis = null; byte[] md5Bytes = null; String hashSHA256 = null; try { File file = new File(filePath); fis = new FileInputStream(file); MessageDigest md5 = MessageDigest.getInstance("SHA-256"); byte[] buffer = new byte[1024]; int length = -1; while ((length = fis.read(buffer, 0, 1024)) != -1) { md5.update(buffer, 0, length); } md5Bytes = md5.digest(); fis.close(); hashSHA256 = byte2hex(md5Bytes); } catch (FileNotFoundException e) { e.printStackTrace(); System.out.println(e.getMessage()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); System.out.println(e.getMessage()); } catch (IOException e) { e.printStackTrace(); System.out.println(e.getMessage()); } return hashSHA256; } /*** * 获取字符串的SHA256-十六进制字符串 * * @param str * @return * @throws IOException */ public static String getStringSHA256(String str) { byte[] md5Bytes = null; try { md5Bytes = str.getBytes("UTF-8"); // 拿到一个SHA256转换器 MessageDigest messageDigest; messageDigest = MessageDigest.getInstance("SHA-256"); // 输入的字符串转换成字节数组 byte[] inputByteArray = str.getBytes(); // inputByteArray是输入字符串转换得到的字节数组 messageDigest.update(inputByteArray); // 转换并返回结果,也是字节数组,包含16个元素 md5Bytes = messageDigest.digest(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return byte2hex(md5Bytes); } /*** * 将byte[]转成16进制字符串 * * @param data * * @return 16进制字符串 */ public static String byte2hex(byte[] data) { StringBuilder hash = new StringBuilder(); String stmp; for (int n = 0; data != null && n < data.length; n++) { stmp = Integer.toHexString(data[n] & 0XFF); if (stmp.length() == 1) hash.append('0'); hash.append(stmp); } return hash.toString(); } }