OAuth 1.0a Request Signing and Verification - HMAC-SHA1 - HMAC-SHA256

This is a security project that I did this Fall semester. I was interested in why the OAuth1.0a specification did not require you to sign a request using RSA-SHA1 or any RSA algorithm. The first issue that I found is where would you store your private keys in a javascript client? - as a javascript encrypted file ? from the browser ?  - that will be a security hole if you allow javascript to get private keys. These are some of the questions that got me asking and which I cannot find answers to for now.

OAuth 1.0a Signature Signing and Verification using JavaScript Implementation


Background

The OAuth specification tries to define an API authentication method that allows consumer websites or applications to access protected API Resources from a Service provider. The advantage that OAuth provides is that the user of the website or application is not required to disclose their credentials to their service provider. Another advantage of using OAuth to authenticate is that it does not require a specific user interface for how Service providers will authenticate a user [1].
Section 9 of the of the OAuth specification [1] specifies that all Token requests and Protected resources requests must be signed by the Consumer and verified by the Service Provider. As we have learned in class, Digital Signature provides authentication and some form of non-repudiation if it is signed by a private key. The signature in the OAuth specification is a hash of the request (a specific format is needed – the Signature Base String) using the users Consumer secret (sort of a private key). As mentioned in the specification, the purpose of signing requests is to prevent unauthorized parties from using the Consumer Key and Tokens when making Token request or Protected Resources requests. The signature is based on encoding the Consumer secret and Token secret (which is unique for each consumer) into a verifiable value which is included with the request.
OAuth does not mandate a particular signature method. The OAuth 1.0a protocol defines three signature methods: HMAC-SHA1, RSA-SHA1, and PLAINTEXT but Service providers are free to implement and document their own methods. This means that the protocol allows flexibility to use any signature method.
The signature is based on the Signature Base String (Section 9.1 [1]). The Signature Base String is the concatenation of following items into a single string, where each item is encoded (Section 5.1 [1]) and separated by ‘&’ (ampersand) character (ASCII code 38), even if the item is empty.
1. The HTTP Request method used to send the request. Value must be uppercase, for example: HEAD, GET, POST etc.
2. The request URL based on (Section 9.1.2 [1]).
(Please see section 9.1.2 how the URL is formed. Here is a link)
3. The normalized request parameters string (Section 9.1.1 [1]).
(Please see section 9.1.1 how to normalize request parameters. Here is a link)

Sample Signature base string: (based on the implementation for this research paper)
Blue = Request Method
Green = Request URL
Red = Normalized request parameters

POST&http%3A%2F%2Flocalhost%3A3000%2Fsample&oauth_consumer_key%3Dtestkey%26oauth_nonce%3DVNl2QAsefSVvZg0CxT9j6SJcPlnRDi01%26oauth_signature%3DA3jkT%252Bm4MZV6M2jxQxPGCRhJlcs%253D%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1446170859%26oauth_token%3Dtestkey%26oauth_version%3D1.0

Purpose of this research

The purpose of this research paper is to implement, learn the signing methods and verification methods for OAuth using JavaScript. Since the popularity of single page application using JavaScript and HTML is on the rise, this research will look into the following:
1. Cryptographic libraries in java script
a. Investigate what the current OAuth signing libraries are using to encode the signature
2. Implement OAuth signing in JavaScript using open source libraries
a. Add a signing method
3. Verify OAuth signature in JavaScript server side in Node using open source libraries
a. Add a verification for a signing method

Cryptographic libraries in JavaScript

While implementing the signing in JavaScript the following were used as the cryptographic libraries.
1. Crypto-js https://code.google.com/p/crypto-js/
This is the library that was used to do the HMAC-SHA1 and HMAC-SHA256 signing. This library has decent cryptographic capabilities like Hashing, Message Authentication Code and ciphers. It is good to know that most of the major algorithms for conventional cryptography are supported in this library (no RSA).


2. jsrsasign http://kjur.github.io/jsrsasign/
This is the library that was used to do the RSA-SHA1 signing. It also provides base64 encoding. This library was also used to generate the Private Key and Public Key pair. This JavaScript library is focused on private-public key cryptography (RSA). It also has support for Digital Certificates (X.509)

Maybe in the future a JavaScript library should be created to have conventional and public key cryptography in one library so that client and server side JavaScript will have less dependency.
Implement OAuth 1.0a signing in JavaScript using open source libraries

Since OAuth is being used by several popular services like Twitter, Flickr, Bitbucket, Linkedin, there are many JavaScript libraries that will help you create an OAuth signature. The one used for this research is oauth1.0a.js library which can be found here https://github.com/ddo/oauth-1.0a. The library implements the following signature signing on the browser out of the box HMAC-SHA1, HMAC-SHA256, and PLAINTEXT. The signature signing uses the Crypto-js library. The library has a dependency on Crypto-js. The implementation is missing the RSA-SHA1 implementation. I have added the RSA-SHA1 implementation for signature signing which uses the jsrsasign library.


Figure 1. Screen capture of the implementation of the RSA-SHA1 signing method. Lines 54-66 of the oauth1.0.a.js

Verify OAuth 1.0a signature in JavaScript server side in Node using open source libraries


After signing a request we need to be able to verify the signature on the server side. The server side implementation uses Node with the node module Express to serve up web static content and REST [2] services. To verify the OAuth signature a middleware function for Node Express application was used which can be found here https://github.com/keybuk/node-express-oauth. The library only supports PLAINTEXT and HMAC-SHA1 signature verification. I have added the HMAC-SHA256 and RSA-SHA1 implementation for signature verification. The server side library uses the same Crypto-js library to verify the signature. I have to add the jsrsasign dependency to do the RSA-SHA1 signature verification.


Figure 2. Screen capture of the implementation of HMAC-SHA256 and RSA-SHA1. Lines 181-195 of the oauth.js file
Implementation Details
The implementation used JavaScript on the browser and JavaScript on the server side in Node.


Figure 3. Browser and Server Communication Diagram



Implementation Folder Structure and Files
Here is the folder structure and files of the implementation. All of these files can be found in this repository https://github.com/petabyte/SEIS720. A short video to install and run can be found here https://youtu.be/0lXqHLTQmR0.


Figure 4. Implementation Folder Structure
Run the code

After install you should be able to hit http://localhost:3000 on your computer. The link will bring up a page like this.


Figure 5. Page after running the implementation
The page will contain each implemented signature method with the following details:

HMAC-SHA1

Response from server: This is the data that was requested via Oauth
Server response time (including signature verification): 1.513ms
Client Signature method: HMAC-SHA1
Client Signature Base String: POST&http%3A%2F%2Flocalhost%3A3000%2Fsample&oauth_consumer_key%3Dtestkey%26oauth_nonce%3DOcHPsdqNtRsTeonRhJsTE7eXTBPgYfdo%26oauth_signature%3DzYUBJA3RatAiV8eUGEkWvSXHAf8%253D%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1446416650%26oauth_token%3Dtestkey%26oauth_version%3D1.0
Client Signature: 4Prn5N6YRXHrriAwJtj97FWUJxM=
Client Side Timing: 5 in milliseconds

Timing for Each Signature Method

I tried to get the average time (5 request each) for each signature method.
Here are the timings

Signature Method
Client Side Signing Timing
Server Response Time (with Verification)
Average Total Time
HMAC-SHA1
2.41 ms
2.411 ms
~ 5 ms
HMAC-SHA256
2.2 ms
2.937 ms
~ 5.13 ms
PLAINTEXT
1 ms
1.301 ms
~ 2 ms
RSA-SHA1
31 ms
8.398 ms
~ 40 ms


Conclusion

Using JavaScript prove to be advantageous because the same library can be used in the client and server side. I have learned that there are some decent JavaScript libraries out there that supports conventional cryptography and public key cryptography. There is an opportunity to create a library that does both. Right now you have to use two or more JavaScript libraries to support both. The OAuth specification about signing request is flexible enough to accommodate any advancement in signature encoding as long as the methods of signing are conveyed to the Consumer by the Service provider. Key storage for key pairs can be an issue for using JavaScript. There is no protected key store management like the one provided in Java. The keys can be stored as ASCII (Base64) data. Even though this is supported by X.509 Certificate standard managing the file that contains the information can easily be copied.

References

[1] OAuth Core 1.0 Revision A. (n.d.). Retrieved October 30, 2015.
[2] Fielding, R. (2000). Architectural Styles and the Design of Network-based Software Architectures. Retrieved October 30, 2015.
[3] Fielding, R. (2000). CHAPTER 5. Retrieved October 30, 2015.


Comments

Popular posts from this blog

Spark DataFrame - Array[ByteBuffer] - IllegalAurmentException

Gensim Doc2Vec on Spark - a quest to get the right Vector