如何在服务器端Swift HTTPS端点中验证SNS消息?

xxslljrj  于 2024-01-05  发布在  Swift
关注(0)|答案(1)|浏览(168)

Amazon提供了documentation来验证路由到HTTP/HTTPS端点的SNS消息是否有效。在服务器上使用Vapor和Swift,沿着swift-certificatesswift-crypto,我实现了验证逻辑:

  1. func messageHasValidSignature<Message: VerifiableMessage>(_ message: Message) async throws -> Bool {
  2. guard let certificateBytes = try await client.get(.init(message.signingCertificateURL)).body else {
  3. logger.error("Failed to get signing certificate body")
  4. throw Abort(.badRequest)
  5. }
  6. let certificateString = String(buffer: certificateBytes)
  7. let certificate = try Certificate(pemEncoded: certificateString)
  8. let publicKey = try _RSA.Signing.PublicKey(derRepresentation: certificate.publicKey.subjectPublicKeyInfoBytes)
  9. guard let signatureData = Data(base64Encoded: message.signature) else {
  10. logger.error("Failed to decode signature")
  11. throw Abort(.badRequest)
  12. }
  13. let signature = _RSA.Signing.RSASignature(rawRepresentation: signatureData)
  14. guard let dataToSign = message.stringToSign.data(using: .utf8) else {
  15. logger.error("Failed to convert string to sign to data")
  16. throw Abort(.badRequest)
  17. }
  18. let digest: any Digest
  19. switch message.signatureVersion {
  20. case ._1:
  21. digest = Insecure.SHA1.hash(data: dataToSign)
  22. case ._2:
  23. digest = SHA256.hash(data: dataToSign)
  24. }
  25. return publicKey.isValidSignature(signature, for: digest)
  26. }

字符串
我正在构造要签名的字符串如下:

  1. extension SubscriptionConfirmationMessage: VerifiableMessage {
  2. var stringToSign: String {
  3. """
  4. Message
  5. \(message)
  6. MessageId
  7. \(messageID)
  8. SubscribeURL
  9. \(subscribeURL)
  10. Timestamp
  11. \(timestamp)
  12. Token
  13. \(token)
  14. TopicArn
  15. \(topicARN)
  16. Type
  17. SubscriptionConfirmation
  18. """
  19. }
  20. }


但是isValidSignature总是返回false。如何正确验证消息?

tgabmvqs

tgabmvqs1#

问题出在传递给isValidSignature的填充上。默认值是PSS(“使用MGF1的PSS填充”)。通过检查C#实现的源代码,我发现它应该是insecurePKCS1v1_5(“PKCS#1 v1.5”)。
验证签名的正确方法是:

  1. return publicKey.isValidSignature(signature, for: digest, padding: .insecurePKCS1v1_5)

字符串

相关问题