我使用Java 2.x的AWS SDK,依赖software.amazon.awssdk: sns
我通过http收到来自sns主题的消息。我想知道是否有任何官方或非官方但支持良好的库可以做签名验证。
我已经使用来自https://docs.aws.amazon.com/sns/latest/dg/sns-example-code-endpoint-java-servlet.html的代码片段实现了验证,但也许更好的解决方案是现有的
public void verifySignature(SnsMessage message) {
String signatureVersion = message.getSignatureVersion();
if (signatureVersion.equals("1")) {
// Check the signature and throw an exception if the signature verification fails.
if (isMessageSignatureVersion1Valid(message)) {
log.info("Signature verification succeeded");
} else {
log.info("Signature verification failed");
throw new SecurityException("Signature verification failed.");
}
} else {
log.info("Unexpected signature version. Unable to verify signature.");
throw new SecurityException("Unexpected signature version. Unable to verify signature.");
}
}
在撰写本文时(2021年8月)针对Java 2的AWS SDK。x还不支持Java 1.x的AWS SDK的所有特性。但幸运的是,你可以同时使用它们。引用自官方文档:
您可以在您的项目中使用两个版本的AWS SDK。
在1中。x,你有SnsMessageManager,它显然在做这个工作:
公共类SnsMessageManager
扩展对象
解编组SNS消息并使用SNS公共证书对其进行验证。
目前最新版本的SNS SDK1.12.286-签名验证在消息反序列化到SnsMessage对象时自动完成。
您可以使用SnsMessageManager#parseMessage将传入消息反序列化为SnsMessage对象。
From SNS SDK javadoc:将消息解组到SnsMessage的子类中。这将自动验证消息的真实性,以确保它是由SNS发送的。如果无法验证消息的有效性,将引发异常。参数:messageBody——包含消息JSON的输入流。返回:非编组消息对象。
从SNS SDK源代码中也可以看出:
SnsMessageManager#parseMessage -> SignatureVerifier#verifySignature
这样就可以了:
InputStream messageInputStream = "<message received from SNS>"
SnsMessage snsMessage = new SnsMessageManager().parseMessage(messageInputStream)
查看SNS文档的这一部分对于签名验证细节很有用。