开发者社区 问答 正文

API 签名机制(Java示例代码2)


4.按照 Base64 编码规则编码成字符串,获取签名值。
public static String newStringByBase64(byte[] bytes)
         throws UnsupportedEncodingException {
     if (bytes == null || bytes.length == 0) {
         return null;
     }
     return new String(new BASE64Encoder().encode(bytes));
}
public static String composeStringToSign(Map<String, String> queries) {
     String[] sortedKeys = (String[]) queries.keySet()
             .toArray(new String[0]);
     Arrays.sort(sortedKeys);
     StringBuilder canonicalizedQueryString = new StringBuilder();
     for (String key : sortedKeys) {            canonicalizedQueryString.append("&").append(percentEncode(key))
                 .append("=")
                 .append(percentEncode((String) queries.get(key)));
     }
     StringBuilder stringToSign = new StringBuilder();
     stringToSign.append("GET");
     stringToSign.append("&");
     stringToSign.append(percentEncode("/"));
     stringToSign.append("&");        stringToSign.append(percentEncode(canonicalizedQueryString.toString()
             .substring(1)));
     return stringToSign.toString();
}
public static String percentEncode(String value) {
     try {
         return value == null ? null : URLEncoder
                 .encode(value, CHARSET_UTF8).replace("+", "%20")
                 .replace("*", "%2A").replace("%7E", "~");
     } catch (Exception e) {
     }
     return "";
}
/**
  * get SignatureNonce
  ** */
public static String getUniqueNonce() {
     UUID uuid = UUID.randomUUID();
     return uuid.toString();
}
/**
  * get timestamp
  **/
public static String getISO8601Time() {
     Date nowDate = new Date();
     SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
     df.setTimeZone(new SimpleTimeZone(0, "GMT"));
     return df.format(nowDate);
}




5.添加签名。 public static String composeUrl(String endpoint, Map<String, String> queries)
         throws UnsupportedEncodingException {
     Map<String, String> mapQueries = queries;
     StringBuilder urlBuilder = new StringBuilder("");
     urlBuilder.append("http");
     urlBuilder.append("://").append(endpoint);
     if (-1 == urlBuilder.indexOf("?")) {
         urlBuilder.append("/?");
     }
     urlBuilder.append(concatQueryString(mapQueries));
     return urlBuilder.toString();
}
public static String concatQueryString(Map<String, String> parameters)
         throws UnsupportedEncodingException {
     if (null == parameters) {
         return null;
     }
     StringBuilder urlBuilder = new StringBuilder("");
     for (Map.Entry<String, String> entry : parameters.entrySet()) {
         String key = (String) entry.getKey();
         String val = (String) entry.getValue();
         urlBuilder.append(encode(key));
         if (val != null) {
             urlBuilder.append("=").append(encode(val));
         }
         urlBuilder.append("&");
     }
     int strIndex = urlBuilder.length();
     if (parameters.size() > 0) {
         urlBuilder.deleteCharAt(strIndex - 1);
     }
     return urlBuilder.toString();
}
public static String encode(String value)
         throws UnsupportedEncodingException {
     return URLEncoder.encode(value, "UTF-8");
}
}


展开
收起
云栖大讲堂 2017-10-19 15:10:22 2141 分享 版权
阿里云 AI 助理回答

为了获取签名值,您需要遵循以下步骤进行Base64编码:

  1. 计算HMAC-SHA1值

    • 使用您的AccessKey Secret(后面加上一个"&"字符)作为密钥,对之前构造的规范化请求字符串(Canonicalized Query String)应用HMAC-SHA1算法计算HMAC值。这一步骤确保了请求的完整性和机密性。
  2. 执行Base64编码

    • 将上一步得到的HMAC值使用Base64编码规则转换成字符串格式。这将生成易于传输和处理的文本格式签名值。

在Java中,实现这一过程可以通过以下方式简化表示(注意:示例代码已根据要求调整,但请确保在实际应用中使用安全且推荐的库来处理Base64编码,例如Apache Commons Codec或Java 8及以上版本的java.util.Base64):

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Map;
import java.util.TreeMap;

public class SignatureGenerator {

    public static String generateSignature(String accessKeySecret, String stringToSign) throws Exception {
        // 使用HMAC-SHA1算法计算签名
        SecretKeySpec signingKey = new SecretKeySpec((accessKeySecret + "&").getBytes("UTF-8"), "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(signingKey);
        
        // 计算HMAC值并进行Base64编码
        byte[] rawHmac = mac.doFinal(stringToSign.getBytes("UTF-8"));
        String signature = Base64.getEncoder().encodeToString(rawHmac);
        
        return signature;
    }

    public static void main(String[] args) {
        try {
            // 假设已经构建好排序并URL编码的查询参数字符串stringToSign
            String stringToSign = "您的规范化请求字符串";
            String accessKeySecret = "您的AccessKey Secret";
            
            // 生成签名
            String signature = generateSignature(accessKeySecret, stringToSign);
            System.out.println("签名值(Signature): " + signature);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

请注意,上述代码片段展示了如何基于给定的stringToSignaccessKeySecret生成签名值。在实际应用中,您需要先按照规范正确构造stringToSign,具体方法如知识库资料所述,包括排序、URL编码请求参数等步骤。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: