Last active
March 13, 2021 20:27
-
-
Save drewmccormack/a51b18ffeda8f596a11a8623481344d8 to your computer and use it in GitHub Desktop.
How to verify the Paddle webhook signature in Swift 3 using the Vapor packages CTLS and Crypto (include OpenSSL)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Verify the signature passed with the Paddle request parameters. | |
/// Details here: https://paddle.com/docs/reference-verifying-webhooks | |
func verifyPaddleSignature(inParameters parameters: [String:String]) throws -> Bool { | |
guard let signatureString = parameters[PaddleParameter.signature.rawValue], | |
let signature = Data(base64Encoded: signatureString) else { | |
return false | |
} | |
// Need to gather sorted parameters | |
var signatureParameters = parameters | |
signatureParameters.removeValue(forKey: PaddleParameter.signature.rawValue) | |
let sortedParameters = signatureParameters.sorted { $0.0 < $1.0 } | |
// Serialize using PHP serialize format. | |
var serializedParameters = "a:\(sortedParameters.count):{" | |
for pair in sortedParameters { | |
let keyLength = pair.key.count | |
let valueLength = pair.value.utf8.count | |
serializedParameters.append("s:\(keyLength):\"\(pair.key)\";s:\(valueLength):\"\(pair.value)\";") | |
} | |
serializedParameters.append("}") | |
guard let serializedParameterData = serializedParameters.data(using: .utf8) else { | |
return false | |
} | |
// Verify RSA signature | |
let publicKeyString = | |
"MIICIjANBgkqhaiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqFPF0PPNa+gDOBYlFYut" + | |
"QrFb1k7JOq2L3fwCZqTjzRGTUWC14UZJsf++sAAR5uzwhYXQI4zNpFGvMtgpmmVD" + | |
"<Replace all this with your key from Paddle>" + | |
"f2tltF2XkY+nn30A2CWsP2sCAwEAAQ==" | |
let publicKey = try CryptorRSA.createPublicKey(withBase64: publicKeyString) | |
let signedData = CryptorRSA.createSigned(with: signature) | |
return try CryptorRSA.createPlaintext(with: serializedParameterData).verify(with: publicKey, signature: signedData, algorithm: .sha1) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment