The Apex Signature Validator is an AngularJS application that assists APEX API consumers in verifying whether signatures are generated correctly in their applications when making restful API calls to the APEX API Gateway. See it in action here.
You can find out more about Apex signature generation from our reference Node.js implementation at https://github.com/GovTechSG/node-apex-api-security.
-
If you are having trouble with CORS when testing your API endpoints, use the server backed signature validator at https://apex-signature-validator.app.gov.sg. See the section below for more details
-
Apex Signature Validator has been tested on Google Chrome, Firefox and Internet Explorer 11.
Full documentation for APEX App security
There are three components that are of importance when it comes to formulating the correct authorization header: basestring, signature, authorization header.
Either:
- The string of text (plaintext) that will be used for HMAC-SHA256 generation used in level 1 authentication. A shared key is used to generate this digest.
Or:
- The string of text (plaintext) that will be used to create a SHA256 with RSA signature using the consumer's PEM-formatted private key.
The composition of the basestring includes:
- {prefix}_app_id (Generated from the API Gateway)
- {prefix}_nonce
- {prefix}_signature_method(HmacSHA256 or SHA256withRSA)
- {prefix}_timestamp
- Any additional parameters (additional parameters do not require a prefix).
All parameters are ordered by their key names. An example of a basestring is as such:
GET&https://example.com/v1/helloworld/nocors&{prefix}_app_id=appid&{prefix}_nonce=59242635618& {prefix}_signature_method=SHA256withRSA&{prefix}_timestamp=1501147626306&{prefix}_version=1.0& firstparam=valueoffirstparam&secondparam=valueofsecondparam
A base64 representation of the digest (HMAC-SHA256 for level 1) or ciphertext (SHA256 with RSA for level 2) derived from the basestring.
The request authorization header begins with the prefix, the key 'realm' with the value being the api endpoint followed by all the parameters in key-value pairs separated by commas. The generated signature is included as {prefix}_signature. An example of a generated authorization header is as follows:
Authorization: Apex realm="https://example.com/v1/helloworld/nocors",{prefix}_app_id=appid,{prefix}_nonce="98344891638",{prefix}_signature="p1WxtrYhM5L8RkAwQQ59PoZ2+5Yr05kHtC0Bh+nalnPg7SuL4/TTcmxhRmGYioSyYQHoMpKyryx0QbWaBKZDRVK4nIiznJ9L9X+IUAQXMWwSdtjOnjMjgZF06EGfyClFbRIGjJDrbwJeuRutji3/qdj9vZMqXRY/hAwnIfTk7IWPUBd9OrQG0PHMDOREl1mAhABk04MOfTAXCMCwx6z70MoIrc0EhQuuygMertnFS4mU0+hxQtgrPjoDZLPsRgFIkU9iPCKKVAMMc3jAkZq6X8BKImJJB4fXMCv6CfCDwd0PFeY4TG6CFhU7h49XAS+e+sO3HWeCzyXxtinhywIxIw==",{prefix}_signature_method="SHA256withRSA",{prefix}_timestamp="1501225489066",{prefix}_version="1.0"
If you have request parameters that are reused often, you can load and save input request parameters in JSON files using the options menu located on the top right.
From the root directory:
$ npm install $ npm run build The minified production build will be compiled by webpack into the dist folder under your project root directory.
From the project root directory:
$ npm install $ npm run devserver This spins up a Webpack Dev Server instance that serves the bundled signature validator app (in memory). This server supports live reloading when changes are detected in the code base.
You can then access the development build on your browser at http://localhost:8080 by default.
- src - controllers - css - service - app.js - package.json - webpack.config.js - index.ejs Tracks library dependencies, notably Webpack that will be used to build the application. The build command in the script block instructs Webpack to look for the file webpack.config.js and displays the compilation progress. Refer to https://webpack.github.io/docs/cli.html for more information on Webpack cli commands.
Specify the entry the point app.js and the output of the bundled files. Plugins and module loaders are used to uglify and bundle css as Webpack does not come with css bundling capabilities by default.
The main angular module of the application and the entry point for Webpack. Controllers, factories and services are imported by Webpack with variable names and injected.
Application code resides within the src folder, separated into the controllers and service sub directories.
- navbarController.js manages the navigation bar
- paramsModalController.js manages the modal triggered by the options button on the navbar that allows user to save/load their parameters through a json formatted file.
- mainController.js manages the application form where users input their parameters, calls functions in service to generate basestrings and test their requests.
The controllers are hooked onto the index.html page through ng-controller attributes. The modal template also resides within index.html.
- config.js stores constant variables
- modalService.js is a singleton that stores parameters inputs to be fetched and share across both mainController and paramsModalController.
- testService.js functions that handle the process of generating basestring, signing basestring, creating auth header with the generated signature and sending the test requests
- utilityService utility functions that convert between formats e.g hex to base64
The JSRSASIGN library is the opensource free pure JavaScript cryptographic library used by the application to perform all digest and RSA related operations. Refer to http://kjur.github.io/jsrsasign/ for more information including the api documentation.
When sending test requests to Apex's gateways, eg. to api.gov.sg endpoints, the signature validator's Send Test Request function would need to make cross-origin requests. For security reasons, browsers restrict cross-origin HTTP requests initiated using Javascript.
If you are getting a response code of -1 when sending a test request, your browser could be rejecting your cross-origin request.
JOSE (Javascript Object Signing and Encryption) is an approach to signing and encrypting JSON content. If your API responses are packaged in any of the JOSE standards, you can use this client to further verify or decrpyt the corresponding API response.
- Input : JWS API Response from the Gateway. As of now, we are only supporting it in JSON format.
- Public Certificate/Key : Public certificate that will be used to verify the JSON Web Signature.
- Output : Data output upon successful verification.
- Input : JWE API Response from the Gateway in JSON format.
- Private Key : Private key that will be used to decrypt the JWE string.
- Output : Data output upon successful decryption.


