AWS SNS signature verification

Hi,

I am creating a proxy which will act as AWS SNS Subscriber. I need to verify the signature, before processing the request. Has anyone worked on similar requirement before and provide some help on how we can achieve this in apigee.

Sample Request Message -

POST / HTTP/1.1
    x-amz-sns-message-type: Notification
    x-amz-sns-message-id: 22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324
    x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
    x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96
    Content-Length: 773
    Content-Type: text/plain; charset=UTF-8
    Host: example.com
    Connection: Keep-Alive
    User-Agent: Amazon Simple Notification Service Agent
    
{
  "Type" : "Notification",
  "MessageId" : "22b80b92-fdea-4c2c-8f9d-bdfb0c7bf324",
  "TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
  "Subject" : "My First Message",
  "Message" : "Hello world!",
  "Timestamp" : "2012-05-02T00:54:06.655Z",
  "SignatureVersion" : "1",
  "Signature" : "EXAMPLEw6JRN...",
  "SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
  "UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:c9135db0-26c4-47ec-8998-413945fb5a96"
}

Thanks.

@Dino-at-Google

Solved Solved
0 7 1,509
1 ACCEPTED SOLUTION

I think you could do this pretty easily in a Java callout, starting from the documentation from AWS describing how to verify a signature on an SNS message.

I can put that together (example repo), but I don't have a good way to test that the code I have is working. If you gave me a couple test messages I could test it to verify that it is working.

View solution in original post

7 REPLIES 7

I think you could do this pretty easily in a Java callout, starting from the documentation from AWS describing how to verify a signature on an SNS message.

I can put that together (example repo), but I don't have a good way to test that the code I have is working. If you gave me a couple test messages I could test it to verify that it is working.

@Apoorva - any feedback on this answer?

Thanks Dino. Yes, we had implemented signature verification in java callout and it is working fine.

 
 

Hi Dino,

I'm using java callout for SNS signature validations but seeing below exception.

javax.json.JsonException: Provider org.glassfish.json.JsonProviderImpl not found

Could you please help in identifying cause of this exception.

Regards,

Sarath

Hi Sarath

It's possible that this answer applies here. 

Can you add that dependency to the pom.xml file, rebuild, and try? 

Alternatively you can try downloading the appropriate jar from the maven repo. Add that jar to the list of resources for the callout, and then redeploy the proxy, and retry. 

Let me know how it goes.  I will want to update the pom file for the repo, if this solves your problem.

What version of Apigee are you using? 

 

Hi Dino,

Thankyou for the response..

EdgeUI version 21.03.10

New Jar file resolved the Json parsing issue but got in to below exception. The Signing Cert URL is hosted at amazonaws.com, Is it failing somewhere else?

awssns_exception java.lang.SecurityException: Verify failed

Stack_Trace-->

java.lang.SecurityException: Verify failed at com.google.apigee.callouts.AwsSnsSignatureVerifier.isMessageSignatureValid(AwsSnsSignatureVerifier.java:84) at com.google.apigee.callouts.AwsSnsSignatureVerifier.execute(AwsSnsSignatureVerifier.java:239) at com.apigee.steps.javacallout.JavaCalloutStepDefinition$ClassLoadWrappedExecution.execute(JavaCalloutStepDefinition.java:235) at com.apigee.steps.javacallout.JavaCalloutStepDefinition$SecurityWrappedExecution$1.run(JavaCalloutStepDefinition.java:302) at com.apigee.steps.javacallout.JavaCalloutStepDefinition$SecurityWrappedExecution$1.run(JavaCalloutStepDefinition.java:300) at java.security.AccessController.doPrivileged(Native Method) at com.apigee.steps.javacallout.JavaCalloutStepDefinition$SecurityWrappedExecution.execute(JavaCalloutStepDefinition.java:300) at com.apigee.steps.javacallout.JavaCalloutStepDefinition$CallOutWrapper.execute(JavaCalloutStepDefinition.java:169) at com.apigee.messaging.runtime.steps.StepExecution.execute(StepExecution.java:157) at com.apigee.flow.execution.AbstractAsyncExecutionStrategy$AsyncExecutionTask.call(AbstractAsyncExecutionStrategy.java:83) at com.apigee.flow.execution.AbstractAsyncExecutionStrategy$AsyncExecutionTask.call(AbstractAsyncExecutionStrategy.java:48) at com.apigee.threadpool.CallableWrapperForMDCPreservation.call(CallableWrapperForMDCPreservation.java:26) at com.apigee.threadpool.ThreadPoolManager$QueueAwareCallableTask.call(ThreadPoolManager.java:546) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.SecurityException: SigningCertUrl appears to be invalid. at com.google.apigee.callouts.AwsSnsSignatureVerifier.verifyCertificateURL(AwsSnsSignatureVerifier.java:98) at com.google.apigee.callouts.AwsSnsSignatureVerifier.isMessageSignatureValid(AwsSnsSignatureVerifier.java:78)

Regards,

Sarath

It seems like there is no problem with the Cert. The cert is valid, has been parsed correctly.  The message is indicating that the signature verification failed. That happens if: 

  • there is a key mismatch.  I guess you insured that you're using the right keys. 
  • The signature has not been created correctly. 

Sig verification failures are hard to troubleshoot. The only advice I have for you is to go back to the beginning, figure out how you'e created the sig, make sure that you're following the spec, and just keep testing variations.