HMAC.swift 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. //
  2. // HMAC.swift
  3. // Swifter
  4. //
  5. // Copyright © 2016 Damian Kołakowski. All rights reserved.
  6. //
  7. import Foundation
  8. public struct HMAC {
  9. //
  10. // HMAC: Keyed-Hashing for Message Authentication
  11. //
  12. // https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
  13. // https://tools.ietf.org/html/rfc2104
  14. //
  15. public static func sha1(_ key: [UInt8], _ message: [UInt8]) -> [UInt8] {
  16. return generate(key, message, (64, { block in
  17. return SHA1.hash(block)
  18. }))
  19. }
  20. public static func sha1(_ key: [UInt8], _ message: [UInt8]) -> String {
  21. return sha1(key, message).reduce("") { $0 + String(format: "%02x", $1) }
  22. }
  23. public static func generate(_ key: [UInt8], _ message: [UInt8], _ setup: (blockSize: Int, hash: (([UInt8]) -> [UInt8]))) -> [UInt8] {
  24. var paddedKey = key
  25. if paddedKey.count > setup.blockSize {
  26. paddedKey = setup.hash(paddedKey)
  27. } else if paddedKey.count < setup.blockSize {
  28. paddedKey = paddedKey + [UInt8](repeating: 0, count: setup.blockSize - paddedKey.count)
  29. }
  30. let oKeyPad = paddedKey.map { $0 ^ UInt8(0x5c) }
  31. let iKeyPad = paddedKey.map { $0 ^ UInt8(0x36) }
  32. return setup.hash(oKeyPad + setup.hash(iKeyPad + message))
  33. }
  34. }