Package: pytickets
*SecureTicketService* is used to create and validate *SecureTickets*.*SecureTickets* are light-weight symmetrically signed data sets witha limited lifestpan.The *key* passed to *SecureTicketService* is the password and thesecurity relies heavily on its strength.  It really should be a 32 byterandom string as you gain integrity AND performance by using a key of32 bytes length (it's padded or replaced by SHA256-hashes of itselfto 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 bysomeone who has knowledge of *key*. The entire contents of *ticket* issecurely hashed using *key* and any change to *ticket* breaks the hashvalidation.>>> key = 'Io5IpK9ZTsKpG1ybaLCHkOH4kvHaTEO2imHvkqLVn7I='>>> sts = SecureTicketService(key.decode('base64'))>>> ticket = sts.create_ticket('someData')>>> ticket.data'someData'>>> sts.validate_ticket(ticket)True>>> sts2 = SecureTicketService('someOtherKey')>>> sts2.validate_ticket(ticket)False**entropy**The optional second argument *entropy* to *create_ticket()*, which must bea string if supplied, cannot be obtained from a ticket; it's justconcatinated 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)False>>> sts.validate_ticket(ticket, 'someEntropy')True**session**Many use cases for secure tickets involves (or should involve) the conceptof a session to prevent various types of attacks. The optional secondargument *session* to *SecureTicketService()* is used in the same manner as*entropy*, but is supplied during *SecureTicketService* instantiationinstead of during ticket creation.>>> sts = SecureTicketService(key, 'someSessionIdentifier')**options**Encryption, serialization and compression of *ticket*'s contents isoptional. Encrypted tickets will have all its data and metadata encryptedwith the *key* supplied to *SecureTicketService*. Serialization allowscomplex 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=FalseEncrypted 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 == ZZbTrue>>> type(ZZa)<type 'long'>>>> strZZ = tickets.crypto.util.long2str(ZZa)>>> type(strZZ)<type 'str'>*DiffieHellmanClient* and *DiffieHellmanServer* implements a protocol bywhich two parties are able to perform a Diffie Hellman key exchange andto verify that the other party has successfully derived the same secretkey.The protocol follows the common Diffie Hellman scheme, but additionallyincludes generation and validation of SHA256-HMAC digests, using thenegotiated key, of some of the negotiation messages. This is in a sensesimilar 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)True>>> c.negotiated_key == s.negotiated_keyTrue>>> type(c.negotiated_key)<type 'str'>