【发布时间】:2021-05-31 17:18:51
【问题描述】:
我使用 DCAppAttestService 生成一个断言对象并将其发送到我的 Cloud Functions 服务器 - 以验证应用内购买是否来自我的应用的合法实例。
这是我的 Swift 代码,当进行应用内购买时:
- 从我的服务器检索一次性质询(字符串)
- 使用该字符串以及客户端数据来生成哈希
- 使用该哈希和设备的
keyID,调用generateAssertion() - 发送断言对象和客户端数据对象的 base64 编码字符串
斯威夫特:
func callSensitiveFunction(name: String, data: [String:String], completion: @escaping (HTTPSCallableResult?, Error?)->()){
var functions = Functions.functions()
var adjustedData: [String:String] = data
guard let keyID = KeychainWrapper.standard.string(forKey: "attestKeyID") else {
print("no attest ID, return")
return
}
let service = DCAppAttestService.shared
// Retrieve the challenge string
functions.httpsCallable("getChallengeString").call(data){ (result, error) in
if let challengeString = result?.data as? String {
// Retrieve the keyID (public key) which was saved at first launch
guard let attestKeyID = KeychainWrapper.standard.string(forKey: "attestKeyID") else { return print("No attestKeyID found") }
// Add challenge string to request
adjustedData["challenge"] = challengeString
// Hash client data (which includes challenge string)
guard let clientData = try? JSONEncoder().encode(adjustedData) else { return }
let clientDataHash = Data(SHA256.hash(data: clientData))
service.generateAssertion(attestKeyID, clientDataHash: clientDataHash) { assertion, err in
guard error == nil else { return print("generateAssertion() error: \(error)") }
let assertionString = assertion?.base64EncodedString() ?? ""
let clientDataString = clientData.base64EncodedString()
adjustedData["assertionString"] = assertionString
adjustedData["clientData"] = clientDataString
functions.httpsCallable(name).call(adjustedData){ (result, error) in
completion(result, error)
print("function \(name) completed")
}
}
}
}
}
但是,当我在后端 (Node.js) 中收到 assertionString 时 - 我不知道如何解码它。使用本教程here 我已经做到了这一点:
const cbor = require("cbor");
const base64url = require('base64url');
let verifyAppleAnonymousAttestation = (assertionString) => {
let assertionBuffer = base64url.toBuffer(assertionString);
console.log(`assertionBuffer: ${assertionBuffer}`) // assertionBuffer: �isignatureXG0E!���56��r��@��@J�r+X������ڳ%� D��c!
let assertionStruct = cbor.decodeAllSync(assertionBuffer)[0];
console.log(`assertionStruct[0]: ${assertionStruct[0]}`) // assertionStruct: [object Object]
但是我不确定从这里去哪里来验证断言字符串。 Apple says assertion 被解码后看起来像这样:
{
signature: <Buffer 30 45 02 20 ... >,
authenticatorData: <Buffer 21 c9 9e 00 ... >
}
知道如何从assertionString 中提取所有验证数据吗?
【问题讨论】:
标签: ios node.js swift encryption base64