活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心
      文档中心

      云通信-短信

      云通信-短信

        • 产品动态公告
        • 产品介绍
        • 什么是短信服务
        • 应用场景
        • 产品优势
        • 产品功能
        • 名词解释
        • 限制说明
        • 认证
        • 计费说明
        • 计费概述
        • 产品定价
        • 欠费与退订
        • 快速入门
        • 新手指南
        • 授权IAM子账号
        • 天翼云短信服务文档使用指引
        • 使用群发助手
        • 用户指南
        • 资质
        • 资质介绍
        • 添加资质
        • 修改资质
        • 删除资质
        • 资质规范
        • 授权书模板
        • 签名
        • 签名介绍
        • 添加签名
        • 修改签名
        • 删除签名
        • 签名规范
        • 签名审核
        • 授权书模板
        • 模板
        • 模板介绍
        • 添加模板
        • 变量规范
        • 模板规范
        • 模板审核
        • 设置
        • 黑名单管理
        • 设置短信发送总量预警
        • 设置消息回执的接收方式
        • 设置短信发送频率(企业用户)
        • 费用
        • 查询发送记录
        • 发送量统计
        • API参考
        • API概览
        • 公共参数
        • 总体说明
        • 公共请求参数
        • 公共响应参数
        • 请求签名
        • 回调消息
        • 回调消息简介与配置流程
        • 上行回调
        • 事件回调
        • 状态回调
        • 模板
        • 查询模板
        • 查询模板列表
        • 添加模板
        • 删除模板
        • 修改模板
        • 签名
        • 查询签名列表
        • 添加签名
        • 删除签名
        • 修改签名
        • 查询签名
        • 发送短信
        • 查询发送记录
        • 错误码
        • 系统错误码
        • 短信发送状态码
        • 常见问题
        • 资质常见问题
        • 签名常见问题
        • 模板常见问题
        • 费用常见问题
        • 发送短信常见问题
        • 文档下载
        • 授权书模板下载
        • 相关协议
        • 云通信SLA协议手册
        • 云通信SLA协议
        • 云通信产品隐私政策说明
        • 服务协议
        • 云通信产品隐私政策声明
          无相关产品

          本页目录

          帮助中心云通信-短信API参考公共参数请求签名
          请求签名
          更新时间 2024-10-10 15:36:37
          • 新浪微博
          • 微信
            扫码分享
          • 复制链接
          最近更新时间: 2024-10-10 15:36:37
          分享文章
          • 新浪微博
          • 微信
            扫码分享
          • 复制链接
          对于每一次HTTP或HTTPS协议请求,我们会根据访问中的签名信息验证访问请求者身份。具体由使用AccessKey和SecurityKey加密验证实现。其中AccessKey是访问者身份,SecurityKey是加密签名字符串和服务器端验证签名字符串的密钥,必须严格保密谨防泄露。

          步骤一:获取AccessKey和SecurityKey

          1. 登录天翼云官网。
          2. 前往个人中心。
          3. 在安全设置中查看用户AccessKey和SecurityKey。

          步骤二:构造时间戳

          1. 构造一个eop-date的时间戳,格式为yyyymmddTHHMMSSZ,简单来说就是“年月日T时分秒Z”。

          步骤三:构造请求流水号

          1. 构造一个ctyun-eop-request-id的流水号,最好为每次请求不同,可以简单的使用UUID。

          步骤四:构造待签名字符串

          1. 构造进行签名的Header:以 header_name:header_value来一个一个通过"\n"拼接起来,强制要求ctyun-eop-request-id和eop-date这个头作为Header中的一部分。将待签名算法的Header需要进行排序(header_name以英文字母的顺序来排序),将排序后得到的列表进行遍历组装成待签名的header。
          2. 构造待签名的Query: query以&作为拼接,key和value以"="连接,排序规则使用26个英文字母的顺序来排序,Query参数全部都需要进行签名。
          3. 构造待签名的Body: 传待发送的body参数进行sha256摘要,对摘要出来的结果转十六进制。
          4. 将待签名的Header、Query、Body通过"\n"进行连接。

          步骤五:构造签名

          1. 先将SecurityKey作为密钥,eop-date作为数据,根据hmacsha256加密算法算出ktime。
          2. 将ktime作为密钥,AccessKey作为数据,根据hmacsha256加密算法算出kAk。
          3. 将kAk作为密钥,eop-date的年月日值(前8位)作为数据,根据hmacsha256加密算法算出kdate。
          4. 将kdate作为密钥,步骤二的待签名字符串作为数据,根据hmacsha256加密算法算法签名并转化为BASE64编码算出signature。

          步骤六:构造请求头

          1. 将eop-date作为Key,步骤二的结果作为Value加入http请求头中。
          2. 将ctyun-eop-request-id作为Key,步骤三的结果作为Value加入http请求头中。
          3. 将Eop-Authorization作为Key,通过字符串拼接的方式将AK、Header、Signature通过空格进行拼接,并将结果作为Value加入http请求头中。
          注意
          1. 当您通过接口发送短信之后,接口服务会及时响应并返回成功的标识,但这仅仅代表平台已经成功接收到您的发送请求了。

          2. 接下来平台会将请求转发给电信运营商,因为发送短信是异步进行的,还需要电信运营商的网络以及接收消息的手机终端支持。

          3. 如果您想第一时间知道消息的最终发送状态,故需要您在控制台的消息配置———事件回调配置中增加状态报告通知的URL,以便平台在接收到运营商的反馈消息时通知您消息的最终发送结果。

          JAVA示例

          完整的Java签名Demo代码:

          package com.example;
          
          /**
           * Hello world!
           *
           */
          import java.net.URL;
          import java.nio.charset.StandardCharsets;
          import java.security.MessageDigest;
          import java.security.NoSuchAlgorithmException;
          import java.text.SimpleDateFormat;
          import java.util.Arrays;
          import java.util.Base64;
          import java.util.Date;
          import java.util.HashMap;
          import java.util.Locale;
          import java.util.Map;
          import java.util.UUID;
          
          import org.apache.http.client.methods.CloseableHttpResponse;
          import org.apache.http.client.methods.HttpPost;
          import org.apache.http.entity.ContentType;
          import org.apache.http.entity.StringEntity;
          import org.apache.http.impl.client.CloseableHttpClient;
          import org.apache.http.impl.client.HttpClients;
          import org.apache.http.util.EntityUtils;
          
          import javax.crypto.Mac;
          import javax.crypto.spec.SecretKeySpec;
          import com.alibaba.fastjson.*;
          
          public class App {
              public static void main(String[] args) throws Exception {
                  //请参考帮助文档填写以下内容
                  Map<String, Object> params = new HashMap<>();
                  //固定参数
                  params.put("action", "SendSms");
                  //请填写您在控制台上申请并通过的短信签名。
                  params.put("signName", ""); 
                  //请填写接收短信的目标手机号,多个手机号使用英文逗号分开
                  params.put("phoneNumber", "");
                  //请填写您在控制台上申请并通过的短信模板,此模板为测试专用模板,可直接进行测试
                  params.put("templateCode", "SMS64124870510");
                  //请填写短信模板对应的模板参数和值。此值为测试模板的变量及参数,可直接使用
                  params.put("templateParam", "{\"code\":\"123456\"}");
                  params.put("extendCode", "");// 选填
                  params.put("sessionId","");  // 选填
                  String body = JSONObject.toJSONString(params);
          
                  // SETUP1:获取AccessKey和SecurityKey
                  String accessKey = "";  // 填写控制台->个人中心->安全设置->查看->AccessKey
                  String securityKey = "";// 填写控制台->个人中心->安全设置->查看->SecurityKey
          
                  // SETUP2:构造时间戳
                  SimpleDateFormat TIME_FORMATTER = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
                  SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyyMMdd");
                  Date nowdate = new Date();
                  String singerDate = TIME_FORMATTER.format(nowdate);
                  String singerDd = DATE_FORMATTER.format(nowdate);
                  System.out.println("singerDate:" + singerDate);
                  System.out.println("singerDd:" + singerDd);
          
                  // SETUP3:构造请求流水号
                  String uuId = UUID.randomUUID().toString();
                  System.out.println("uuId:" + uuId);
          
                  // SETUP4:构造待签名字符串
                  String CampmocalHeader = String.format("ctyun-eop-request-id:%s\neop-date:%s\n", uuId, singerDate);// uuid去掉this
                  // header的key按照26字母进行排序, 以&作为连接符连起来
          
                  URL url = new URL("https://sms-global.ctapi.ctyun.cn/sms/api/v1");
                  String query = url.getQuery();
                  String afterQuery = "";
                  if (query != null) {
                      String param[] = query.split("&");
                      Arrays.sort(param);
                      for (String str : param) {
                          if (afterQuery.length() < 1)
                              afterQuery = afterQuery + str;
                          else
                              afterQuery = afterQuery + "&" + str;
                      }
                  }
          
                  // String body ="";
                  String calculateContentHash = getSHA256(body); // 报文原封不动进行sha256摘要
                  String sigtureStr = CampmocalHeader + "\n" + afterQuery + "\n" + calculateContentHash;
                  System.out.println("calculateContentHash:" + calculateContentHash);
                  System.out.println("sigtureStr:" + sigtureStr);
          
                  // SETUP5:构造签名
          
                  byte[] ktime = HmacSHA256(singerDate.getBytes(), securityKey.getBytes());
                  byte[] kAk = HmacSHA256(accessKey.getBytes(), ktime);
                  byte[] kdate = HmacSHA256(singerDd.getBytes(), kAk);
                  String Signature = Base64.getEncoder().encodeToString(HmacSHA256(sigtureStr.getBytes("UTF-8"), kdate));
          
                  // SETUP6:构造请求头
                  HttpPost httpPost = new HttpPost(String.valueOf(url));
                  httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
                  httpPost.setHeader("ctyun-eop-request-id", uuId);
                  httpPost.setHeader("Eop-date", singerDate);
                  String signHeader = String.format("%s Headers=ctyun-eop-request-id;eop-date Signature=%s", accessKey,
                          Signature);
                  httpPost.setHeader("Eop-Authorization", signHeader);
                  System.out.println("Signature" + Signature);
                  System.out.println("signHeader" + signHeader);
          
                  httpPost.setEntity(new StringEntity(body, ContentType.create("application/json", "utf-8")));
          
                  try (CloseableHttpClient httpClient = HttpClients.createDefault();
          
                          CloseableHttpResponse response = httpClient.execute(httpPost)) {
                      String string = EntityUtils.toString(response.getEntity(), "utf-8");
                      System.out.println("返回结果:" + string);
                  } catch (Exception e) {
                      System.out.println(e.getMessage());
                  }
              }
          
              private static String toHex(byte[] data) {
                  StringBuilder sb = new StringBuilder(data.length * 2);
                  byte[] var2 = data;
                  int var3 = data.length;
                  for (int var4 = 0; var4 < var3; ++var4) {
                      byte b = var2[var4];
                      String hex = Integer.toHexString(b);
                      if (hex.length() == 1) {
                          sb.append("0");
                      } else if (hex.length() == 8) {
                          hex = hex.substring(6);
                      }
                      sb.append(hex);
                  }
                  return sb.toString().toLowerCase(Locale.getDefault());
              }
          
              private static String getSHA256(String text) {
                  try {
                      MessageDigest md = MessageDigest.getInstance("SHA-256");
                      // byte[] a = text.getBytes(StandardCharsets.UTF_8);
          
                      md.update(text.getBytes(StandardCharsets.UTF_8));
                      return toHex(md.digest());
                  } catch (NoSuchAlgorithmException var3) {
                      return null;
                  }
              }
          
              private static byte[] HmacSHA256(byte[] data, byte[] key) throws Exception {
                  try {
                      Mac mac = Mac.getInstance("HmacSHA256");
                      mac.init(new SecretKeySpec(key, "HmacSHA256"));
                      return mac.doFinal(data);
                  } catch (Exception e) {
                      return null;
                  }
              }
          
          }
          
          
          
          

          Golang示例

          完整的golang签名Demo代码:

          package main
          
          import (
          	"bytes"
          	"crypto/hmac"
          	"crypto/sha256"
          	"encoding/base64"
          	"encoding/hex"
          	"encoding/json"
          	"fmt"
          	"time"
          
          	"github.com/google/uuid"
          	"github.com/valyala/fasthttp"
          )
          
          const url = "https://sms-global.ctapi.ctyun.cn/sms/api/v1"
          
          func main() {
          
          	//填写控制台->个人中心->安全设置->查看->AccessKey->替代ak
          	//填写控制台->个人中心->安全设置->查看->SecurityKey->替代sk
          	c := NewClient("ak", "sk")
          
          	//请参考帮助文档填写以下内容
          	e := SendSmsPara{
          		Action:        "SendSms",               //固定参数
          		SignName:      "",                      //请填写您在控制台上申请并通过的短信签名。
          		PhoneNumber:   "",                      //请填写接收短信的目标手机号,多个手机号使用英文逗号分开
          		TemplateCode:  "SMS64124870510",        //请填写您在控制台上申请并通过的短信模板,此模板为测试专用模板,可直接进行测试
          		TemplateParam: "{\"code\":\"123456\"}", //请填写短信模板对应的模板参数和值。此值为测试模板的变量及参数,可直接使用
          		ExtendCode:    "",                      //扩展码,选填
          		SessionId:     "",                      //选填
          	}
          
          	for i := 0; i < 1; i++ {
          		c.SendSms(e) //发送短信接口
          	}
          }
          
          type SendSmsPara struct {
          	Action        string `json:"action"`
          	PhoneNumber   string `json:"phoneNumber"`
          	SignName      string `json:"signName"`
          	TemplateCode  string `json:"templateCode"`
          	TemplateParam string `json:"templateParam"`
          	ExtendCode    string `json:"extendCode"`
          	SessionId     string `json:"sessionId"`
          }
          
          type client struct {
          	ak, sk string
          }
          
          // 创建client对象
          func NewClient(ak string, sk string) *client {
          	c := &client{
          		ak: ak,
          		sk: sk,
          	}
          	return c
          }
          
          // 发送短信
          func (c *client) SendSms(e SendSmsPara) {
          	body, err := json.Marshal(e)
          	if err != nil {
          		fmt.Println("Entity convers to json failed!")
          		return
          	}
          
          	b, err := c.EopPost(body)
          	if err != nil {
          		fmt.Print("Request Error:", err.Error())
          		return
          	}
          
          	fmt.Println(string(b))
          }
          
          func (c *client) EopPost(body []byte) ([]byte, error) {
          	client := fasthttp.Client{}
          	req := fasthttp.AcquireRequest()
          	resp := fasthttp.AcquireResponse()
          	defer func() {
          		fasthttp.ReleaseResponse(resp)
          		fasthttp.ReleaseRequest(req)
          	}()
          	req.Header.SetContentType("application/json")
          	req.Header.SetMethod("POST")
          
          	// SETUP1:获取AccessKey和SecurityKey
          	accessKey := c.ak
          	securityKey := c.sk
          
          	// SETUP2:构造时间戳
          	eop_date := time.Now().Format("20060102T150405Z")
          
          	// SETUP3:构造请求流水号
          	uuid := uuid.New().String()
          
          	// SETUP4:构造待签名字符串
          	req.SetRequestURI(url)
          	args := req.URI().QueryArgs()
          	args.Sort(bytes.Compare)
          
          	headerStr := "ctyun-eop-request-id:" + uuid + "\n" + "eop-date:" + eop_date + "\n"
          	queryStr := args.String()
          	calculateContentHash := getSha256(body)
          	signStr := headerStr + "\n" + queryStr + "\n" + calculateContentHash
          
          	// SETUP5:构造签名
          	Ktime := hmacSha256(eop_date, securityKey)
          	Kak := hmacSha256(accessKey, string(Ktime))
          	Kdate := hmacSha256(eop_date[:8], string(Kak))
          	signatureDate := hmacSha256(signStr, string(Kdate))
          	signature := base64.StdEncoding.EncodeToString(signatureDate)
          
          	// SETUP6:构造请求头
          	req.Header.Add("Eop-date", eop_date)
          	req.Header.Add("ctyun-eop-request-id", uuid)
          	signatureHeader := accessKey + " Headers=ctyun-eop-request-id;eop-date Signature=" + signature
          	req.Header.Add("Eop-Authorization", signatureHeader)
          
          	req.SetBody(body)
          
          	if err := client.Do(req, resp); err != nil {
          		return nil, err
          	}
          
          	b := resp.Body()
          
          	return b, nil
          }
          
          func hmacSha256(data, secret string) []byte {
          	h := hmac.New(sha256.New, []byte(secret))
          	h.Write([]byte(data))
          
          	return h.Sum(nil)
          }
          
          func getSha256(data []byte) string {
          	hash := sha256.New()
          	hash.Write(data)
          	bytes := hash.Sum(nil)
          	return hex.EncodeToString(bytes)
          }
          
          

          nodejs示例

          完整的nodejs签名Demo代码:

          import axios from 'axios'
          import dayjs from 'dayjs'
          import * as crypto from 'crypto'
          import * as querystring from 'querystring'
          
          // shar256算法
          const sha256 = data => crypto.createHash('SHA256').update(data).digest('hex')
          // hmacsha256算法
          const hmacsha256 = (data, key) => crypto.createHmac('sha256', key).update(data).digest('hex')
          
          // SETUP1:获取AccessKey和SecurityKey
          const accessKey = ''
          const securityKey = ''
          
          const body = { foo: 'bar' }
          
          // SETUP2:构造时间戳
          const timestamp = dayjs().format('YYYYMMDDTHHmmss') + 'Z'
          
          // SETUP3:构造请求流水号
          const requestId = crypto.randomUUID()
          
          // SETUP4:构造待签名字符串
          const headerStr = `ctyun-eop-request-id:${requestId}\neop-date:${timestamp}\n\n`
          const calculateContentHash = sha256(JSON.stringify(body))
          const rawString = `${headerStr}\n${calculateContentHash}`
          
          // SETUP5:构造签名
          const signTime = hmacsha256(timestamp, securityKey)
          const signAK = hmacsha256(accessKey, Buffer.from(signTime, 'hex'))
          const signDate = hmacsha256(timestamp.slice(0, 8), Buffer.from(signAK, 'hex'))
          const sign = hmacsha256(rawString, Buffer.from(signDate, 'hex'))
          const signature = Buffer.from(sign, 'hex').toString('base64')
          
          // SETUP:6 构造请求头
          const signatureHeader = `${accessKey} Headers=ctyun-eop-request-id;eop-date Signature=${signature}`
          const headers = {
            'Content-Type': 'application/json',
            'eop-date': timestamp,
            'Eop-Authorization': signatureHeader,
            'ctyun-eop-request-id': requestId,
          }
          
          // SETUP:7 构造请求
          axios
            .post('https://sms-global.ctapi.ctyun.cn/sms/api/v1', body, {
              headers,
            })
            .then(res => {
              console.log(res.data)
            })
            .catch(err => {
              console.log(err)
            })
          

          C#示例

          完整的C#签名Demo代码:

          using Newtonsoft.Json;
          using System;
          using System.Security.Cryptography;
          using System.Text;
          using System.Net.Http;
          using System.Threading.Tasks;
          
          public class Program
          {
            private static byte[] HmacSHA256(byte[] data, byte[] signKey)
            {
              string signRet = string.Empty;
              using HMACSHA256 mac = new(signKey);
              byte[] hash = mac.ComputeHash(data);
              return hash;
            }
          
            private static string Sha256(string data)
            {
              byte[] bytes = Encoding.UTF8.GetBytes(data);
              var hash = SHA256.HashData(bytes);
          
              var strBuilder = new StringBuilder();
              for (int i = 0; i < hash.Length; i++)
              {
                strBuilder.Append(hash[i].ToString("x2"));
              }
              return strBuilder.ToString();
            }
          
            private const string sendMsgAPIUrl = "https://sms-global.ctapi.ctyun.cn/sms/api/v2";
            public static async Task Main()
            {
              string AccessKey = "";   //填写控制台->个人中心->安全设置->查看->AccessKey
              string SecurityKey = "";   //填写控制台->个人中心->安全设置->查看->SecurityKey
              var currentTime = DateTime.Now;
              var eopDate = currentTime.ToString("yyyyMMddTHHmmssZ");
              var ctyuneoprequestid = Guid.NewGuid().ToString();
          
              #region 构造待签名字符串
          
              //请参考帮助文档填写以下内容
              var sortDic = new SortedDictionary<string, string>
              {
          
                  { "action", "SendSms" },                      //固定参数
                  { "phoneNumber", "" },                        //请填写接收短信的目标手机号,多个手机号使用英文逗号分开  
                  { "signName", "天翼云测试" },                   //请填写您在控制台上申请并通过的短信签名。  
                  { "templateCode", "SMS64124870510" },         //请填写您在控制台上申请并通过的短信模板,此模板为测试专用模板,可直接进行测试  
                  { "templateParam", "{\"code\":\"123456\"}" }, //请填写短信模板对应的模板参数和值。此值为测试模板的变量及参数,可直接使用
                  { "extendCode", "" },                         //可选,非必填
                  { "sessionId", "" }                           //可选,非必填
              };
          
              var header = $"ctyun-eop-request-id:{ctyuneoprequestid}\neop-date:{eopDate}\n";
              var bodyJson = JsonConvert.SerializeObject(sortDic);
              var body = Sha256(bodyJson);
              var strS = $"{header}\n\n{body}";
          
              #endregion
          
              #region 构造签名
          
              var ktime = HmacSHA256(Encoding.UTF8.GetBytes(eopDate), Encoding.UTF8.GetBytes(SecurityKey));
              var kAk = HmacSHA256(Encoding.UTF8.GetBytes(AccessKey), ktime);
              var kdate = HmacSHA256(Encoding.UTF8.GetBytes(currentTime.ToString("yyyyMMdd")), kAk);
              var signature = Convert.ToBase64String(HmacSHA256(Encoding.UTF8.GetBytes(strS), kdate));
          
              #endregion
          
              #region 构造请求头
          
              var eopAuthorization = $"{AccessKey} Headers=ctyun-eop-request-id;eop-date Signature={signature}";
          
              #endregion
          
              // http post请求
              try
              {
                var client = new HttpClient();
                client.DefaultRequestHeaders.Add("eop-date", eopDate);
                client.DefaultRequestHeaders.Add("eop-Authorization", eopAuthorization);
                client.DefaultRequestHeaders.Add("ctyun-eop-request-id", ctyuneoprequestid);
                client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
          
                var data = new StringContent(bodyJson, Encoding.UTF8, "application/json");
                var response = await client.PostAsync(sendMsgAPIUrl, data);
                string result = await response.Content.ReadAsStringAsync();
                Console.WriteLine(result);
              }
              catch (Exception ex)
              {
                Console.WriteLine(ex.Message);
              }
          
            }
          }
          
          

          php示例

          完整的php签名Demo代码:

          <?php
          
          class Cty
          {
              public function com_create_guid() {
          
                  return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
            
                    mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
            
                    mt_rand( 0, 0xffff ),
            
                    mt_rand( 0, 0x0fff ) | 0x4000,
            
                    mt_rand( 0, 0x3fff ) | 0x8000,
            
                    mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
            
                  );
            
              }
              public function ctyun($SecurityKey,$accessKey){
                  date_default_timezone_set('Asia/Shanghai');
          
                  $uuid=$this->com_create_guid();
                  $url='https://sms-global.ctapi.ctyun.cn/sms/api/v1';
                  $time=date('Ymd', time()).'T'.date('His').'Z';
                  $timeDate=substr($time,0,8);
          
                  //****需要修改****
                  //请参考帮助文档填写以下内容
                  $body = json_encode(array(
                      'action'=>'SendSms', //固定参数
                      'phoneNumber'=>'',//请填写接收短信的目标手机号,多个手机号使用英文逗号分开
                      'signName'=>'天翼云测试',//请填写您在控制台上申请并通过的短信签名。
                      'templateCode'=>'SMS64124870510',//请填写您在控制台上申请并通过的短信模板,此模板为测试专用模板,可直接进行测试
                      'templateParam'=>'{"code":"1111"}'//请填写短信模板对应的模板参数和值。此值为测试模板的变量及参数,可直接使用
                      ));
             
            
                  $postFields = $body;
          
                  $body=bin2hex(hash("sha256", $body, true));
                  $query='';
                  $strsignature="ctyun-eop-request-id:".$uuid."\n"."eop-date:".$time."\n"."\n".$query."\n".$body;
          
                  $Ktime=$this->en($time,$SecurityKey);
          
                  $kAk=$this->en($accessKey,$Ktime);
          
                  $kdate=$this->en($timeDate,$kAk);
          
                  $signature=base64_encode(($this->en(utf8_encode($strsignature),$kdate)));
          
                  $header=array(
                      'Content-Type: application/json',
                      'ctyun-eop-request-id:'.$uuid,
                      'Eop-Authorization:'.$accessKey.' Headers=ctyun-eop-request-id;'.'eop-date Signature='.$signature,
                      'eop-date:'.$time,
                  );
          
                  $ch = curl_init();
                  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
                  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
                  curl_setopt($ch, CURLOPT_URL, $url);
                  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                  curl_setopt($ch, CURLOPT_POST, true);
                  curl_setopt($ch, CURLOPT_POSTFIELDS,$postFields);
                  curl_setopt($ch, CURLOPT_HTTPHEADER, $header);//header请求。如不需要可以去掉
          
                  $response = curl_exec($ch);
                  $response=json_decode($response,true);
                  // curl_close($ch);
                  return $response;
          
              }
              public function en($str,$pass){
                  $ret=(hash_hmac("sha256",($str) , ($pass), true));
                  return $ret;
              }
          }
          $cty= new Cty();
          //****需要修改**** 
          //填写控制台->个人中心->安全设置->查看->AccessKey
          //填写控制台->个人中心->安全设置->查看->SecurityKey
          $res=$cty->ctyun('securityKey','accessKey');
          print_r([$res]);
          

          Python示例

          完整的Python签名Demo代码:

          # -*- coding: utf8 -*-
          import requests
          import json
          import hashlib
          import base64
          import hmac
          import datetime
          import uuid
          
          METHOD_GET = 'GET'
          METHOD_POST = 'POST'
          
          #1.请填写您的AK,SK,请注意保密
          AK = ''  # 云通信控制台-》个人中心-》安全设置-》用户AccessKey,点击查看将AccessKey填入AK,
          SK = ''  # 云通信控制台-》个人中心-》安全设置-》用户AccessKey,点击查看将SecurityKey填入SK,
          #2.第二步请看文档末尾
          
          def hmac_sha256(secret, data):
              secret = bytearray(secret)
              data = bytearray(data)
              return hmac.new(secret, data, digestmod=hashlib.sha256).digest()
          
          def base64_of_hmac(data):
              return base64.b64encode(data)
          
          def get_request_uuid():
              return str(uuid.uuid1())
          
          def get_sorted_str(data):
              """
              鉴权用的参数整理
              :param data: dict 需要整理的参数
              :return: str
              """
              sorted_data = sorted(data.items(), key=lambda item: item[0])
              str_list = map(lambda x, y: '%s=%s' % (x, y), sorted_data)
              return '&'.join(str_list)
          
          def build_sign(query_params, body_params, eop_date, request_uuid):
              """
              计算鉴权字段
              :param query_params: dict get请求中的参数
              :param body_params: dict post请求中的参数
              :param eop_date: str 请求时间,格式为:'%Y%m%dT%H%M%SZ'
              :return: str
              """
              body_str = json.dumps(body_params) if body_params else ''
              body_digest = hashlib.sha256(body_str.encode('utf-8')).hexdigest()
              # 请求头中必要的两个参数
              header_str = 'ctyun-eop-request-id:%s\neop-date:%s\n' % (
                  request_uuid, eop_date)
              # url中的参数,或get参数
              # query_str = get_sorted_str(query_params)
          
              signature_str = '%s\n%s\n%s' % (header_str, "", body_digest)
          
              print_log(repr('signature_str is: %s' % signature_str))
              sign_date = eop_date.split('T')[0]
          
              # 计算鉴权密钥
              k_time = hmac_sha256(SK.encode(), eop_date.encode())
              k_ak = hmac_sha256(k_time, AK.encode())
              k_date = hmac_sha256(k_ak, sign_date.encode())
          
              signature_base64 = base64_of_hmac(
                  hmac_sha256(k_date, signature_str.encode())).decode()
              # 构建请求头的鉴权字段值
              sign_header = '%s Headers=ctyun-eop-request-id;eop-date Signature=%s' % (
                  AK, signature_base64)
              return sign_header
          
          def get_sign_headers(query_params, body):
              """
              获取鉴权用的请求头参数
              :param query_params: dict get请求中的参数
              :param body: dict post请求中的参数
              :return:
              """
              now = datetime.datetime.now()
              eop_date = datetime.datetime.strftime(now, '%Y%m%dT%H%M%SZ')
              request_uuid = get_request_uuid()
              headers = {  # 三个鉴权用的参数
                  'eop-date': eop_date,
                  'ctyun-eop-request-id': request_uuid,
                  'Eop-Authorization': build_sign(query_params="", body_params=body, eop_date=eop_date, request_uuid=request_uuid),
                  # 'Eop-Authorization': 'abc',
                  "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82"
              }
              return headers
          
          def get(url, params=None, header_params=None):
              return execute(url, method=METHOD_GET, params=params, header_params=header_params)
          
          def post(url, params=None, header_params=None):
              return execute(url, method=METHOD_POST, params=params, header_params=header_params)
          
          def execute(url, method, params=None, header_params=None):
              params = params or {}
              header_params = header_params or {}
              query_params, body = (params, {}) if method == METHOD_GET else ({}, params)
              headers = get_sign_headers(query_params, body)
              headers.update(header_params)
          
              print_log(u'url: %s' % url)
              print_log(u'请求方式: %s' % method)
              print_log(u'请求头: %s' % headers)
              print_log(u'请求参数: %s' % params)
          
              if method == METHOD_GET:
                  res = requests.get(url, params=params, headers=headers, verify=False)
              else:
                  if params:
                      res = requests.post(
                          url, json=params, headers=headers, verify=False)
                  else:
                      res = requests.post(
                          url, data=params, headers=headers, verify=False)
          
              print_log(u'返回状态码: %s' % res.status_code)
              print_log(u'返回: %s' % res.text)
              return res
          
          def print_log(log_info):
              now = datetime.datetime.now()
              log_info = u'[%s]: %s' % (str(now), log_info)
          
              print(log_info)
          
          #2.请参考帮助文档,填入以下参数:
          #https://www.ctyun.cn/document/10020426/10021544
          params = {
              'action':"SendSms", #以发送短信为例
              'signName':'',#请传入您在控制台已经申请并通过的 短信签名 例如'云通信',该签名只做示例不可用。
              'phoneNumber':'',#请传入用来接收短信的手机号,多个手机号请用 英文逗号 分隔
              'templateCode':'SMS64124870510',#请传入您在控制台已经申请并通过的 短信模板,SMS64124870510为测试专用无需申请,可直接使用。
              'templateParam':'{\"code\":\"123456\"}',#请传入短信模板的参数,左侧数据为册数模板的参数,可直接使用
              #'extendCode':
              #'sessionId':
          }
          post('https://sms-global.ctapi.ctyun.cn/sms/api/v1',params=params)
          
          
          文档反馈

          建议您登录后反馈,可在建议与反馈里查看问题处理进度

          鼠标选中文档,精准反馈问题

          选中存在疑惑的内容,即可快速反馈问题,我们会跟进处理

          知道了

          上一篇 :  公共响应参数
          下一篇 :  回调消息
          搜索 关闭
          ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
          公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
          备案 京公网安备11010802043424号 京ICP备 2021034386号
          ©2025天翼云科技有限公司版权所有
          京ICP备 2021034386号
          备案 京公网安备11010802043424号
          增值电信业务经营许可证A2.B1.B2-20090001
          用户协议 隐私政策 法律声明