Skip to main content
This is a pre-production deployment of Warehouse. Changes made here affect the production instance of PyPI (
Help us improve Python packaging - Donate today!

pyTickets are light-weight symmetrically signed data containers with optional encryption, serialization and compression of their contents. Now includes an *alpha* DiffieHellman implementation. Do not trust it yet :-)

Project Description

*SecureTicketService* is used to create and validate *SecureTickets*.
*SecureTickets* are light-weight symmetrically signed data sets with
a limited lifestpan.

The *key* passed to *SecureTicketService* is the password and the
security relies heavily on its strength. It really should be a 32 byte
random string as you gain integrity AND performance by using a key of
32 bytes length (it's padded or replaced by SHA256-hashes of itself
to make it 32 bytes anyways).
For your convenience, classmethod *create_random_key()* is provided:

>>> key = SecureTicketService.create_random_key()
>>> assert len(key) == 32
>>> sts = SecureTicketService(key)

A SecureTicket *ticket* which is successfully validated using
``SecureTicketService.validate_ticket()`` can only be created by
someone who has knowledge of *key*. The entire contents of *ticket* is
securely hashed using *key* and any change to *ticket* breaks the hash

>>> key = 'Io5IpK9ZTsKpG1ybaLCHkOH4kvHaTEO2imHvkqLVn7I='
>>> sts = SecureTicketService(key.decode('base64'))
>>> ticket = sts.create_ticket('someData')
>>> sts.validate_ticket(ticket)
>>> sts2 = SecureTicketService('someOtherKey')
>>> sts2.validate_ticket(ticket)


The optional second argument *entropy* to *create_ticket()*, which must be
a string if supplied, cannot be obtained from a ticket; it's just
concatinated together with the rest of ticket when the hash is created.
The same *entropy* value must therefore be used in
``SecureTicketService.validate_hash()`` or else validation fails.

>>> ticket = sts.create_ticket('someKey', 'someEntropy')
>>> sts.validate_ticket(ticket)
>>> sts.validate_ticket(ticket, 'someEntropy')


Many use cases for secure tickets involves (or should involve) the concept
of a session to prevent various types of attacks. The optional second
argument *session* to *SecureTicketService()* is used in the same manner as
*entropy*, but is supplied during *SecureTicketService* instantiation
instead of during ticket creation.

>>> sts = SecureTicketService(key, 'someSessionIdentifier')


Encryption, serialization and compression of *ticket*'s contents is
optional. Encrypted tickets will have all its data and metadata encrypted
with the *key* supplied to *SecureTicketService*. Serialization allows
complex data types in *data* instead of just strings. Compression
(zlib) is useful if the *data* argument is inconveniently large.
Options and their default values:

* serialize=False
* encrypt=False
* compress=False

Encrypted ticket attributes must be viewed through a *SecureTicketService*
instance which provide transparent decryption:

>>> key = SecureTicketService.create_random_key()
>>> sts = SecureTicketService(key, serialize=1, compress=1, encrypt=1)
>>> ticket = sts.create_ticket(['asd', 123], 'ee')
>>> assert sts.get_data(ticket) == sts(ticket).data == ['asd', 123]

DiffieHellman, DiffieHellmanClient, DiffieHellmanServer
*DiffieHellman* implements the Diffie Hellman key exchange algorithm.
Variable names in the implementation match those from
*Diffie-Hellman Key Agreement Method (RFC 2631)*, but in each method *xa* and
*ya* are used for the secret and the exposed key parts in *self* while *xb*
(which is never seen) and *yb* is the key parts of the other party.

>>> a = DiffieHellman(psize=2048) # prime size defaults to 1536
>>> b = DiffieHellman(psize=2048)
>>> ZZa = a.calc_ZZ(b.ya) # ZZ is the negotiated secret
>>> ZZb = b.calc_ZZ(a.ya)
>>> ZZa == ZZb
>>> type(ZZa)
<type 'long'>
>>> strZZ = tickets.crypto.util.long2str(ZZa)
>>> type(strZZ)
<type 'str'>

*DiffieHellmanClient* and *DiffieHellmanServer* implements a protocol by
which two parties are able to perform a Diffie Hellman key exchange and
to verify that the other party has successfully derived the same secret

The protocol follows the common Diffie Hellman scheme, but additionally
includes generation and validation of SHA256-HMAC digests, using the
negotiated key, of some of the negotiation messages. This is in a sense
similar to the well known TCP three way handshake.

>>> c = DiffieHellmanClient(asize=256) # asize should be 256 for aes128
>>> s = DiffieHellmanServer() # will adapt to client in 'hello' phase
>>> A = c.client_hello()
>>> B = s.server_hello(A)
>>> C = c.client_verify(B)
>>> s.server_verify(C)
>>> c.negotiated_key == s.negotiated_key
>>> type(c.negotiated_key)
<type 'str'>

Release History

This version
History Node

History Node


History Node


History Node


Download Files

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

Filename, Size & Hash SHA256 Hash Help File Type Python Version Upload Date
(24.2 kB) Copy SHA256 Hash SHA256
Source None Jan 17, 2012

Supported By

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 Google Google Cloud Servers