Gallery of Twitter API nonce overkills

2014-07-16 00:00:00 +0100


Looking for a Twitter API library that would work with Python 3 I stumbled upon a number of projects that implement OAuth authentication protocol in a rather superfulous way (but “baroque” would be a better word here). After seeing how it’s done in TweetPony (file api.py) I had to think for a while:

return base64.b64encode(hashlib.sha1(str(random.getrandbits(256))).digest(), random.choice(['rA','aZ','gQ','hH','hG','aR','DD'])).rstrip('==')

These double encodings seem strange, but what are these “magic values” (‘rA’ etc) for? I could not find any other explanation rather than an attempt to “increase” randomness and unprictability. By a factor of 7…

Another example seems to be very popular in .NET world (Twitter API with OAuth):

string oauthnonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));

Technically this is much simpler that the TweetPony one. BASE64 is probably not necessary and using a timestamp alone is a bit risky, because system time can be reset back — e.g. by NTP time synchronisation — and the nonce will no longer be a nonce. So a random component is missing here…

The same problem is apparent in this JavaScript snippet (How to use Twitter OAuth 1.1 with JavaScript JQuery):

'oauth_nonce' => time(),

Another example, this time for PHP, is a study of elegance and simplicity (Understanding OAuth 1):

$nonce = md5(mt_rand());

That’s it! mt_rand() does not produce cryptographically strong randoms but for a nonce it should be sufficiently good.

The Python 3 library for Twitter I’ve eventually ended up with is birdy. No, it does not implement OAauth — it relies on oauthlib that uses a mix of random number and a timestamp (common.py):

return unicode_type(unicode_type(random.getrandbits(64)) + generate_timestamp())

Just for reference, here’s what the original OAuth 1.0 reference says about the nonce:

The Consumer SHALL then generate a Nonce value that is unique for all requests with that timestamp. A nonce is a random string, uniquely generated for each request. The nonce allows the Service Provider to verify that a request has never been made before and helps prevent replay attacks when requests are made over a non-secure channel (such as HTTP).

RFC 5849 (OAuth 1.1) is more verbose on that topic:

A nonce is a random string, uniquely generated by the client to allow the server to verify that a request has never been made before and helps prevent replay attacks when requests are made over a non-secure channel. The nonce value MUST be unique across all requests with the same timestamp, client credentials, and token combinations. To avoid the need to retain an infinite number of nonce values for future checks, servers MAY choose to restrict the time period after which a request with an old timestamp is rejected. Note that this restriction implies a level of synchronization between the client's and server's clocks. Servers applying such a restriction MAY provide a way for the client to sync with the server's clock; alternatively, both systems could synchronize with a trusted time service. Details of clock synchronization strategies are beyond the scope of this specification.

OAuth 2 (RFC 6749) does not define any rules on nonce usage because specific protocol details are delegated to an upcomingMAC Access Authentication> draft, which defines the nonce as follows:

REQUIRED. A unique string generated by the client. The value MUST be unique across all requests with the same timestamp and MAC key identifier combination.