title: Invalid Signature with telesign call REST API
body: <p>The API sends a verification code via a phone call that the user then enters into a website... basically verifying that there phone number is valid.</p>
  
  <p>But I'm having trouble signing the request. No matter what I try it returns "Invalid Signature" </p>
  
  <p>The API documentation:
  <a href="http://docs.telesign.com/rest/content/verify-call.html" rel="nofollow">http://docs.telesign.com/rest/content/verify-call.html</a></p>
  
  <p>The authentication documentation:
  <a href="http://docs.telesign.com/rest/content/rest-auth.html" rel="nofollow">http://docs.telesign.com/rest/content/rest-auth.html</a></p>
  
  <p>The authentication examples:
  <a href="http://docs.telesign.com/rest/content/auth-examples.html" rel="nofollow">http://docs.telesign.com/rest/content/auth-examples.html</a></p>
  
  <p>The code:</p>
  
  <pre><code>&lt;cffunction name="encryptHmacSHA1" returntype="binary" access="public" output="false"&gt;
      &lt;cfargument name="base64Key" type="string" required="true"&gt;
      &lt;cfargument name="signMessage" type="string" required="true"&gt;
      &lt;cfargument name="encoding" type="string" default="UTF-8"&gt;
  
      &lt;cfset var messageBytes = JavaCast("string",arguments.signMessage).getBytes(arguments.encoding)&gt;
      &lt;cfset var keyBytes = binaryDecode(arguments.base64Key, "base64")&gt;
      &lt;cfset var key  = createObject("java","javax.crypto.spec.SecretKeySpec")&gt;
      &lt;cfset var mac  = createObject("java","javax.crypto.Mac")&gt;
      &lt;cfset key  = key.init(keyBytes,"HmacSHA1")&gt;
      &lt;cfset mac  = mac.getInstance(key.getAlgorithm())&gt;
      &lt;cfset mac.init(key)&gt;
      &lt;cfset mac.update(messageBytes)&gt;
  
      &lt;cfreturn mac.doFinal()&gt;
  &lt;/cffunction&gt;
  
  
  &lt;cfscript&gt;
      // 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") &amp; " " &amp; TimeFormat(dates.dateToUse,"HH:mm:ss") &amp; " +0000";
  
  
      // HEADERS
      headers = [ 
             "POST",
             "application/x-www-form-urlencoded", 
             "#dates.signingDate#",
             "phone_number=#phoneNumberToCall#&amp;ucid=OTHR", 
             "/v1/verify/call"
            ];
  
      headerText = arrayToList(headers, chr(10)) &amp; chr(10);
  
      // CREATE SIGNATURE
      stringToSign = binaryEncode( encryptHmacSHA1(keys.apiKey, headerText), "base64");
  
      // AUTHORIZE HEADER
      Authorization = "TSA" &amp; " " &amp; keys.customerID &amp; ":" &amp; stringToSign;
  &lt;/cfscript&gt;
  
  &lt;cfhttp method="POST" url="https://rest.telesign.com/v1/verify/call" port="443" charset="UTF-8" result="verifyPhoneCall"&gt; 
      &lt;cfhttpparam type="header" name="authorization" value="#Authorization#"&gt;
      &lt;cfhttpparam type="header" name="content-type" value="application/x-www-form-urlencoded"&gt;
      &lt;cfhttpparam type="header" name="date" value="#dates.signingDate#"&gt;
      &lt;cfhttpparam name="phone_number" value="#phoneNumberToCall#" type="formfield"&gt;
      &lt;cfhttpparam name="ucid" value="OTHR" type="formfield"&gt;
  &lt;/cfhttp&gt;
  &lt;cfdump var="#verifyPhoneCall#"&gt; 
  </code></pre>
  
  <p>The headers need to be included in the signature with "new lines". And the docs also say that they need to be in the same order that the http tag is sending them in. I don't think I have the order correct... or even how I'm supposed to set an order in the cfhttp call.</p>
  
  <p>Any help is appreciated. And yes the keys are real. I'll generate new ones soon. </p>
  
  <p>Thanks,</p>
  
  <p>Brian</p>