Java 和 Python 实现阿里云短信服务http发送

Java版:

package com.mmall.test;

/**
 * 阿里云短信http发送url构造
 * https://help.aliyun.com/document_detail/56189.html?spm=a2c4g.11186623.6.590.7cfdB8hhB8hhtr
 * @author Declan
 */
public class SignDemo {
    public static void main(String[] args) throws Exception {
        String accessKeyId = "xxxxxxxxxxxxxxxxxx";
        String accessSecret = "xxxxxxxxxxxxxxxxxxxxx";
        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();
        // 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", "13800138000");
        paras.put("SignName", "上海东方明珠");
        paras.put("TemplateParam", "{\"code\":\"1234\"}");
        paras.put("TemplateCode", "SMS_144405431");
//        paras.put("TemplateCode", "SMS_0000");
//        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"));
        //gmK7se8XVpMA+6h+E33NG8ADk7E=
        return new sun.misc.BASE64Encoder().encode(signData);
    }
}

Python 版

# coding:utf-8

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
from datetime import datetime
import uuid
from urllib import quote
from hashlib import sha1
import hmac
from hmac import new as hmac


def specialUrlEncode(value):
    newValue = quote(str(value).encode('utf-8'), safe='').replace('+', '%20').replace('*', '%2A').replace('%7E', '~')
    return newValue

def sign(accessSecret, stringToSign):
    return str(hmac(accessSecret, stringToSign, sha1).digest().encode('base64')[:-1])


def generateALiYunSmsUrl():
    accessKeyId = "xxxxxxxxxxx"
    accessSecret = "xxxxxxxxxxxxxxxxxxxxxxxxx"
    time_format_str = datetime.utcnow().isoformat()
    time_format_str = time_format_str.split(".")[0] + "Z"

    dic = {}
    dic["SignatureMethod"]="HMAC-SHA1"
    # uuid
    dic["SignatureNonce"]=str(uuid.uuid1())
    dic["AccessKeyId"] = accessKeyId
    dic["SignatureVersion"] = "1.0"
    dic["Timestamp"] = time_format_str
    dic["Format"] = "XML"
    # 业务API参数
    dic["Action"] = "SendSms"
    dic["Version"] = "2017-05-25"
    dic["RegionId"] = "cn-hangzhou"
    dic["PhoneNumbers"] = "13800138000"
    dic["SignName"] = "上海东方明珠"
    dic["TemplateParam"] = "{'code':'1234'}"
    dic["TemplateCode"] = "SMS_144405431"

    # 如果字典中有 Signature 则将其去除掉
    if dic.has_key("Signature"):
        dic.pop("Signature")


    # 构造一个list,将dic中的key放在list中,并对list进行升序排序
    list = []
    for key in dic:
        list.append(key)
    # 进行排序
    list.sort()

    sortQueryStringTmp = ''
    for key in list:
        sortQueryStringTmp = sortQueryStringTmp + '&' + specialUrlEncode(key)+'='+specialUrlEncode(dic[key])

    # 去掉第一个 '&'
    sortQueryString = sortQueryStringTmp[1:]


    #构造签名  (这里对 '/' 也要进行编码 )
    stringToSign = 'GET'+'&'+quote('/', safe='')+'&'
    stringToSign = stringToSign+specialUrlEncode(sortQueryString)

    #进行签名加密
    privateSign = sign(accessSecret+'&', stringToSign)

    #签名最后做特殊URL处理
    signature = specialUrlEncode(privateSign)

    # 得到的发送短信的url
    print "http://dysmsapi.aliyuncs.com/?Signature="+signature+sortQueryStringTmp



generateALiYunSmsUrl()


 

转载于:https://my.oschina.net/Declan/blog/2870324

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值