Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTTP Message Signatures

This library implements HTTP Message Signatures. The underlying crypto is provided by PyCryptodomex.

Pypi Page: https://pypi.org/project/httpsigpy/

Usage:

from httpsig import *

Signing

To sign an HTTP message, first it has to be parsed into its message components:

msg = event['body'].encode('utf-8')
components = parse_components(msg)

This provides a data structure with each possible message component indexed by its name, identifier, and value.

To create the signature input, pass in the parsed components structure as well as a list of components to sign, with the signature parameters:

siginput = generate_input(
    components, 
    ( # covered components list
        { 'id': "@method" }, 
        { 'id': "@authority" },
        { 'id': "@path" },
        { 'id': "content-digest" },
        { 'id': "content-length" },
        { 'id': "content-type" }
    ),
    {
        'created': 1618884473,
        'keyid': 'test-key-rsa-pss'
    }
)

base = siginput['signatureInput']
sigparams = siginput['signatureParams']

This outputs a base string that can be passed to the signer.

key = RSA.import_key(PKCS8.unwrap(PEM.decode(rsaTestKeyPssPrivate)[0])[1])

h = SHA512.new(base.encode('utf-8'))
signer = pss.new(key, mask_func=mgf512, salt_bytes=64)

signed = http_sfv.Item(signer.sign(h))

Verify

To verify an HTTP message, first it has to be parsed into its message components:

msg = event['body'].encode('utf-8')
components = parse_components(msg)

This provides a data structure with each possible message component indexed by its name, identifier, and value.

To create the signature input, pass in the parsed components structure as well as a list of components to sign, and the signature parameters.

siginput = generate_input(
    components, 
    ( # covered components list
        { 'id': "@method" }, 
        { 'id': "@authority" },
        { 'id': "@path" },
        { 'id': "content-digest" },
        { 'id': "content-length" },
        { 'id': "content-type" }
    ),
    {
        'created': 1618884473,
        'keyid': 'test-key-rsa-pss'
    }
)

This can be passed to the verifier function:

h = SHA512.new(base.encode('utf-8'))

pubKey = RSA.import_key(rsaTestKeyPssPublic)
verifier = pss.new(pubKey, mask_func=mgf512, salt_bytes=64)

try:
    verified = verifier.verify(h, signed.value)
    print('> YES!')
except (ValueError, TypeError):
    print('> NO!')

About

HTTP Message Signatures for Python 3

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages