开发者社区> 问答> 正文

使用阿里大鱼发送短信,出现错误:SignatureDoesNotMatch : Specified signature is not matched with our calculation.

使用阿里大鱼.net版本的SDK,发送短信,出现错误:SignatureDoesNotMatch : Specified signature is not matched with our calculation.

展开
收起
阿刘123456 2017-10-25 09:53:54 11648 0
3 条回答
写回答
取消 提交回答
  • 我也遇到这个问题, 明确按文档 提供的 参数, 移动的 短信平台 则相对简单,不需要这么多参数,当然也不会签名错误!
    我用的 是 Delphi :

    /// 薄皮虎(QQ:12161881)
    ///
    /// 利用阿里云短信服务接口发短信
    /// 阿里云短信服务:https://dayu.aliyun.com/
    /// 阿里云短信接口文档:https://help.aliyun.com/document_detail/56189.html?spm=5176.doc55284.6.567.eJGSTC
    ///
    /// 分配给应用的AccessKey
    /// 分配给应用的AccessSecret
    /// 格式为yyyy-MM-dd’T’HH:mm:ss’Z’
    /// 没传默认为JSON,可选填值:XML
    /// 建议固定值:HMAC-SHA1
    /// 建议固定值:1.0
    /// 用于请求的防重放攻击,每次请求唯一,GUID
    /// 发送短信API的值为:SendSms
    /// 短信API的值为:2017-05-25
    /// 短信API的值为:cn-hangzhou
    /// 接收手机号码
    /// 短信签名,传入的短信签名必须是在阿里云“管理中心-短信签名管理”中的可用签名
    /// 短信模板ID
    /// 短信模板变量,例如:{"code":"1234","product":"alidayu"}
    /// 业务id
    /// 请求ID
    /// 状态码-返回OK代表请求成功,其他错误码详见错误码列表
    /// 状态码的描述
    /// 发送回执ID,可根据该ID查询具体的发送状态
    procedure SendSMS(const AccessKeyId, AccessSecret, Timestamp, Format,
    SignatureMethod, SignatureVersion, SignatureNonce, Action, Version,
    RegionId, PhoneNumbers, SignName, TemplateCode, TemplateParam, OutId: string;
    var RequestId, Code, sMessage, BizId, CryptData, CryptResult: string);

    // 签名方法详见https://help.aliyun.com/document_detail/56189.html?spm=5176.doc55284.6.567.eJGSTC
    function MakeSign(const AParams: TStringList; const AppSecret: string; var CryptData: string): string;
    var

    I: Integer;
    Data, AccessSecret, ParamName, ParamValue, sSigned: string;
    Bs: TBytes;

    begin

    // 参数排序
    AParams.CaseSensitive := True;   // 区分大小写
    AParams.Sort;
    
    // 参数拼接
    Data := '';
    for I := 0 to AParams.Count - 1 do
    begin
      ParamName := Copy(AParams[I], 0, Pos('=',AParams[I])-1);
      ParamValue := Copy(AParams[I], Pos('=',AParams[I])+1,Length(AParams[I])-Pos('=',AParams[I])+1);
      Data := Data + HttpEncode(ParamName).Replace('+','%20').Replace('*','%2A').Replace('%7E','~')+
       '=' + HttpEncode(ParamValue).Replace('+','%20').Replace('*','%2A').Replace('%7E','~') + '&';
    end;
    
    Data := LeftStr(Data, Data.Length-1);
    Data := 'POST&%2F&'+HttpEncode(Data);
    CryptData := UTF8Encode(Data);
    AccessSecret :=  UTF8Encode(AppSecret.Trim+'&');
    
    // HMACSHA1 + BASE64 算法
    Bs := THashSHA1.GetHMACAsBytes(CryptData, AccessSecret);
    sSigned := TIdEncoderMIME.EncodeBytes(TIdBytes(Bs));
    Result := HttpEncode(sSigned);

    end;

    var
    HTTP: TNetHTTPClient;
    JO: TJSONObject;
    Params: TStringList;
    Response, ResultMsg: string;
    begin

    HTTP := TNetHTTPClient.Create(nil);
    Params := TMyStringList.Create;
    try

    Params.Values['AccessKeyId'] := AccessKeyId;
    Params.Values['Timestamp'] := Timestamp;
    Params.Values['Format'] := Format;
    Params.Values['SignatureMethod'] := SignatureMethod;
    Params.Values['SignatureVersion'] := SignatureVersion;
    Params.Values['SignatureNonce'] := SignatureNonce;
    
    Params.Values['Action'] := Action;
    Params.Values['Version'] := Version;
    Params.Values['RegionId'] := RegionId;
    Params.Values['PhoneNumbers'] := PhoneNumbers;
    Params.Values['SignName'] := SignName;
    
    Params.Values['TemplateCode'] := TemplateCode;
    Params.Values['TemplateParam'] := TemplateParam;
    Params.Values['OutId'] := OutId;
    
    CryptResult := MakeSign(Params, AccessSecret, CryptData);
    
    Params.Insert(0, 'Signature=' + CryptResult);
    
    HTTP.ContentType := 'application/x-www-form-urlencoded';  // 提交数据方式
    try
      Response := HTTP.Post('https://dysmsapi.aliyuncs.com/', Params).ContentAsString();
    except
      on E: Exception do
      begin
        ResultMsg := E.Message;
        Exit;
      end;
    end;
    
    JO := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    try
      if JO <> nil then
      begin
        JO.TryGetValue<string>('RequestId', RequestId);
        JO.TryGetValue<string>('Code', Code);
        JO.TryGetValue<string>('Message', sMessage);
        JO.TryGetValue<string>('BizId', BizId);
    
      end;
    
    finally
      JO.Free;
    end;
    

    finally

    HTTP.Free;
    Params.Free;

    end;

    end;

    procedure TForm1.btnSendClick(Sender: TObject);
    var
    RequestId, Code, strMsg, BizId, CryptData, CryptResult: string;
    begin

    SendSMS(

          edtAccessKeyId.Text,
          edtAccessSecret.Text,
          edtTimestamp.Text,         // 时间戳
          edtFormat.Text,              // JSON
          edtSignatureMethod.Text,   // HMAC-SHA1
          edtSignatureVersion.Text,  // 1.0
          edtSignatureNonce.Text,    // 事先生成的签名字符串
          edtAction.Text,                // SendSms
          edtVersion.Text,           // 2017-05-25
          edtRegionId.Text,          // cn-hangzhou
          edtPhoneNum.Text,          // phoneno
          edtSignName.Text,          // 签名
          edtTemplateCode.Text,      // 模板代码
          edtTemplateParam.Text,     // {"code":"1111"}
          edtOutId.Text,             // 外部流水扩展字段
          RequestId,
          Code,
          strMsg,
          BizId ,
          CryptData,
          CryptResult
          );
    

    mmoSign.Text := CryptData;
    edtSigned.Text := CryptResult;
    edtRequestId.Text := RequestId;
    edtCode.Text := Code;
    edtMessage.Text := strMsg;
    edtBizId.Text := BizId;

    2019-07-17 21:40:57
    赞同 展开评论 打赏
  • 同样的问题,List操作正常,Create操作就这个错误,求解

    2019-07-17 21:40:57
    赞同 展开评论 打赏
  • 签名不正确吧.

    检查一下 字段的顺序, 私钥值, 格式

    2019-07-17 21:40:57
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载