signature.swift 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. //
  2. // You also need a Bridging-Header.h to import CommonCrypto:
  3. // #import <CommonCrypto/CommonCrypto.h>
  4. //
  5. import Foundation
  6. // https://stackoverflow.com/a/41965688/326257
  7. extension Data {
  8. func hmac256(key: Data) -> String {
  9. let cKey = (key as NSData).bytes
  10. let cData = (self as NSData).bytes
  11. var result = [CUnsignedChar](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
  12. CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), cKey, key.count, cData, self.count, &result)
  13. let hmacData:NSData = NSData(bytes: result, length: (Int(CC_SHA256_DIGEST_LENGTH)))
  14. return customBase64(input: hmacData as Data)
  15. }
  16. }
  17. // https://stackoverflow.com/a/26502285/326257
  18. extension String {
  19. func hexadecimal() -> Data? {
  20. var data = Data(capacity: characters.count / 2)
  21. let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive)
  22. regex.enumerateMatches(in: self, range: NSMakeRange(0, utf16.count)) { match, flags, stop in
  23. let byteString = (self as NSString).substring(with: match!.range)
  24. var num = UInt8(byteString, radix: 16)!
  25. data.append(&num, count: 1)
  26. }
  27. guard data.count > 0 else { return nil }
  28. return data
  29. }
  30. }
  31. func customBase64(input: Data) -> String {
  32. return input.base64EncodedString()
  33. .replacingOccurrences(of: "+", with: "-")
  34. .replacingOccurrences(of: "/", with: "_")
  35. .replacingOccurrences(of: "=+$", with: "", options: .regularExpression)
  36. }
  37. let key = "943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881".hexadecimal()!;
  38. let salt = "520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5".hexadecimal()!;
  39. let partialPath = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg"
  40. let toSign = salt + partialPath.utf8
  41. let signature = toSign.hmac256(key: key)
  42. let path = "/\(signature)\(partialPath)"
  43. print(path)