I am attempting to generate a signing key for AWS according to AWS's documentation here for an iOS application. The documentation is pretty good however, it doesn't provide an example using Swift. Apple provides CryptoKit which should be the right framework, but I haven't been able to puzzle it out.
Ruby Example
def getSignatureKey key, dateStamp, regionName, serviceName
kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + key, dateStamp)
kRegion = OpenSSL::HMAC.digest('sha256', kDate, regionName)
kService = OpenSSL::HMAC.digest('sha256', kRegion, serviceName)
kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")
kSigning
end
Sample Inputs from AWS Docs
key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
dateStamp = '20120215'
regionName = 'us-east-1'
serviceName = 'iam'
Should output
kSecret = '41575334774a616c725855746e46454d492f4b374d44454e472b62507852666943594558414d504c454b4559'
kDate = '969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d'
kRegion = '69daa0209cd9c5ff5c8ced464a696fd4252e981430b10e3d3fd8e2f197d7a70c'
kService = 'f72cfd46f26bc4643f06a11eabb6c0ba18780c19a8da0c31ace671265e3c87fa'
kSigning = 'f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a000a1a9e090d414db404d'
My attempt (note you have to append AWS to the key according to the docs)
import Foundation
import CryptoKit
let key = "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"
let dateStamp = "20120215"
let regionName = "us-east-1"
let serviceName = "iam"
let keyData = Data("AWS\(key)".utf8)
let symmetricKey = SymmetricKey(data: keyData)
let dateStampData = Data(dateStamp.utf8)
let signature = HMAC<SHA256>.authenticationCode(for: dateStampData, using: symmetricKey)
let skeyString = keyData.map { String(format: "%02hhx", $0) }.joined()
print("kSecret \t= \(skeyString)")
let kDateString = Data(signature).map { String(format: "%02hhx", $0) }.joined()
print("kDate \t\t= \(kDateString)")
The first one is correct, so it seems I have the initial key correct, but when trying to apply it to dateStamp it doesn't match.
Outputs
kSecret = 415753774a616c725855746e46454d492f4b374d44454e472b62507852666943594558414d504c454b4559
kDate = 2226579f8b317a03ec325a8c8b3d27cf465ce52787455e1880039824b4ba0e25
Of course the moment I post the question I find the issue. The original issue was I was appending
AWSinstead ofAWS4the string appeared to be correct for kSecret because I was looking at the first set and last set of digits. Here is the solution for anyone looking to do the same.Outputs