iOS AWS Request 4
iOSにAWS Request 4リクエストを送るのは思ったほど簡単ではないので、整理することにしました.
Date
PUT test$file.text HTTP/1.1
Host: examplebucket.s3.amazonaws.com
Date: Fri, 24 May 2013 00:00:00 GMT
Authorization: SignatureToBeCalculated
x-amz-date: 20130524T000000Z
x-amz-storage-class: REDUCED_REDUNDANCY
x-amz-content-sha256: 44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072
<Payload>
多くのプロセスがありますが、最終的には上のようにヘッダーを作成します.Date
まずDate形式から始め、DateのtimezoneをUTC時間に設定します.
Dateには、indexを使用して切り取られたx-amz-dateに必要なフォーマットとは異なるタイムスタンプフォーマットも必要です.private var dateString:String{
switch self {
case .saveFile:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd'T'HHmmssXXXXX"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
return dateFormatter.string(from: Date())
}
}
private var timestampString:String{
let index = dateString.index(dateString.startIndex, offsetBy: 7)
return String(dateString[...index])
}
Payload
PUT演算にはハッシュPayloadが必要であり,それを頭の中に置く. private var hashedPayload: String{
switch self {
case .saveFile(let url):
do{
let payload = try Data(contentsOf:url)
return SHA256.hash(data: payload).map{String(format: "%02hhx", $0)}.joined()
}catch{
fatalError("파일 hash 과정 중 오류 발생: " + error.localizedDescription)
}
}
}
CanonicalRequest
次に、CanonicalRequestから文字列が生成されます.let canonicalHeaders = """
content-type:application/zip\n\
host:\(host)\n\
x-amz-content-sha256:\(hashedPayload)\n\
x-amz-date:\(dateString)
"""
let signedHeaders = "content-type;host;x-amz-content-sha256;x-amz-date"
let canonicalRequest = "PUT\n/\(endPoint)\n\n\(canonicalHeaders)\n\n\(signedHeaders)\n\(hashedPayload)"
このときsignedheadersの順序はアルファベット順である.
StringToSign
stringToSignは、ハッシュCanonicalRequestによってフォーマットを調整します.let credentialScope:String = timestampString + "/" + region + "/" + service + "/" + "aws4_request"
let stringToSign:String = algorithm + "\n" + dateString + "\n" + credentialScope + "\n"
+ SHA256.hash(data: canonicalRequest.data(using: .utf8)!).map{String(format: "%02hhx", $0)}.joined()
let algorithm = "AWS4-HMAC-SHA256"
let region = "ap-northeast-2"
let service = "s3"
Signature
やっと署名を生成する準備ができました.SWIFTのCryptoKitを用いるとHMACが容易に実現できる.private var signatureKey: SymmetricKey {
guard let secretKey = Bundle.main.infoDictionary!["AWS_SECRET_KEY"] as? String else{
fatalError("SECRET KEY 없음")
}
let kDate = HMAC<SHA256>.authenticationCode(for: timestampString.data(using: .utf8)!, using: SymmetricKey(data:("AWS4" + secretKey).data(using: .utf8)!))
let kRegion = HMAC<SHA256>.authenticationCode(for: region.data(using: .utf8)!, using: SymmetricKey(data:kDate))
let kService = HMAC<SHA256>.authenticationCode(for: service.data(using: .utf8)!, using: SymmetricKey(data:kRegion))
return SymmetricKey(data:HMAC<SHA256>.authenticationCode(for: "aws4_request".data(using: .utf8)!, using: SymmetricKey(data:kService)))
}
let signature = HMAC<SHA256>.authenticationCode(for: stringToSign.data(using: .utf8)!, using: signatureKey)
.map{String(format: "%02hhx", $0)}.joined()
Authorization Header
最後に、承認ヘッダを作成し、リクエストを発行すれば成功します.できない場合は、response bodyを出力できない理由がわかります.let awsSignature = """
\(algorithm) Credential=\(accessKey)/\(credentialScope), \
SignedHeaders=\(signedHeaders), Signature=\(signature)
"""
private var headers: HTTPHeaders{
switch self {
case .saveFile:
return [
"Content-Type":"application/zip",
"Host":"\(host)",
"X-Amz-Content-SHA256":hashedPayload,
"X-Amz-Date":dateString,
"Authorization":awsSignature
]
}
}
リファレンス
https://gist.github.com/elmyn/b63913d7ba4ffa26b37d55c7b7e260e1
https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
https://docs.aws.amazon.com/ko_kr/general/latest/gr/sigv4-signed-request-examples.html
Reference
この問題について(iOS AWS Request 4), 我々は、より多くの情報をここで見つけました
https://velog.io/@dbghwns11/iOS-AWS-Request-4
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
private var dateString:String{
switch self {
case .saveFile:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd'T'HHmmssXXXXX"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
return dateFormatter.string(from: Date())
}
}
private var timestampString:String{
let index = dateString.index(dateString.startIndex, offsetBy: 7)
return String(dateString[...index])
}
PUT演算にはハッシュPayloadが必要であり,それを頭の中に置く.
private var hashedPayload: String{
switch self {
case .saveFile(let url):
do{
let payload = try Data(contentsOf:url)
return SHA256.hash(data: payload).map{String(format: "%02hhx", $0)}.joined()
}catch{
fatalError("파일 hash 과정 중 오류 발생: " + error.localizedDescription)
}
}
}
CanonicalRequest
次に、CanonicalRequestから文字列が生成されます.let canonicalHeaders = """
content-type:application/zip\n\
host:\(host)\n\
x-amz-content-sha256:\(hashedPayload)\n\
x-amz-date:\(dateString)
"""
let signedHeaders = "content-type;host;x-amz-content-sha256;x-amz-date"
let canonicalRequest = "PUT\n/\(endPoint)\n\n\(canonicalHeaders)\n\n\(signedHeaders)\n\(hashedPayload)"
このときsignedheadersの順序はアルファベット順である.
StringToSign
stringToSignは、ハッシュCanonicalRequestによってフォーマットを調整します.let credentialScope:String = timestampString + "/" + region + "/" + service + "/" + "aws4_request"
let stringToSign:String = algorithm + "\n" + dateString + "\n" + credentialScope + "\n"
+ SHA256.hash(data: canonicalRequest.data(using: .utf8)!).map{String(format: "%02hhx", $0)}.joined()
let algorithm = "AWS4-HMAC-SHA256"
let region = "ap-northeast-2"
let service = "s3"
Signature
やっと署名を生成する準備ができました.SWIFTのCryptoKitを用いるとHMACが容易に実現できる.private var signatureKey: SymmetricKey {
guard let secretKey = Bundle.main.infoDictionary!["AWS_SECRET_KEY"] as? String else{
fatalError("SECRET KEY 없음")
}
let kDate = HMAC<SHA256>.authenticationCode(for: timestampString.data(using: .utf8)!, using: SymmetricKey(data:("AWS4" + secretKey).data(using: .utf8)!))
let kRegion = HMAC<SHA256>.authenticationCode(for: region.data(using: .utf8)!, using: SymmetricKey(data:kDate))
let kService = HMAC<SHA256>.authenticationCode(for: service.data(using: .utf8)!, using: SymmetricKey(data:kRegion))
return SymmetricKey(data:HMAC<SHA256>.authenticationCode(for: "aws4_request".data(using: .utf8)!, using: SymmetricKey(data:kService)))
}
let signature = HMAC<SHA256>.authenticationCode(for: stringToSign.data(using: .utf8)!, using: signatureKey)
.map{String(format: "%02hhx", $0)}.joined()
Authorization Header
最後に、承認ヘッダを作成し、リクエストを発行すれば成功します.できない場合は、response bodyを出力できない理由がわかります.let awsSignature = """
\(algorithm) Credential=\(accessKey)/\(credentialScope), \
SignedHeaders=\(signedHeaders), Signature=\(signature)
"""
private var headers: HTTPHeaders{
switch self {
case .saveFile:
return [
"Content-Type":"application/zip",
"Host":"\(host)",
"X-Amz-Content-SHA256":hashedPayload,
"X-Amz-Date":dateString,
"Authorization":awsSignature
]
}
}
リファレンス
https://gist.github.com/elmyn/b63913d7ba4ffa26b37d55c7b7e260e1
https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
https://docs.aws.amazon.com/ko_kr/general/latest/gr/sigv4-signed-request-examples.html
Reference
この問題について(iOS AWS Request 4), 我々は、より多くの情報をここで見つけました
https://velog.io/@dbghwns11/iOS-AWS-Request-4
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
let canonicalHeaders = """
content-type:application/zip\n\
host:\(host)\n\
x-amz-content-sha256:\(hashedPayload)\n\
x-amz-date:\(dateString)
"""
let signedHeaders = "content-type;host;x-amz-content-sha256;x-amz-date"
let canonicalRequest = "PUT\n/\(endPoint)\n\n\(canonicalHeaders)\n\n\(signedHeaders)\n\(hashedPayload)"
stringToSignは、ハッシュCanonicalRequestによってフォーマットを調整します.
let credentialScope:String = timestampString + "/" + region + "/" + service + "/" + "aws4_request"
let stringToSign:String = algorithm + "\n" + dateString + "\n" + credentialScope + "\n"
+ SHA256.hash(data: canonicalRequest.data(using: .utf8)!).map{String(format: "%02hhx", $0)}.joined()
let algorithm = "AWS4-HMAC-SHA256"
let region = "ap-northeast-2"
let service = "s3"
Signature
やっと署名を生成する準備ができました.SWIFTのCryptoKitを用いるとHMACが容易に実現できる.private var signatureKey: SymmetricKey {
guard let secretKey = Bundle.main.infoDictionary!["AWS_SECRET_KEY"] as? String else{
fatalError("SECRET KEY 없음")
}
let kDate = HMAC<SHA256>.authenticationCode(for: timestampString.data(using: .utf8)!, using: SymmetricKey(data:("AWS4" + secretKey).data(using: .utf8)!))
let kRegion = HMAC<SHA256>.authenticationCode(for: region.data(using: .utf8)!, using: SymmetricKey(data:kDate))
let kService = HMAC<SHA256>.authenticationCode(for: service.data(using: .utf8)!, using: SymmetricKey(data:kRegion))
return SymmetricKey(data:HMAC<SHA256>.authenticationCode(for: "aws4_request".data(using: .utf8)!, using: SymmetricKey(data:kService)))
}
let signature = HMAC<SHA256>.authenticationCode(for: stringToSign.data(using: .utf8)!, using: signatureKey)
.map{String(format: "%02hhx", $0)}.joined()
Authorization Header
最後に、承認ヘッダを作成し、リクエストを発行すれば成功します.できない場合は、response bodyを出力できない理由がわかります.let awsSignature = """
\(algorithm) Credential=\(accessKey)/\(credentialScope), \
SignedHeaders=\(signedHeaders), Signature=\(signature)
"""
private var headers: HTTPHeaders{
switch self {
case .saveFile:
return [
"Content-Type":"application/zip",
"Host":"\(host)",
"X-Amz-Content-SHA256":hashedPayload,
"X-Amz-Date":dateString,
"Authorization":awsSignature
]
}
}
リファレンス
https://gist.github.com/elmyn/b63913d7ba4ffa26b37d55c7b7e260e1
https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
https://docs.aws.amazon.com/ko_kr/general/latest/gr/sigv4-signed-request-examples.html
Reference
この問題について(iOS AWS Request 4), 我々は、より多くの情報をここで見つけました
https://velog.io/@dbghwns11/iOS-AWS-Request-4
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
private var signatureKey: SymmetricKey {
guard let secretKey = Bundle.main.infoDictionary!["AWS_SECRET_KEY"] as? String else{
fatalError("SECRET KEY 없음")
}
let kDate = HMAC<SHA256>.authenticationCode(for: timestampString.data(using: .utf8)!, using: SymmetricKey(data:("AWS4" + secretKey).data(using: .utf8)!))
let kRegion = HMAC<SHA256>.authenticationCode(for: region.data(using: .utf8)!, using: SymmetricKey(data:kDate))
let kService = HMAC<SHA256>.authenticationCode(for: service.data(using: .utf8)!, using: SymmetricKey(data:kRegion))
return SymmetricKey(data:HMAC<SHA256>.authenticationCode(for: "aws4_request".data(using: .utf8)!, using: SymmetricKey(data:kService)))
}
let signature = HMAC<SHA256>.authenticationCode(for: stringToSign.data(using: .utf8)!, using: signatureKey)
.map{String(format: "%02hhx", $0)}.joined()
最後に、承認ヘッダを作成し、リクエストを発行すれば成功します.できない場合は、response bodyを出力できない理由がわかります.
let awsSignature = """
\(algorithm) Credential=\(accessKey)/\(credentialScope), \
SignedHeaders=\(signedHeaders), Signature=\(signature)
"""
private var headers: HTTPHeaders{
switch self {
case .saveFile:
return [
"Content-Type":"application/zip",
"Host":"\(host)",
"X-Amz-Content-SHA256":hashedPayload,
"X-Amz-Date":dateString,
"Authorization":awsSignature
]
}
}
リファレンスhttps://gist.github.com/elmyn/b63913d7ba4ffa26b37d55c7b7e260e1
https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
https://docs.aws.amazon.com/ko_kr/general/latest/gr/sigv4-signed-request-examples.html
Reference
この問題について(iOS AWS Request 4), 我々は、より多くの情報をここで見つけました https://velog.io/@dbghwns11/iOS-AWS-Request-4テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol