This is a pre-production deployment of Warehouse. Changes made here affect the production instance of PyPI (pypi.python.org).
Help us improve Python packaging - Donate today!

HMAC signature library for http requests signing

Project Description

About

SignIt is a helper-library to create and verify HMAC (HMAC-SHA256 by default) signatures that could be used to sign requests to the APIs.


Use cases

On the client side you could

  • sign your requests using signit.signature.create()

On the server side you could

  • parse a signature retrieved from request header or query string using signit.signature.parse()
  • verify retrieved signature using signit.signature.verify()
  • generate access and secret keys for client using signit.key.generate()

Example of usage (client)

import datetime
import requests
import signit

ACCESS_KEY = 'MY_ACCESS_KEY'
SECRET_KEY = 'MY_SECRET_KEY'

def create_user(user: dict) -> bool:
    msg = str(datetime.datetime.utcnow().timestamp())
    auth = signit.signature.create(MY_ACCESS_KEY, MY_SECRET_KEY, msg)
    headers = {
        'Unix-Timestamp': msg,
        'Authorization': auth,
    }
    r = requests.post('http://example.com/users', json=user, headers=headers)
    return r.status_code == 201

The Authorization header will look like

Authorization: HMAC-SHA256 MY_ACCESS_KEY:0947c88ce16d078dde4a2aded1fe4627643a378757dccc3428c19569fea99542

Example of usage (server)

The server has issued an access key and a secret key for you. And only you and the server know the secret key.

So that the server could identify you by your public access key and ensure that you used the secret key to produce a hash of the message in this way:

# ...somewhere in my_api/resources/user.py
import signit
from aiohttp import web
from psycopg2 import IntegrityError

async def post(request):
    message = request.headers['Unix-Timestamp']
    signature = request.headers['Authorization']
    prefix, access_key, hmac_digest = signit.signature.parse(signature)
    secret_key = await get_secret_key_from_db(access_key)
    if not signit.signature.verify(hmac_digest, secret_key, message):
        raise web.HTTPUnauthorized('Invalid signature')
    try:
        await create_user(request)
    except IntegrityError:
        raise web.HTTPConflict()
    return web.HTTPCreated()

Additionally if you use a Unix-Timestamp as a message message the server could check if the request is too old and deny with 401 to protect against “replay attacks”.

Release History

Release History

This version
History Node

0.3.0

History Node

0.2.0

History Node

0.1.3

History Node

0.1.2

History Node

0.1.1

History Node

0.1.0

Download Files

Download Files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
signit-0.3.0-py2.py3-none-any.whl (6.3 kB) Copy SHA256 Checksum SHA256 2.7 Wheel Mar 17, 2016
signit-0.3.0.tar.gz (3.9 kB) Copy SHA256 Checksum SHA256 Source Mar 17, 2016

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting