DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: deliping
今日帖子: 1
在线用户: 1
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
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
谢谢:)
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2019/4/8 10:52:11
1楼: 不懂java的,看考什么java代码呢。

他这个签名过程并不复杂,自己实现不就完了么?
----------------------------------------------
--
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2019/4/8 11:10:50
2楼: GMT 时间
新版本 delphi 内置
HMAC SHA1
新版本 delphi 内置
randomUUID 我们是 GUID,不过,可能存在 大小写区别 是不是带括号的区别。
另外,你缺少一堆函数的 实现代码。
我们也懒得去猜。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 ghs_79 (ghs) ★☆☆☆☆ -
盒子活跃会员
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爱好者。
作者:
男 ghs_79 (ghs) ★☆☆☆☆ -
盒子活跃会员
2019/4/8 11:55:59
4楼: 1、java用randomUUID也是为了取得随机字符串,自已写个算法就行,或者用FormatDatetime('yyyyMMddhhnnss', now)
2、TreeMap,用TStringList也可以,有Name\Value.
----------------------------------------------
Delphi爱好者。
作者:
男 comeheres (tomorrow) ▲▲▲▲▲ -
普通会员
2019/4/8 12:00:37
5楼: Hmac_sha1算法,Delphi其实一行就能搞定,当然得新版本

TNetEncoding.Base64.EncodeBytesToString(hash.THashSHA1.GetHMACAsBytes('计算内容','密钥'))
----------------------------------------------
业余编程爱好者
作者:
男 dbyoung (dbyoung) ★☆☆☆☆ -
普通会员
2019/4/8 12:45:04
6楼: 直接调用 Java 函数,不用转。

https://blog.csdn.net/dbyoung/article/details/89085406
----------------------------------------------
武汉天气不好
作者:
男 comeheres (tomorrow) ▲▲▲▲▲ -
普通会员
2019/4/8 15:12:16
7楼:
按此在新窗口浏览图片


按此在新窗口浏览图片
----------------------------------------------
业余编程爱好者
作者:
男 earthsbest (全能中间件) ▲▲▲▲△ -
普通会员
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
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
2019/4/9 13:08:37
9楼: 感谢大家的协助:)
谢谢comeheres,测试没有任何问题。
万分感谢
----------------------------------------------
-
作者:
男 yesin119 (yesin119) ★☆☆☆☆ -
盒子活跃会员
2019/4/9 13:10:12
10楼: comeheres代码跟艺术品一样相当美观,真的是太感谢了。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行72.26563毫秒 RSS