title: HMAC SHA256 JWT Signature is incorrect
body: <p><strong>The answer:</strong></p>
  
  <p>Instead of the hmac func below here are the functions I am now using...</p>
  
  <pre><code>func base64Encoded(algorithm: CryptoAlgorithm, key: String) -&gt; String {
    let hmac = self.hmac(algorithm: algorithm, key: key)
    let digestLen = algorithm.digestLength
    let dataResult = NSData(bytes: hmac, length: digestLen)
    hmac.deallocateCapacity(digestLen)
  
    return dataResult.base64EncodedString()
  }
  
  func hash(algorithm: CryptoAlgorithm, key: String) -&gt; String {
    let hmac = self.hmac(algorithm: algorithm, key: key)
    let digestLen = algorithm.digestLength
    let hash = NSMutableString()
  
    for i in 0..&lt;digestLen {
      hash.appendFormat("%02x", hmac[i])
    }
  
    hmac.deallocateCapacity(digestLen)
  
    return hash as String 
  }
  
  func hmac(algorithm: CryptoAlgorithm, key: String) -&gt; UnsafeMutablePointer&lt;CUnsignedChar&gt; {
    let str = self.cString(using: String.Encoding.utf8)
    let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8))
    let digestLen = algorithm.digestLength
  
    let result = UnsafeMutablePointer&lt;CUnsignedChar&gt;(allocatingCapacity: digestLen)
  
    let keyStr = key.cString(using: String.Encoding.utf8)
    let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8))
  
    CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)
  
    return result
  }
  </code></pre>
  
  <p><strong>ORIGINAL POST</strong></p>
  
  <p>I have a JWT which I am trying to verify the signature. Here is the JWT...</p>
  
  <blockquote>
    <p>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhcGkudGVzdC5jb20vdjEvYXV0aCIsImV4cCI6MTQ2OTk3ODQ5OCwic3ViIjoiMTIzNDU2Nzg5MCIsImVtYWlsIjoidGVzdEB0ZXN0LmNvbSIsInJvbGVzIjpbImFkbWluIiwiY3VzdG9tZXIiXSwicGVybWlzc2lvbnMiOlsidGVzdC5wcm9maWxlIiwidGVzdC5wcm9maWxlLmNvbnRhY3QiLCJ0ZXN0LnByb2ZpbGUuZGV2aWNlIiwidGVzdC5wcm9maWxlLmFwcCJdfQ.GfLxXOL978Pm5GYMI0WTBEVcMrfVj2jJb-Il_XzO7g4</p>
  </blockquote>
  
  <p>I'm working in Swift 3 and I updated the methods in this SO answer <a href="https://stackoverflow.com/a/24411522/741626">https://stackoverflow.com/a/24411522/741626</a>. This is what those methods now look like.</p>
  
  <pre><code>import Foundation
  
  enum CryptoAlgorithm {
    case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
  
      var HMACAlgorithm: CCHmacAlgorithm {
      var result: Int = 0
      switch self {
      case .MD5:      result = kCCHmacAlgMD5
      case .SHA1:     result = kCCHmacAlgSHA1
      case .SHA224:   result = kCCHmacAlgSHA224
      case .SHA256:   result = kCCHmacAlgSHA256
      case .SHA384:   result = kCCHmacAlgSHA384
      case .SHA512:   result = kCCHmacAlgSHA512
      }
    return CCHmacAlgorithm(result)
  }
  
  var digestLength: Int {
    var result: Int32 = 0
      switch self {
      case .MD5:      result = CC_MD5_DIGEST_LENGTH
      case .SHA1:     result = CC_SHA1_DIGEST_LENGTH
      case .SHA224:   result = CC_SHA224_DIGEST_LENGTH
      case .SHA256:   result = CC_SHA256_DIGEST_LENGTH
      case .SHA384:   result = CC_SHA384_DIGEST_LENGTH
      case .SHA512:   result = CC_SHA512_DIGEST_LENGTH
      }
      return Int(result)
    }
  }
  
  extension String {
  
  func hmac(algorithm: CryptoAlgorithm, key: String) -&gt; String {
    let str = self.cString(using: String.Encoding.utf8)
    let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8))
    let digestLen = algorithm.digestLength
  
    let result = UnsafeMutablePointer&lt;CUnsignedChar&gt;(allocatingCapacity: digestLen)
  
    let keyStr = key.cString(using: String.Encoding.utf8)
    let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8))
  
    CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)
  
    let hash = NSMutableString()
    for i in 0..&lt;digestLen {
      hash.appendFormat("%02x", result[i])
    }
  
    result.deallocateCapacity(digestLen)
  
    return hash as String
  
  }
  </code></pre>
  
  <p>I am able to base64Decode the header &amp; payload successfully but when I try to verify the signature it's always wrong (doesn't look anything like AND is way too long).</p>
  
  <p><strong>What I've tried.</strong></p>
  
  <p><strong>1</strong> I've tried several JWTs - always wrong in the same way</p>
  
  <p><strong>2</strong> I've hard coded the sha256 constants to ensure I wasn't using the wrong encoding / length</p>
  
  <p><strong>3</strong> I've tried many types of String.Encoding but while they always generate a different result as expected, none of them generate the desired signature.</p>
  
  <p><strong>4</strong> I've used an Objective-C method to generate the hmac to try and rule out if my conversion to Swift 3 broke anything. Same results, here is the Objective C code.</p>
  
  <pre><code>+ (NSData *)hmacSha256:(NSString *)string key:(NSString *)key;
  {
    NSData *dataIn = [string dataUsingEncoding:NSUTF8StringEncoding];
    NSData *keyIn = [key dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData *macOut = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
  
    CCHmac( kCCHmacAlgSHA256,
         keyIn.bytes,
         keyIn.length,
         dataIn.bytes,
         dataIn.length,
         macOut.mutableBytes);
  
    return macOut;
  }
  </code></pre>
  
  <p>The code originated here: <a href="https://stackoverflow.com/a/31003443/741626">https://stackoverflow.com/a/31003443/741626</a>. I'd rather not plug in Objective-C code to my Swift project but if I have to I will!</p>
  
  <p>Here is my calling func</p>
  
  <pre><code>func decodeToken(token: String) {
    let array = token.characters.split(isSeparator: { $0 == "." })
  .map(String.init)
  
    let header:String = String(array[0])
    let payload:String = String(array[1])
    let signature:String = String(array[2])
  
    let encodedString = header + "." + payload
    let hmac = encodedString.hmac(algorithm: .SHA256, key: "")
  }
  </code></pre>
  
  <p><strong>EDIT</strong></p>
  
  <p>When I run the code the resulting hmac is </p>
  
  <blockquote>
    <p>19f2f15ce2fdefc3e6e4660c23459304455c32b7d58f68c96fe225fd7cceee0e</p>
  </blockquote>
  
  <p>I've triple checked that the secret is correct, which is <strong>""</strong> (empty string)</p>
  
  <p><strong>What am I doing wrong?</strong></p>
  
  <p>I would really like to test in my client app that the tokens I receive are trustworthy rather than glossing over this. If anyone has any ideas what I'm doing wrong that would be great.</p>