Skip to content

Instantly share code, notes, and snippets.

@jiaaro
Created August 14, 2012 20:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jiaaro/3352528 to your computer and use it in GitHub Desktop.
Save jiaaro/3352528 to your computer and use it in GitHub Desktop.
Rootbuzz Request signing
<?php
function apisig($salt, $dataDict) {
# sort the data by key
ksort($dataDict);
# url encode the data
$dataStr = http_build_query($dataDict);
# %20 is more robust than + for spaces
$dataStr = str_replace("+", "%20", $dataStr);
# make the hash and return the hex version of the output
return sha1($salt . $dataStr);
}
function signRequest($salt, $requestData) {
if (array_key_exists('s', $requestData)) {
unset($requestData['s']);
}
$requestData['s'] = apisig($salt, $requestData);
return $requestData;
}
function isValid($salt, $signedRequest) {
$signedRequestClone = $signedRequest;
$signature = $signedRequestClone["s"];
unset($signedRequestClone["s"]);
return ($signature == apisig($salt, $signedRequestClone));
}
?>
from urllib import urlencode
from hashlib import sha1
def apisig(salt, data_dict):
# put sort the data by key, and store it in an ordered dict
data = sorted(data_dict.items())
data_str = urlencode(data)
# %20 is more robust than + for spaces
data_str = data_str.replace("+", "%20")
# make the hash and return the hex version of the output
return sha1(salt + data_str).hexdigest()
def sign_request(salt, request_data):
if "s" in request_data:
request_data.pop("s")
request_data["s"] = apisig(salt, request_data)
return request_data
def is_valid(salt, signed_request):
signed_request = signed_request.copy()
signature = signed_request.pop("s")
return signature == apisig(salt, signed_request)
###############################
########## Tests ##########
###############################
# example salt
salt = "51f7b5601fcbae7d44692e690cce4d9ef8b87a48"
# simulate logged in user
data1 = {
"user_id": 2348768723,
"email": "hi-mom+nospam@gmail.com"
}
assert apisig(salt, data1) == "be457f788510725104923f300a7bf20a75977aa2"
assert sign_request(salt, data1) == {
"user_id": 2348768723,
"email": "hi-mom+nospam@gmail.com",
"s": "be457f788510725104923f300a7bf20a75977aa2"
}
# simulate anonymous user
data2 = {
"user_id": None
}
assert apisig(salt, data2) == "4a66714331fe8e82de4c106911b2db8bf84a13d3"
assert sign_request(salt, data2) == {
"user_id": None,
"s": "4a66714331fe8e82de4c106911b2db8bf84a13d3"
}
# checking a request signature
signed1 = {
'email': 'hi-mom+nospam@gmail.com',
's': 'be457f788510725104923f300a7bf20a75977aa2',
'user_id': 2348768723
}
signed2 = {
's': '4a66714331fe8e82de4c106911b2db8bf84a13d3',
'user_id': None
}
assert is_valid(salt, signed1)
assert is_valid(salt, signed2)
# requires addressable (i.e. gem install addressable)
require 'digest/sha1'
require "addressable/uri"
def apisig(salt, data_dict)
uri = Addressable::URI.new
uri.query_values = data_dict.sort_by {|k, v| k}.map {|k,v| v.nil? ? [k,"None"] : [k,v] }
Digest::SHA1.hexdigest salt + uri.query
end
def sign_request(salt, request_data)
if request_data.has_key? "s"
request_data.delete "s"
end
request_data["s"] = apisig salt, request_data
return request_data
end
def is_valid(salt, signed_request)
signature = signed_request["s"]
request = signed_request.clone
request.delete "s"
return signature == apisig(salt, request)
end
###############################
########## Tests ##########
###############################
# helper fn from http://www.dzone.com/snippets/basic-ruby-assert-function
def assert(conditional)
raise "Assertion failed !" unless conditional
end
# example salt
salt = "51f7b5601fcbae7d44692e690cce4d9ef8b87a48"
# simulate logged in user
data1 = {
"user_id" => 2348768723,
"email" => "hi-mom+nospam@gmail.com"
}
assert apisig(salt, data1) == "be457f788510725104923f300a7bf20a75977aa2"
assert sign_request(salt, data1) == {
"user_id" => 2348768723,
"email" => "hi-mom+nospam@gmail.com",
"s" => "be457f788510725104923f300a7bf20a75977aa2"
}
# simulate anonymous user
data2 = {
"user_id" => nil
}
assert apisig(salt, data2) == "4a66714331fe8e82de4c106911b2db8bf84a13d3"
assert sign_request(salt, data2) == {
"user_id" => nil,
"s" => "4a66714331fe8e82de4c106911b2db8bf84a13d3"
}
# checking a request signature
signed1 = {
'email' => 'hi-mom+nospam@gmail.com',
's' => 'be457f788510725104923f300a7bf20a75977aa2',
'user_id' => 2348768723
}
signed2 = {
's' => '4a66714331fe8e82de4c106911b2db8bf84a13d3',
'user_id' => nil
}
assert is_valid(salt, signed1)
assert is_valid(salt, signed2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment