title: Verify X-Hub-Signature from Facebook
body: <p>I'm something of a beginner with the Play Framework (2.5 and Scala in this case) - and I'm trying to learn by building a bot for Facebook messenger. However I've gotten stuck trying to verify the signature of the messages.</p>
  
  <p>I've followed the Facebook documentation and created a webhook. Which handles POST requests using<code>getRawMessages</code> (see code below). This then tries to verify that the request is signed by Facebook using the <code>verifyPayload</code> function. However I can't seem to get the computed and the actual hashes to match up.</p>
  
  <p>I've taken a lead from looking at this question: <a href="https://stackoverflow.com/questions/20658813/how-to-verify-instagram-real-time-api-x-hub-signature-in-java">How to verify Instagram real-time API x-hub-signature in Java?</a> which seems to be doing pretty much what I want, but for the Instagram equivalent. But I still can't seem to get it right.</p>
  
  <pre><code>val secret = "&lt;facebooks secret token&gt;"  
  
  def getRawMessages = Action (parse.raw) {
      request =&gt;
  
        val xHubSignatureOption = request.headers.get("X-Hub-Signature")
  
        try {
          for {
            signature &lt;- xHubSignatureOption
            rawBodyAsBytes &lt;- request.body.asBytes()
          } yield {
            val rawBody = rawBodyAsBytes.toArray[Byte]
            val incomingHash = signature.split("=").last
            val verified = verifyPayload(rawBody, secret, incomingHash)
            Logger.info(s"Was verified? $verified")
          }
          Ok("Test")
        }
        catch {
          case _ =&gt; Ok("Test")
        }
    }
  
    val HMAC_SHA1_ALGORITHM = "HmacSHA1"
  
    def verifyPayload(payloadBytes: Array[Byte], secret: String, expected: String): Boolean =  {
  
      val secretKeySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), HMAC_SHA1_ALGORITHM)
      val mac = Mac.getInstance(HMAC_SHA1_ALGORITHM)
      mac.init(secretKeySpec)
      val result = mac.doFinal(payloadBytes)
  
      val computedHash = Hex.encodeHex(result).mkString
      Logger.info(s"Computed hash: $computedHash")
  
      computedHash == expected
    }
  </code></pre>
  
  <p>The Facebook <a href="https://developers.facebook.com/docs/graph-api/webhooks" rel="nofollow noreferrer">webhook docs</a> state:</p>
  
  <blockquote>
    <p>The HTTP request will contain an X-Hub-Signature header which contains
    the SHA1 signature of the request payload, using the app secret as the
    key, and prefixed with sha1=. Your callback endpoint can verify this
    signature to validate the integrity and origin of the payload</p>
    
    <p>Please note that the calculation is made on the escaped unicode
    version of the payload, with lower case hex digits. If you just
    calculate against the decoded bytes, you will end up with a different
    signature. For example, the string äöå should be escaped to
    \u00e4\u00f6\u00e5.</p>
  </blockquote>
  
  <p>I'm guessing that what I'm missing is getting the payload properly escaped to unicode, but I can't seem to find a way to do it. And the answer in the referenced question also appeared to just get the byte array without doing anything more with it (<code>jsonRawBytes = jsonRaw.asBytes();</code>).</p>
  
  <p>Any help with how to proceed would be much appreciated.</p>