|
|
导航: |
论坛 -> DELPHI技术
斑竹:liumazi,sephil |
|
作者: |
|
2019/4/8 9:50:33 |
标题: |
阿里云的这个签名算法,怎么转成Delphi的? |
浏览:2820 |
|
加入我的收藏 |
楼主: |
public class SignDemo { public static void main(String[] args) throws Exception { String accessKeyId = "testId"; String accessSecret = "testSecret"; java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));// 这里一定要设置GMT时区 java.util.Map<String, String> paras = new java.util.HashMap<String, String>(); // 1. 系统参数 paras.put("SignatureMethod", "HMAC-SHA1"); paras.put("SignatureNonce", java.util.UUID.randomUUID().toString()); paras.put("AccessKeyId", accessKeyId); paras.put("SignatureVersion", "1.0"); paras.put("Timestamp", df.format(new java.util.Date())); paras.put("Format", "XML"); // 2. 业务API参数 paras.put("Action", "SendSms"); paras.put("Version", "2017-05-25"); paras.put("RegionId", "cn-hangzhou"); paras.put("PhoneNumbers", "15300000001"); paras.put("SignName", "阿里云短信测试专用"); paras.put("TemplateParam", "{\"customer\":\"test\"}"); paras.put("TemplateCode", "SMS_71390007"); paras.put("OutId", "123"); // 3. 去除签名关键字Key if (paras.containsKey("Signature")) paras.remove("Signature"); // 4. 参数KEY排序 java.util.TreeMap<String, String> sortParas = new java.util.TreeMap<String, String>(); sortParas.putAll(paras); // 5. 构造待签名的字符串 java.util.Iterator<String> it = sortParas.keySet().iterator(); StringBuilder sortQueryStringTmp = new StringBuilder(); while (it.hasNext()) { String key = it.next(); sortQueryStringTmp.append("&").append(specialUrlEncode(key)).append("=").append(specialUrlEncode(paras.get(key))); } String sortedQueryString = sortQueryStringTmp.substring(1);// 去除第一个多余的&符号 StringBuilder stringToSign = new StringBuilder(); stringToSign.append("GET").append("&"); stringToSign.append(specialUrlEncode("/")).append("&"); stringToSign.append(specialUrlEncode(sortedQueryString)); String sign = sign(accessSecret + "&", stringToSign.toString()); // 6. 签名最后也要做特殊URL编码 String signature = specialUrlEncode(sign); System.out.println(paras.get("SignatureNonce")); System.out.println("\r\n=========\r\n"); System.out.println(paras.get("Timestamp")); System.out.println("\r\n=========\r\n"); System.out.println(sortedQueryString); System.out.println("\r\n=========\r\n"); System.out.println(stringToSign.toString()); System.out.println("\r\n=========\r\n"); System.out.println(sign); System.out.println("\r\n=========\r\n"); System.out.println(signature); System.out.println("\r\n=========\r\n"); // 最终打印出合法GET请求的URL System.out.println("http://dysmsapi.aliyuncs.com/?Signature=" + signature + sortQueryStringTmp); } public static String specialUrlEncode(String value) throws Exception { return java.net.URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~"); } public static String sign(String accessSecret, String stringToSign) throws Exception { javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA1"); mac.init(new javax.crypto.spec.SecretKeySpec(accessSecret.getBytes("UTF-8"), "HmacSHA1")); byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); return new sun.misc.BASE64Encoder().encode(signData); } }
具体的文档:https://help.aliyun.com/document_detail/101343.html 谢谢:)
----------------------------------------------
- |
作者: |
|
2019/4/8 10:52:11 |
1楼: |
不懂java的,看考什么java代码呢。
他这个签名过程并不复杂,自己实现不就完了么?
----------------------------------------------
--
|
作者: |
|
2019/4/8 11:10:50 |
2楼: |
GMT 时间 新版本 delphi 内置 HMAC SHA1 新版本 delphi 内置 randomUUID 我们是 GUID,不过,可能存在 大小写区别 是不是带括号的区别。 另外,你缺少一堆函数的 实现代码。 我们也懒得去猜。
----------------------------------------------
(C)(P)Flying Wang
|
作者: |
|
2019/4/8 11:52:07 |
3楼: |
这里主要是Hmac_sha1这个算法,其它的都好办。 uses IdGlobal, IdHashSHA, IdHMAC, IdHMACSHA1;
function HMACSHA1(const Sign, Key: String): String; var hmac: TIdHMACSHA1; hash: TIdBytes; begin LoadOpenSSLLibrary; hmac := TIdHMACSHA1.Create; try hmac.Key := TIdTextEncoding.UTF8.GetBytes(Key); hash := hmac.HashValue(TIdTextEncoding.UTF8.GetBytes(Sign)); Result := ToHex(hash); finally hmac.Free; end; end;
----------------------------------------------
Delphi爱好者。
|
作者: |
|
2019/4/8 11:55:59 |
4楼: |
1、java用randomUUID也是为了取得随机字符串,自已写个算法就行,或者用FormatDatetime('yyyyMMddhhnnss', now) 2、TreeMap,用TStringList也可以,有Name\Value.
----------------------------------------------
Delphi爱好者。
|
作者: |
|
2019/4/8 12:00:37 |
5楼: |
Hmac_sha1算法,Delphi其实一行就能搞定,当然得新版本
TNetEncoding.Base64.EncodeBytesToString(hash.THashSHA1.GetHMACAsBytes('计算内容','密钥'))
----------------------------------------------
业余编程爱好者
|
作者: |
|
2019/4/8 12:45:04 |
6楼: |
直接调用 Java 函数,不用转。
https://blog.csdn.net/dbyoung/article/details/89085406
----------------------------------------------
武汉天气不好
|
作者: |
|
2019/4/8 15:12:16 |
7楼: |
----------------------------------------------
业余编程爱好者
|
作者: |
|
2019/4/8 16:47:12 |
8楼: |
function Sign(const AData, AKey: string): string; var HashBytes: {$IFDEF IDE_XE8up}TBytes{$ELSE}TIdBytes{$ENDIF}; begin {$IFDEF IDE_XE8up} HashBytes := THashSHA1.GetHMACAsBytes(AData, AKey); Result := TNetEncoding.Base64.EncodeBytesToString(HashBytes); {$ELSE} with TIdHMACSHA1.Create do try Key := ToBytes(AKey, IndyTextEncoding_UTF8()); HashBytes := HashValue(ToBytes(AData, IndyTextEncoding_UTF8())); Result := TIdEncoderMIME.EncodeBytes(HashBytes); finally Free; end; {$ENDIF} end;
----------------------------------------------
Delphi4Linux Delphi三层/FireDAC 技术群:734515869 http://www.cnblogs.com/rtcmw
|
作者: |
|
2019/4/9 13:08:37 |
9楼: |
感谢大家的协助:) 谢谢comeheres,测试没有任何问题。 万分感谢
----------------------------------------------
-
|
作者: |
|
2019/4/9 13:10:12 |
10楼: |
comeheres代码跟艺术品一样相当美观,真的是太感谢了。
----------------------------------------------
-
|
|