RSA签名算法,计算调用加密报文,安全传输
生活随笔
收集整理的這篇文章主要介紹了
RSA签名算法,计算调用加密报文,安全传输
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
RSA簽名算法
1. 獲取當前的時間戳參數
2. 計算參數簽名
3. 獲取請求對象的MD5密文
4. 通過私鑰計算某個參數的RSA簽名
5. 轉換字符集到utf8
6. MD5加密字符串
7. base64編碼
8. base64編碼字符串
9. base64解碼
/*** 參數簽名算法工具類*/
public class RSAUtils {/*** 獲取當前的時間戳參數* @return*/public static String getRtick(){long timestamp = new Date().getTime();int rnd = (int)Math.random() * 1000;String rtick = timestamp + "" + rnd;return rtick;}/*** 計算參數簽名* @param developerId 開發者ID* @param privateKey 用戶私鑰* @param host 請求的HOST地址(http://ip:port/context)* @param methodName 請求的接口方法名* @param rtick 時間戳參數* @param urlParams url參數(param1=value1¶m2=value2¶m3=value3)* @param requestBody request body 參數(JSON字符串)* @return*/public static String calcRsaSign(String developerId, String privateKey, String host, String methodName, String rtick, String urlParams, String requestBody) {String url = host+methodName;Map<String, String> mySignedURLParams = new TreeMap<String, String>();mySignedURLParams.put("developerId", developerId);mySignedURLParams.put("rtick", rtick);mySignedURLParams.put("signType", "rsa");if(urlParams != null && !"".equals(urlParams)){String[] params = urlParams.split("&");for(String p1 : params){String[] p2 = p1.split("=");String key = p2[0];String value = "";if(p2.length == 2){value = p2[1];}mySignedURLParams.put(key, value);}}String requestPath;try {requestPath = new URL(url).getPath();}catch (MalformedURLException e) {throw new RuntimeException(e.getMessage(), e);}StringBuilder signStringBuilder = new StringBuilder();for (String name : mySignedURLParams.keySet()) {String value = mySignedURLParams.get(name);signStringBuilder.append(name);signStringBuilder.append("=");signStringBuilder.append(value);}signStringBuilder.append(requestPath);if (requestBody != null && !"".equals(requestBody) ) {String requestMd5 = getRequestMd5(requestBody);signStringBuilder.append(requestMd5);}String signString = signStringBuilder.toString();String rsaSign = calcRsaSign(privateKey, signString);//rsa算出來的sign,需要urlencodetry {rsaSign = URLEncoder.encode(rsaSign,"UTF-8");} catch (UnsupportedEncodingException e) {rsaSign = null;}return rsaSign;}/*** 獲取request body 的MD5* @param requestBody* @return*/private static String getRequestMd5(final String requestBody) {byte[] data;String newRequestBody = convertToUtf8(requestBody);try {data = newRequestBody.getBytes("UTF-8");}catch (UnsupportedEncodingException e) {throw new RuntimeException(e.getMessage(), e);}return md5(data);}/*** 計算參數RSA簽名* @param privateKey* @param signData* @return*/private static String calcRsaSign(String privateKey, final String signData) {byte[] data;try {data = signData.getBytes("UTF-8");}catch (UnsupportedEncodingException e) {throw new RuntimeException(e.getMessage(), e);}byte[] sign = null;// 解密由base64編碼的私鑰byte[] privateKeyBytes = base64decode(privateKey.getBytes());// 構造PKCS8EncodedKeySpec對象PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);// KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory;try {keyFactory = KeyFactory.getInstance("RSA");}catch (NoSuchAlgorithmException e) {throw new RuntimeException(e.getMessage(), e);}// 取私鑰匙對象PrivateKey priKey;try {priKey = keyFactory.generatePrivate(pkcs8KeySpec);}catch (InvalidKeySpecException e) {throw new RuntimeException(e.getMessage(), e);}// 用私鑰對信息生成數字簽名Signature signature;try {signature = Signature.getInstance("SHA1withRSA");}catch (NoSuchAlgorithmException e) {throw new RuntimeException(e.getMessage(), e);}try {signature.initSign(priKey);}catch (InvalidKeyException e) {throw new RuntimeException(e.getMessage(), e);}try {signature.update(data);sign = signature.sign();}catch (SignatureException e) {throw new RuntimeException(e.getMessage(), e);}return new String(base64encode(sign));}/*** 轉換字符集到utf8** @param src* @return*/private static String convertToUtf8(String src) {if (src == null || src.length() == 0) {return src;}if ("UTF-8".equalsIgnoreCase(Charset.defaultCharset().name())) {return src;}byte[] srcData = src.getBytes();try {return new String(srcData, "UTF-8");}catch (UnsupportedEncodingException e) {throw new RuntimeException(e.getMessage(), e);}}/*** md5* @param data* @return*/public static String md5(byte[] data) {char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};byte[] btInput = data;// 獲得MD5摘要算法的 MessageDigest 對象MessageDigest mdInst;try {mdInst = MessageDigest.getInstance("MD5");}catch (NoSuchAlgorithmException e) {throw new RuntimeException(e.getMessage(), e);}// 使用指定的字節更新摘要mdInst.update(btInput);// 獲得密文byte[] md = mdInst.digest();// 把密文轉換成十六進制的字符串形式int j = md.length;char str[] = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];str[k++] = hexDigits[byte0 >>> 4 & 0xf];str[k++] = hexDigits[byte0 & 0xf];}return new String(str);}/*** base64編碼* @param data* @return*/public static byte[] base64encode(byte[] data) {return Base64.encodeBase64(data);}/*** base64編碼字符串* @param data* @return*/public static String base64encodeString(byte[] data) {return Base64.encodeBase64String(data);}/*** base64解碼* @param data* @return*/public static byte[] base64decode(byte[] data) {try {return Base64.decodeBase64(data);} catch (Exception e) {ByteArrayOutputStream outputStream = new ByteArrayOutputStream();for (int i = 0; i < data.length; i++) {byte c = data[i];if (c == 13 || c == 10) {continue;}outputStream.write(c);}try {outputStream.close();} catch (IOException e2) {}data = outputStream.toByteArray();return Base64.decodeBase64(data);}}
}
總結
以上是生活随笔為你收集整理的RSA签名算法,计算调用加密报文,安全传输的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jar包部署shell脚本编写,在服务器
- 下一篇: 两步完成项目定时启动,java项目定时启