title: JWT verify signature using HMACSHA256 and show "Invalid Signature" by Swift
body: <p>I have a question about JWT. <br>
  I try to create own signature and use hard-code secret key "hello1234567890987654321test1234". <br>
  And I use my function to create a signature and post to <a href="https://jwt.io/" rel="nofollow noreferrer">https://jwt.io/</a> to decode.<br>
  Then this webside show me "Invalid Signature".<br>
  What's wrong about me HMACSHA256 function? <br>
  And I found the "-","_" in webside and convert "+","/" in my output signature. <br>
  How to fix my output signature? <br>
  Is this signature is correct?<br></p>
  
  <p>I also find two HMACSHA256 methods searching in Google. I don't know which is better one. <br>
  please give me some advice about choosing this.<br>
  Thanks.<br></p>
  
  <p>Image:
  <a href="https://i.stack.imgur.com/SSKQa.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/SSKQa.png" alt="Question Image."></a></p>
  
  <p>Method1:</p>
  
  <pre><code>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 hmac1(algorithm: CryptoAlgorithm, key: String) -&gt; String {
          var result: [CUnsignedChar]
          if let ckey = key.cString(using: String.Encoding.utf8), let cdata = self.cString(using: String.Encoding.utf8) {
              result = Array(repeating: 0, count: Int(algorithm.digestLength))
              CCHmac(algorithm.HMACAlgorithm, ckey, ckey.count-1, cdata, cdata.count-1, &amp;result)
          } else {
              fatalError("Nil returned when processing input strings as UTF8")
          }
  
          return Data(bytes: result, count: result.count).base64EncodedString()
      }
  }
  </code></pre>
  
  <p>Method2: </p>
  
  <pre><code>enum HMACAlgorithm {
      case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
  
      func toCCHmacAlgorithm() -&gt; 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)
      }
  
      func digestLength() -&gt; Int {
          var result: CInt = 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 hmac2(algorithm: HMACAlgorithm, key: String) -&gt; String {
          let cKey = key.cString(using: String.Encoding.utf8)
          let cData = self.cString(using: String.Encoding.utf8)
          var result = [CUnsignedChar](repeating: 0, count: Int(algorithm.digestLength()))
          CCHmac(algorithm.toCCHmacAlgorithm(), cKey!, strlen(cKey!), cData!, strlen(cData!), &amp;result)
          let hmacData:NSData = NSData(bytes: result, length: (Int(algorithm.digestLength())))
          let hmacBase64 = hmacData.base64EncodedString(options: .lineLength76Characters)
          return String(hmacBase64)
      }
  }
  </code></pre>
  
  <p>Usage: </p>
  
  <pre><code>class ViewController: UIViewController {
  
      override func viewDidLoad() {
          super.viewDidLoad()
  
          let headerString: String = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
          let payloadString: String = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
          let totalString: String = headerString + "." + payloadString
  
          let signature1 = totalString.hmac1(algorithm: .SHA256, key: "hello1234567890987654321test1234")
          let signature2 = totalString.hmac2(algorithm: .SHA256, key: "hello1234567890987654321test1234")
  
          print("signature1 : \(signature1)") // signature1 : L9YSDasvO2B5i8FZUczC+MAtSsTuM0Dj+FEpfn6uoRs=
          print("signature2 : \(signature2)") // signature2 : L9YSDasvO2B5i8FZUczC+MAtSsTuM0Dj+FEpfn6uoRs=
  
      }
  }
  </code></pre>