d94054dd1a
- 项目从 SPM (Sources/VODManager/) 迁移到 Xcode 构建系统 (VODManager.xcodeproj) - 源码目录从 Sources/VODManager/ 迁移至 VODManager/VODManager/ - 用 Localizable.xcstrings 替代旧的 .lproj/Localizable.strings 文件 - 删除已废弃的 apps/web、apps/server、docker 目录及相关文档 - RTL 侧边栏修复:切语言时用 .id() 强制重建 NavigationSplitView - 视频库无账号时不发起 API 请求和重试 - 无账号时显示 ContentUnavailableView 提示
59 lines
1.8 KiB
Swift
59 lines
1.8 KiB
Swift
import Foundation
|
|
import CryptoKit
|
|
|
|
enum VODSignatureError: Error {
|
|
case invalidKey
|
|
case encodingFailed
|
|
}
|
|
|
|
struct VODSignature {
|
|
static func sign(
|
|
method: String = "GET",
|
|
parameters: [String: String],
|
|
accessKeySecret: String
|
|
) throws -> String {
|
|
var params = parameters
|
|
params["SignatureMethod"] = "HMAC-SHA1"
|
|
params["SignatureVersion"] = "1.0"
|
|
|
|
let sortedKeys = params.keys.sorted()
|
|
let canonicalQuery = sortedKeys
|
|
.compactMap { key -> String? in
|
|
guard let value = params[key] else { return nil }
|
|
return "\(percentEncode(key))=\(percentEncode(value))"
|
|
}
|
|
.joined(separator: "&")
|
|
|
|
let stringToSign = "\(method)&%2F&\(percentEncode(canonicalQuery))"
|
|
|
|
guard let keyData = "\(accessKeySecret)&".data(using: .utf8) else {
|
|
throw VODSignatureError.invalidKey
|
|
}
|
|
guard let messageData = stringToSign.data(using: .utf8) else {
|
|
throw VODSignatureError.encodingFailed
|
|
}
|
|
|
|
let key = SymmetricKey(data: keyData)
|
|
let signature = HMAC<Insecure.SHA1>.authenticationCode(for: messageData, using: key)
|
|
let signatureData = Data(signature)
|
|
return signatureData.base64EncodedString()
|
|
}
|
|
|
|
static func percentEncodePublic(_ value: String) -> String {
|
|
percentEncode(value)
|
|
}
|
|
|
|
private static func percentEncode(_ value: String) -> String {
|
|
let allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"
|
|
var result = ""
|
|
for char in value.utf8 {
|
|
if allowed.utf8.contains(char) {
|
|
result.append(Character(UnicodeScalar(char)))
|
|
} else {
|
|
result.append(String(format: "%%%02X", char))
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
}
|