路漫漫其修远兮
吾将上下而求索

阿里云发送短信,restful-api示例

下面的示例可作为api服务的参考,将(时间+信息+url+秘钥)进行哈希加密,附到header里面发送,可以保证信息不被篡改,同时服务端设置客户端和服务端时间偏差不能大于5分钟,5分钟内同一报文不能发送两次,否则都要返回错误,这样可以保证信息正确,即使被盗取,发送给服务端也不合法,但是不能发送私密信息

下面是python示例

[root@master ~]#cat a.py 
#!/usr/bin/env python
#encoding=utf-8

import time
import base64
import hashlib
import httplib
import uuid
import hmac

class SMSClient:
    def __init__(self, app_key, app_secret):
        self.__app_key, self.__app_secret = app_key, app_secret

    def send(self, receiver, sign, template_code, parameters=''):
        print receiver, sign, template_code, parameters
        self.__host = 'sms.market.alicloudapi.com'
        self.__str_uri = '/singleSendSms?ParamString=%s&RecNum=%s&SignName=%s&TemplateCode=%s' % (parameters, receiver, sign, template_code)
        print self.__str_uri
        self.build_headers()
        self.__connection = httplib.HTTPConnection(self.__host, 80)
        self.__connection.connect()
        self.__connection.request('GET', self.__str_uri, headers=self.__headers)
        response = self.__connection.getresponse()
        print response.status, response.getheaders(), response.read()

    def build_headers(self):
        headers = dict()
        headers['X-Ca-Key'] = self.__app_key
        headers['X-Ca-Nonce'] = str(uuid.uuid4())
        headers['X-Ca-Timestamp'] = str(int(time.time() * 1000))
        headers['X-Ca-Signature-Headers'] = 'X-Ca-Key,X-Ca-Nonce,X-Ca-Timestamp'
        str_header = '\n'.join('%s:%s' % (k, headers[k]) for k in ['X-Ca-Key','X-Ca-Nonce','X-Ca-Timestamp'])
        str_to_sign = '%s\n\n\n\n\n%s\n%s' % ('GET', str_header, self.__str_uri)
        headers['X-Ca-Signature'] = self.__get_sign(str_to_sign, self.__app_secret)
        self.__headers = headers

    def __get_sign(self, source, secret):
        h = hmac.new(secret, source, hashlib.sha256)
        signature = base64.encodestring(h.digest()).strip()
        return signature

cli = SMSClient(app_key="24544195", app_secret="52a73ee2d28571115a4dead5f25a264f")
cli.send('15211112222', '名字','SMS_105630061', '{"no":"12345"}')

[root@master ~]#python a.py 
15211111111 名字 SMS_105630061 {"no":"12345"}
/singleSendSms?ParamString={"no":"12345"}&RecNum=152111111111&SignName=名字&TemplateCode=SMS_105630061
200 [('content-length', '16'), ('access-control-allow-headers', 'X-Requested-With,X-Sequence,X-Ca-Key,\
X-Ca-Secret,X-Ca-Version,X-Ca-Timestamp,X-Ca-Nonce,X-Ca-API-Key,X-Ca-Stage,X-Ca-Client-DeviceId,\
X-Ca-Client-AppId,X-Ca-Signature,X-Ca-Signature-Headers,X-Ca-Signature-Method,X-Forwarded-For,X-Ca-Date,\
X-Ca-Request-Mode,Authorization,Content-Type,Accept,Accept-Ranges,Cache-Control,Range,Content-MD5'), \
('access-control-max-age', '172800'), ('server', 'Tengine'), ('connection', 'keep-alive'), \
('date', 'Sun, 21 Jan 2018 16:18:17 GMT'), ('access-control-allow-origin', '*'), ('access-control-allow-methods',\
 'GET,POST,PUT,DELETE,HEAD,OPTIONS,PATCH'), ('content-type', 'text/plain;charset=ISO-8859-1'), ('x-ca-request-id', \
 '350CE561-6073-4FBE-AA46-99E373BA533C')] {"success":true}

下面是shell示例

[root@master ~]#cat a.sh 
#!/usr/bin/env bash

RECEIVER=15211111111      #接收方手机号
SIGN="名字"            #签名
TEMP_CODE="SMS_105630061"      #短信模板
PARAMS="{\"no\":\"123456\"}" #模板参数(json格式)

K="24544195" #AppKey,从管理控制台获取,下同
S="52a73ee2d28571115a4dead5f25a264f" #AppSecret

NL="
"
[ "x`uname`" = "xDarwin" ] && {
NONCE="`uuidgen`"
TIMESTAMP="`date +%s`500"
} || {
NONCE="`uuid`"
TIMESTAMP="`date +%s%3N`"
}
STR_HEADER="X-Ca-Key:$K${NL}X-Ca-Nonce:$NONCE${NL}X-Ca-Timestamp:$TIMESTAMP"
STR_URI="/singleSendSms?ParamString=$PARAMS&RecNum=$RECEIVER&SignName=$SIGN&TemplateCode=$TEMP_CODE"
STR_TO_SIGN="GET${NL}${NL}${NL}${NL}${NL}$STR_HEADER${NL}$STR_URI"
SIGN="`/bin/echo -n "$STR_TO_SIGN" | openssl dgst -sha256 -hmac "$S" | sed 's/.* //g' | xxd -r -p | base64`"
STR_URI="`echo "$STR_URI" | sed 's#{#\\\\{#g;s#}#\\\\}#g'`"
curl -v -H 'Accept:' \
    -H "X-Ca-Key: $K" \
    -H "X-Ca-Nonce: $NONCE" \
    -H "X-Ca-Timestamp: $TIMESTAMP" \
    -H "X-Ca-Signature-Headers: X-Ca-Key,X-Ca-Nonce,X-Ca-Timestamp" \
    -H "X-Ca-Signature: $SIGN" \
    "http://sms.market.alicloudapi.com$STR_URI"
    
[root@master ~]#bash a.sh 
* About to connect() to sms.market.alicloudapi.com port 80 (#0)
*   Trying 112.124.219.217... connected
* Connected to sms.market.alicloudapi.com (112.124.219.217) port 80 (#0)
> GET /singleSendSms?ParamString={"no":"123456"}&RecNum=15211111111&SignName=名字&TemplateCode=SMS_105630061 HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: sms.market.alicloudapi.com
> X-Ca-Key: 24548195
> X-Ca-Nonce: 930821ea-fec5-11e7-9997-00505624745f
> X-Ca-Timestamp: 1516551018689
> X-Ca-Signature-Headers: X-Ca-Key,X-Ca-Nonce,X-Ca-Timestamp
> X-Ca-Signature: 5mGyVEdPX5efeOHQRRNo9jPbDF1Knsh1Mf1JqnU8TmQ=
> 
< HTTP/1.1 200 OK
< Server: Tengine
< Date: Sun, 21 Jan 2018 16:23:21 GMT
< Content-Type: text/plain;charset=ISO-8859-1
< Content-Length: 16
< Connection: keep-alive
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET,POST,PUT,DELETE,HEAD,OPTIONS,PATCH
< Access-Control-Allow-Headers: X-Requested-With,X-Sequence,X-Ca-Key,X-Ca-Secret,X-Ca-Version,X-Ca-Timestamp,X-Ca-Nonce,\
X-Ca-API-Key,X-Ca-Stage,X-Ca-Client-DeviceId,X-Ca-Client-AppId,X-Ca-Signature,X-Ca-Signature-Headers,X-Ca-Signature-Method,\
X-Forwarded-For,X-Ca-Date,X-Ca-Request-Mode,Authorization,Content-Type,Accept,Accept-Ranges,Cache-Control,Range,Content-MD5
< Access-Control-Max-Age: 172800
< X-Ca-Request-Id: 47E5BA80-76D8-44DF-A0E6-C4312DED1826
< 
* Connection #0 to host sms.market.alicloudapi.com left intact
* Closing connection #0
{"success":true}

HMAC介绍:

Hash-based message authentication code,利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。

a specific construction for calculating a message authentication code (MAC) involving a cryptographic hash function in combination with a secret cryptographic key. As with any MAC, it may be used to simultaneously verify both the data integrity and the authenticity of a message.【主要是为了能让人对对方身份正确性和消息有效性进行验证,与消息摘要的最大不同,就是有签名密钥!】

应用:

HMAC的一个典型应用是用在“挑战/响应”(Challenge/Response)身份认证中

1. 客户端向服务器发出一个验证请求

2. 服务器接到此请求后生成一个随机数并通过网络传输给客户端(此为挑战)

3. 客户端将收到的随机数提供给ePass,由ePass使用该随机数与存储在ePass中的密钥进行HMAC-MD5运算并得到一个结果作为认证证据传给服务器(此为响应)。

4. 与此同时,服务器也使用该随机数与存储在服务器数据库中的该客户密钥进行HMAC-MD5运算,如果服务器的运算结果与客户端传回的响应结果相同,则认为客户端是一个合法用户 

安全性:

HMAC算法更象是一种加密算法,它引入了密钥,其安全性已经不完全依赖于所使用的HASH算法

1. 使用的密钥是双方事先约定的,第三方不可能知道。能够得到的信息只有作为“挑战”的随机数和作为“响应”的HMAC结果,无法根据这两个数据推算出密钥。由于不知道密钥,所以无法仿造出一致的响应。

2. HMAC与一般的加密重要的区别在于它具有“瞬时”性,即认证只在当时有效

参考文档:https://yq.aliyun.com/articles/59928

未经允许不得转载:江哥架构师笔记 » 阿里云发送短信,restful-api示例

分享到:更多 ()

评论 抢沙发

评论前必须登录!