telesign调用REST API的签名无效

telesign调用REST API的签名无效,rest,coldfusion,coldfusion-10,Rest,Coldfusion,Coldfusion 10,API通过电话发送验证码,然后用户进入网站。。。基本上是验证电话号码是否有效 但是我在签署请求时遇到了麻烦。无论我尝试什么,它都会返回“无效签名” API文档: 身份验证文档: 身份验证示例: 守则: <cffunction name="encryptHmacSHA1" returntype="binary" access="public" output="false"> <cfargument name="base64Key" type="string" req

API通过电话发送验证码,然后用户进入网站。。。基本上是验证电话号码是否有效

但是我在签署请求时遇到了麻烦。无论我尝试什么,它都会返回“无效签名”

API文档:

身份验证文档:

身份验证示例:

守则:

<cffunction name="encryptHmacSHA1" returntype="binary" access="public" output="false">
    <cfargument name="base64Key" type="string" required="true">
    <cfargument name="signMessage" type="string" required="true">
    <cfargument name="encoding" type="string" default="UTF-8">

    <cfset var messageBytes = JavaCast("string",arguments.signMessage).getBytes(arguments.encoding)>
    <cfset var keyBytes = binaryDecode(arguments.base64Key, "base64")>
    <cfset var key  = createObject("java","javax.crypto.spec.SecretKeySpec")>
    <cfset var mac  = createObject("java","javax.crypto.Mac")>
    <cfset key  = key.init(keyBytes,"HmacSHA1")>
    <cfset mac  = mac.getInstance(key.getAlgorithm())>
    <cfset mac.init(key)>
    <cfset mac.update(messageBytes)>

    <cfreturn mac.doFinal()>
</cffunction>


<cfscript>
    // PHONE NUMBER TO CALL
    phoneNumberToCall = "15554565555"; 

    // KEYS
    keys = structNew();
    keys.customerID = "D561FCF4-BA8D-4DFC-86D1-1A46DF47A308";
    keys.apiKey = "mDzGHsMOc2g/ivkuINEFVh6fn/v4kdjvlTvtgFVOShu7hVWXS0eV2nLSw1FXgEzDSuOjhlKLXvneiq+YFG1/Vg==";

    // DATES
    dates = structNew();
    dates.timeZoneInfo = GetTimeZoneInfo();
    dates.dateToUse = DateAdd("h",dates.timeZoneInfo.utcHourOffset,now());
    dates.signingDate = DateFormat(dates.dateToUse,"ddd, dd mmm yyyy") & " " & TimeFormat(dates.dateToUse,"HH:mm:ss") & " +0000";


    // HEADERS
    headers = [ 
           "POST",
           "application/x-www-form-urlencoded", 
           "#dates.signingDate#",
           "phone_number=#phoneNumberToCall#&ucid=OTHR", 
           "/v1/verify/call"
          ];

    headerText = arrayToList(headers, chr(10)) & chr(10);

    // CREATE SIGNATURE
    stringToSign = binaryEncode( encryptHmacSHA1(keys.apiKey, headerText), "base64");

    // AUTHORIZE HEADER
    Authorization = "TSA" & " " & keys.customerID & ":" & stringToSign;
</cfscript>

<cfhttp method="POST" url="https://rest.telesign.com/v1/verify/call" port="443" charset="UTF-8" result="verifyPhoneCall"> 
    <cfhttpparam type="header" name="authorization" value="#Authorization#">
    <cfhttpparam type="header" name="content-type" value="application/x-www-form-urlencoded">
    <cfhttpparam type="header" name="date" value="#dates.signingDate#">
    <cfhttpparam name="phone_number" value="#phoneNumberToCall#" type="formfield">
    <cfhttpparam name="ucid" value="OTHR" type="formfield">
</cfhttp>
<cfdump var="#verifyPhoneCall#"> 

//要拨打的电话号码
phoneNumberToCall=“15554565555”;
//钥匙
keys=structNew();
keys.customerID=“D561FCF4-BA8D-4DFC-86D1-1A46DF47A308”;
keys.apiKey=“mDzGHsMOc2g/ivkuINEFVh6fn/v4kdjvltvtgfvoshu7hvwxs0ev2nlsw1fxgezdsuojhlxvneiq+YFG1/Vg=”;
//日期
dates=structNew();
dates.timeZoneInfo=GetTimeZoneInfo();
dates.dateToUse=DateAdd(“h”,dates.timeZoneInfo.utcHourOffset,now());
dates.signingDate=日期格式(dates.dateToUse,“ddd,dd-mmm-yyyy”)和时间格式(dates.dateToUse,“HH:mm:ss”)和“+0000”;
//标题
标题=[
“职位”,
“application/x-www-form-urlencoded”,
“#日期。签名日期”,
“phone#u number=#phoneNumberToCall#&ucid=OTHR”,
“/v1/验证/调用”
];
headerText=ArrayList(标题,chr(10))&chr(10);
//创建签名
stringToSign=binaryEncode(encryptHmacSHA1(key.apiKey,headerText),“base64”);
//授权标头
Authorization=“TSA”和“&keys.customerID&:”&stringToSign;
标题需要包含在带有“新行”的签名中。文档还说,它们需要与http标记发送它们的顺序相同。我想我的订单不对。。。甚至我应该如何在cfhttp调用中设置顺序

感谢您的帮助。是的,钥匙是真的。我很快就会生成新的

谢谢


Brian查看了他们关于它的文档后提到,帖子正文必须与构造签名时使用的字符串相匹配(强调我的):

。。。构造签名字符串时,必须使用 POST请求在发送到服务时准确地

默认情况下,
cfhttpparam
url对任何
formField
值进行编码。由于构造签名时未对这些值进行编码,因此cfhttp提交的内容不匹配。因此出现了错误

禁用签名中所有表单字段的自动编码:

   <cfhttpparam name="phone_number" 
         value="#phoneNumberToCall#"
         type="formfield"  
         encoded="false">
。。而不是:

headerText = arrayToList(headers, chr(10)) & chr(10);

顺便说一句,CF10有一个内置的。因此,您可以使用它来代替自定义自定义自定义项。但是首先让代码工作:)非常感谢您的帮助和解释问题/解决方案。我真的很感激。我将调查hmac()。。。去拿新钥匙,欢迎。很高兴这有帮助:)我希望你发布的证书不再有效,因为它很容易被滥用。
headerText = arrayToList(headers, chr(10));
headerText = arrayToList(headers, chr(10)) & chr(10);