使用阿里大鱼.net版本的SDK,发送短信,出现错误:SignatureDoesNotMatch : Specified signature is not matched with our calculation.
我也遇到这个问题, 明确按文档 提供的 参数, 移动的 短信平台 则相对简单,不需要这么多参数,当然也不会签名错误!
我用的 是 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;
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。