博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sign签名算法一致算法-.net、java、golang
阅读量:6820 次
发布时间:2019-06-26

本文共 16313 字,大约阅读时间需要 54 分钟。

签名在接口中使用广泛,那么进行接口交互的时候为了保证数据中途不会被篡改需要进行一致性签名,下面将为大家展示个语言一致性前面的算法,同样的内容签名后的数据必须是一致的:

java版本:

1 package cn.com.gome.utils; 2  3 /** 4  * 编码 5  * @author  6  * 7  */ 8 public abstract class Constants { 9     10     /**11      * TOP默认时间格式12      */13     public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";14     15     /**16      * TOP Date默认时区17      */18     public static final String DATE_TIMEZONE = "GMT+8";19     20     /**21      * UTF-8字符集22      */23     public static final String CHARSET_UTF8 = "UTF-8";24     25     /**26      * GBK字符集27      */28     public static final String CHARSET_GBK = "GBK";29     30     /**31      * TOP JSON 应格式32      */33     public static final String FORMAT_JSON = "json";34     35     /**36      * TOP XML 应格式37      */38     public static final String FORMAT_XML = "xml";39     40     /**41      * MD5签名方式42      */43     public static final String SIGN_METHOD_MD5 = "md5";44     45     /**46      * HMAC签名方式47      */48     public static final String SIGN_METHOD_HMAC = "hmac";49     50     51 }
View Code
1 package cn.com.gome.utils;  2   3 import java.io.IOException;  4 import java.security.GeneralSecurityException;  5 import java.security.MessageDigest;  6 import java.security.NoSuchAlgorithmException;  7 import java.util.Arrays;  8 import java.util.Map;  9  10 import javax.crypto.Mac; 11 import javax.crypto.SecretKey; 12 import javax.crypto.spec.SecretKeySpec; 13  14 import cn.com.gome.utils.StringUtils; 15  16 /** 17  * 签名工具 18  * @author  19  * 20  */ 21 public class SignUtil { 22     /** 23      * 签名算法 24      *  25      * @param params 26      * @param secret 27      * @param signMethod 28      * @return 29      * @throws IOException 30      */ 31     public static String signTopRequest(Map
params, String secret, String signMethod) 32 throws IOException { 33 // 第一步:检查参数是否已经排序 34 String[] keys = params.keySet().toArray(new String[0]); 35 Arrays.sort(keys); 36 37 // 第二步:把所有参数名和参数值串在一起 38 StringBuilder query = new StringBuilder(); 39 if (Constants.CHARSET_UTF8.equals(signMethod)) { 40 query.append(secret); 41 } 42 for (String key : keys) { 43 String value = params.get(key); 44 if (StringUtils.areNotEmpty(key, value)) { 45 query.append(key).append(value); 46 } 47 } 48 49 // 第三步:使用MD5/HMAC加密 50 byte[] bytes = new byte[0]; 51 if (Constants.CHARSET_UTF8.equals(signMethod)) { 52 bytes = encryptHMAC(query.toString(), secret); 53 } else { 54 query.append(secret); 55 try { 56 bytes = encryptMD5(query.toString()); 57 } catch (NoSuchAlgorithmException e) { 58 // TODO Auto-generated catch block 59 e.printStackTrace(); 60 } 61 } 62 63 // 第四步:把二进制转化为大写的十六进制 64 return byte2hex(bytes); 65 } 66 67 /** 68 * hmac加密 69 * @param data 70 * @param secret 71 * @return 72 * @throws IOException 73 */ 74 public static byte[] encryptHMAC(String data, String secret) throws IOException { 75 byte[] bytes = null; 76 try { 77 SecretKey secretKey = new SecretKeySpec(secret.getBytes(Constants.CHARSET_UTF8), "HmacMD5"); 78 Mac mac = Mac.getInstance(secretKey.getAlgorithm()); 79 mac.init(secretKey); 80 bytes = mac.doFinal(data.getBytes(Constants.CHARSET_UTF8)); 81 } catch (GeneralSecurityException gse) { 82 throw new IOException(gse.toString()); 83 } 84 return bytes; 85 } 86 87 /** 88 * 实现md5加密 89 * @param data 90 * @return 91 * @throws IOException 92 * @throws NoSuchAlgorithmException 93 */ 94 public static byte[] encryptMD5(String data) throws IOException, NoSuchAlgorithmException { 95 96 //确定计算方法 97 MessageDigest md5 = MessageDigest.getInstance("MD5"); 98 return md5.digest(data.getBytes(Constants.CHARSET_UTF8)); 99 }100 101 /**102 * 将字节数据进行16位处理103 * @param bytes104 * @return105 */106 public static String byte2hex(byte[] bytes) {107 StringBuilder sign = new StringBuilder();108 for (int i = 0; i < bytes.length; i++) {109 String hex = Integer.toHexString(bytes[i] & 0xFF);110 if (hex.length() == 1) {111 sign.append("0");112 }113 sign.append(hex.toUpperCase());114 }115 return sign.toString();116 }117 }
View Code
1 package cn.com.gome.utils;  2   3 /**  4  * 字符串工具类  5  * @author   6  *  7  */  8 public abstract  class StringUtils {  9      10     private StringUtils() {} 11  12     /** 13      * 检查指定的字符串是否为空。 14      * 
    15 *
  • SysUtils.isEmpty(null) = true
  • 16 *
  • SysUtils.isEmpty("") = true
  • 17 *
  • SysUtils.isEmpty(" ") = true
  • 18 *
  • SysUtils.isEmpty("abc") = false
  • 19 *
20 * 21 * @param value 待检查的字符串 22 * @return true/false 23 */ 24 public static boolean isEmpty(String value) { 25 int strLen; 26 if (value == null || (strLen = value.length()) == 0) { 27 return true; 28 } 29 for (int i = 0; i < strLen; i++) { 30 if ((Character.isWhitespace(value.charAt(i)) == false)) { 31 return false; 32 } 33 } 34 return true; 35 } 36 37 /** 38 * 检查对象是否为数字型字符串,包含负数开头的。 39 */ 40 public static boolean isNumeric(Object obj) { 41 if (obj == null) { 42 return false; 43 } 44 char[] chars = obj.toString().toCharArray(); 45 int length = chars.length; 46 if(length < 1) 47 return false; 48 49 int i = 0; 50 if(length > 1 && chars[0] == '-') 51 i = 1; 52 53 for (; i < length; i++) { 54 if (!Character.isDigit(chars[i])) { 55 return false; 56 } 57 } 58 return true; 59 } 60 61 /** 62 * 检查指定的字符串列表是否不为空。 63 */ 64 public static boolean areNotEmpty(String... values) { 65 boolean result = true; 66 if (values == null || values.length == 0) { 67 result = false; 68 } else { 69 for (String value : values) { 70 result &= !isEmpty(value); 71 } 72 } 73 return result; 74 } 75 76 /** 77 * 把通用字符编码的字符串转化为汉字编码。 78 */ 79 public static String unicodeToChinese(String unicode) { 80 StringBuilder out = new StringBuilder(); 81 if (!isEmpty(unicode)) { 82 for (int i = 0; i < unicode.length(); i++) { 83 out.append(unicode.charAt(i)); 84 } 85 } 86 return out.toString(); 87 } 88 89 /** 90 * 过滤不可见字符 91 */ 92 public static String stripNonValidXMLCharacters(String input) { 93 if (input == null || ("".equals(input))) 94 return ""; 95 StringBuilder out = new StringBuilder(); 96 char current; 97 for (int i = 0; i < input.length(); i++) { 98 current = input.charAt(i); 99 if ((current == 0x9) || (current == 0xA) || (current == 0xD)100 || ((current >= 0x20) && (current <= 0xD7FF))101 || ((current >= 0xE000) && (current <= 0xFFFD))102 || ((current >= 0x10000) && (current <= 0x10FFFF)))103 out.append(current);104 }105 return out.toString();106 }107 108 }
View Code

.net版本

1  private static string SignTopRequest(IDictionary
parameters, string secret, string signMethod) 2 { 3 // 第一步:把字典按Key的字母顺序排序 4 IDictionary
sortedParams = new SortedDictionary
(parameters, StringComparer.Ordinal); 5 IEnumerator
> dem = sortedParams.GetEnumerator(); 6 7 // 第二步:把所有参数名和参数值串在一起 8 StringBuilder query = new StringBuilder(); 9 if (Constants.CHARSET_UTF_8.Equals(signMethod))10 {11 query.Append(secret);12 }13 while (dem.MoveNext())14 {15 string key = dem.Current.Key;16 string value = dem.Current.Value;17 if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))18 {19 query.Append(key).Append(value);20 }21 }22 23 // 第三步:使用MD5/HMAC加密24 byte[] bytes;25 if (Constants.CHARSET_UTF_8.Equals(signMethod))26 {27 HMACMD5 hmac = new HMACMD5(Encoding.UTF8.GetBytes(secret));28 bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));29 }30 else31 {32 query.Append(secret);33 MD5 md5 = MD5.Create();34 bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(query.ToString()));35 }36 37 // 第四步:把二进制转化为大写的十六进制38 StringBuilder result = new StringBuilder();39 for (int i = 0; i < bytes.Length; i++)40 {41 result.Append(bytes[i].ToString("X2"));42 }43 44 return result.ToString();45 }
View Code
1 namespace Sys.Common 2 { 3     public sealed class Constants 4     { 5         public static string CHARSET_ISO_2022_JP = "ISO-2022-JP"; 6         public static string CHARSET_ISO_2022_CN = "ISO-2022-CN"; 7         public static string CHARSET_ISO_2022_KR = "ISO-2022-KR"; 8         public static string CHARSET_ISO_8859_5 = "ISO-8859-5"; 9         public static string CHARSET_ISO_8859_7 = "ISO-8859-7";10         public static string CHARSET_ISO_8859_8 = "ISO-8859-8";11         public static string CHARSET_BIG5 = "BIG5";12         public static string CHARSET_GB18030 = "GB18030";13         public static string CHARSET_EUC_JP = "EUC-JP";14         public static string CHARSET_EUC_KR = "EUC-KR";15         public static string CHARSET_EUC_TW = "EUC-TW";16         public static string CHARSET_SHIFT_JIS = "SHIFT_JIS";17         public static string CHARSET_IBM855 = "IBM855";18         public static string CHARSET_IBM866 = "IBM866";19         public static string CHARSET_KOI8_R = "KOI8-R";20         public static string CHARSET_MACCYRILLIC = "x-mac-cyrillic"; //C#中"MACCYRILLIC"改名了21         public static string CHARSET_WINDOWS_1251 = "WINDOWS-1251";22         public static string CHARSET_WINDOWS_1252 = "WINDOWS-1252";23         public static string CHARSET_WINDOWS_1253 = "WINDOWS-1253";24         public static string CHARSET_WINDOWS_1255 = "WINDOWS-1255";25         public static string CHARSET_UTF_8 = "UTF-8";26         public static string CHARSET_UTF_16BE = "UTF-16BE";27         public static string CHARSET_UTF_16LE = "UTF-16LE";28         public static string CHARSET_UTF_32BE = "UTF-32BE";29         public static string CHARSET_UTF_32LE = "UTF-32LE";30         public static string CHARSET_TIS_620 = "WINDOWS-874";//C#泰语的TIS-620在.NET里叫WINDOWS-87431         //.NET直接支持GB2312编码的32         //public static string CHARSET_HZ_GB_2312 = "GB2312"; 33 34         // WARNING: Listed below are charsets which Java does not support.35         public static string CHARSET_HZ_GB_2312 = "HZ-GB-2312"; // Simplified Chinese36         public static string CHARSET_X_ISO_10646_UCS_4_3412 = "X-ISO-10646-UCS-4-3412"; // Malformed UTF-3237         public static string CHARSET_X_ISO_10646_UCS_4_2143 = "X-ISO-10646-UCS-4-2143"; // Malformed UTF-3238     }39 }
View Code

golang版本

1 package utils  2   3 import (  4     "bytes"  5     "crypto/hmac"  6     "crypto/md5"  7     "fmt"  8     "sort"  9     "strconv" 10     "strings" 11     "sync" 12 ) 13  14 //签名的字符编码类型 15 type GOLANG_CHARSET string 16  17 //字符编码类型常量 18 const ( 19     CHARSET_ISO_2022_JP            GOLANG_CHARSET = "ISO-2022-JP" 20     CHARSET_ISO_2022_CN                           = "ISO-2022-CN" 21     CHARSET_ISO_2022_KR                           = "ISO-2022-KR" 22     CHARSET_ISO_8859_5                            = "ISO-8859-5" 23     CHARSET_ISO_8859_7                            = "ISO-8859-7" 24     CHARSET_ISO_8859_8                            = "ISO-8859-8" 25     CHARSET_BIG5                                  = "BIG5" 26     CHARSET_GB18030                               = "GB18030" 27     CHARSET_EUC_JP                                = "EUC-JP" 28     CHARSET_EUC_KR                                = "EUC-KR" 29     CHARSET_EUC_TW                                = "EUC-TW" 30     CHARSET_SHIFT_JIS                             = "SHIFT_JIS" 31     CHARSET_IBM855                                = "IBM855" 32     CHARSET_IBM866                                = "IBM866" 33     CHARSET_KOI8_R                                = "KOI8-R" 34     CHARSET_MACCYRILLIC                           = "x-mac-cyrillic" 35     CHARSET_WINDOWS_1251                          = "WINDOWS-1251" 36     CHARSET_WINDOWS_1252                          = "WINDOWS-1252" 37     CHARSET_WINDOWS_1253                          = "WINDOWS-1253" 38     CHARSET_WINDOWS_1255                          = "WINDOWS-1255" 39     CHARSET_UTF_8                                 = "UTF-8" 40     CHARSET_UTF_16BE                              = "UTF-16BE" 41     CHARSET_UTF_16LE                              = "UTF-16LE" 42     CHARSET_UTF_32BE                              = "UTF-32BE" 43     CHARSET_UTF_32LE                              = "UTF-32LE" 44     CHARSET_TIS_620                               = "WINDOWS-874" 45     CHARSET_HZ_GB_2312                            = "HZ-GB-2312" 46     CHARSET_X_ISO_10646_UCS_4_3412                = "X-ISO-10646-UCS-4-3412" 47     CHARSET_X_ISO_10646_UCS_4_2143                = "X-ISO-10646-UCS-4-2143" 48 ) 49  50 //当前类的指针 51 var sign *signUtils 52  53 //同步锁 54 var signone sync.Once 55  56 //签名类 57 type signUtils struct { 58     mapExtend *MapExtend 59 } 60  61 //实例化签名 62 func Sign() *signUtils { 63     signone.Do(func() { 64         sign = new(signUtils) 65         sign.mapExtend = new(MapExtend) 66     }) 67     return sign 68 } 69  70 /** 71 签名算法 72 parameters 要签名的数据项 73 secret 生成的publicKey 74 signMethod 签名的字符编码 75 */ 76 func (s *signUtils) SignTopRequest(parameters *map[string]string, secret string, signMethod GOLANG_CHARSET) string { 77     /** 78     1、第一步:把字典按Key的字母顺序排序 79     2、第二步:把所有参数名和参数值串在一起 80     3、第三步:使用MD5/HMAC加密 81     4、第四步:把二进制转化为大写的十六进制 82     */ 83  84     //第一步:把字典按Key的字母顺序排序 85     keys, err := s.mapExtend.GetKeys(parameters) 86     if err != nil { 87         //        goto result 88         return "" 89     } 90     sort.Strings(keys) 91     //第二步:把所有参数名和参数值串在一起 92     var bb bytes.Buffer 93     if CHARSET_UTF_8 == signMethod { 94         bb.WriteString(secret) 95     } 96     for i, v := range keys { 97         _ = i 98         val := (*parameters)[v] 99         if len(val) > 0 {100             bb.WriteString(v)101             bb.WriteString(val)102         }103     }104     fmt.Println(bb.String())105     //第三步:使用MD5/HMAC加密106     b := make([]byte, 0)107     if CHARSET_UTF_8 == signMethod {108         h := hmac.New(md5.New, s.GetUtf8Bytes(secret))109         h.Write(bb.Bytes())110         b = h.Sum(nil)111     } else {112         bb.WriteString(secret)113         md5instence := md5.New()114         md5instence.Write(bb.Bytes())115         b = md5instence.Sum(nil)116     }117     //第四步:把二进制转化为大写的十六进制118     var result bytes.Buffer119     for i := 0; i < len(b); i++ {120         s := strconv.FormatInt(int64(b[i]&0xff), 16)121         if len(s) == 1 {122             result.WriteString("0")123         }124         result.WriteString(s)125     }126     //返回签名完成的字符串127     return strings.ToUpper(result.String())128 }129 130 //默认utf8字符串131 func (s *signUtils) GetUtf8Bytes(str string) []byte {132     b := []byte(str)133     return b134 }
View Code

 

转载于:https://www.cnblogs.com/linuxone/p/6709276.html

你可能感兴趣的文章