-
Notifications
You must be signed in to change notification settings - Fork 15
pure-python implementation of the SPAKE2 Password-Authenticated Key Exchange algorithm
License
warner/python-spake2
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
= Pure-Python PAKE2 = This is an easy-to-use implementation of the PAKE2 password-authenticated key exchange algorithm[1], implemented purely in Python, released under the MIT license. This allows two parties, who share a weak password, to safely derive a strong shared secret (and therefore build an encrypted+authenticated channel). A passive attacker who eavesdrops on the connection learns no information about the password or the generated secret. An active attacker (man-in-the-middle) gets exactly one guess at the password, and unless they get it right, they learn no information about the password or the generated secret. Each execution of the protocol enables one guess. The use of a weak password is made safer by the rate-limiting of guesses: no off-line attack is possible. The protocol requires the exchange of one pair of messages, so only one round trip is necessary to establish the session key. If key-confirmation is necessary, that will require a second round trip. All messages are JSON-serializable. For the default security level (using a 1024-bit modulus, roughly equivalent to an 80-bit symmetric key), the message is about 265 bytes long. An alternative binary encoding is available, which reduces the message sizes by about 50%. == Dependencies == This package is pure-python: no C code or compiled extension modules are used. It requires the 'simplejson' module for data serialization. == Speed == To run the built-in speed tests, just run the bench_pake2.py script. PAKE2 consists of two phases, separated by a single message exchange. On my 2008 mac laptop, the default params_80 security level takes about 20ms to complete both phases. The params_112 level takes about 185ms, and params_128 takes about 422ms. The two phases take roughly equal time. This library uses only Python. A version which used C speedups for the large modular multiplication operations would probably be an order of magnitude faster. == History == The PAKE2 protocol comes from Professor Dan Boneh. The chapter that defines PAKE2 also defines PAKE2+, which changes one side (typically a server) to record a derivative of the password instead of the actual password. In PAKE2+, a server compromise does not immediately give access to the passwords: instead, the attacker must perform an offline dictionary attack against the stolen data before they can learn the passwords. Brian Warner wrote this Python version in July 2010, based upon the algorithm from Boneh's book. == Testing == To run the built-in test suite from a source directory, do: PYTHONPATH=. python pake2/test/test_pake2.py The tests take approximately 3 seconds on my laptop. == Security == This library does not protect against timing attacks. Do not allow attackers to measure how long it takes you to create or respond to a message. This library depends upon a strong source of random numbers. Do not use it on a system where os.urandom() is weak. == Usage == Alice and Bob both initialize their PAKE2 instances with the same (weak) password. They will exchange messages to (hopefully) derive a shared secret key "K". The protocol is symmetric: for each operation that Alice does, Bob will do the same. For each message that Alice sends, Bob will send a corresponding message. However, there are two roles in the PAKE2 protocol, "P" and "Q". The two sides must agree ahead of time which one will play which role (the messages they generate depend upon which side they play). For environments in which one piece of code always plays the same role, there are two separate classes PAKE2_P and PAKE2_Q to make this easier to set up. Each instance of a PAKE2 protocol uses a set of shared parameters. These include a group, a generator, and a pair of arbitrary group elements. The python-pake2 implementation comes with several pre-generated parameter sets, with various security levels. You start by creating a PAKE2 instance, using the password and the side indicator ("P" or "Q"). You can override an option to increase the security level (at the expense of processing speed). Then you ask the instance for the outbound message by calling msg_out=p.one(), and send it to your partner. Once you receive the corresponding inbound message, you pass it into the instance and extract the (shared) key bytestring with key=p.two(msg_in). For example, the client-side might do: from pake2 import PAKE2_P p = PAKE2_P("our password") msg_out = p.one() send(msg_out) msg_in = receive() key = p.two(msg_in) while the server-side might do: from pake2 import PAKE2_Q p = PAKE2_Q("our password") msg_out = p.one() send(msg_out) msg_in = receive() key = p.two(msg_in) If both sides used the same password, and there is no man-in-the-middle, then both sides will obtain the same key. If not, the two sides will get different keys, so using "key" for data encryption will result in garbled data. To safely test for identical keys before use, you can perform a second message exchange at the end of the protocol, before actually using the key (be careful to not simply send the shared key over the encrypted wire: this would allow a MitM to learn the key that they could otherwise not guess). This key-confirmation step is asymmetric: one side will always learn about the success or failure of the protocol before the other. # Alice does this: ... key = p.two(msg_in) hhkey = sha256(sha256(key).digest()).digest() send(hhkey) # and Bob does this: ... key = p.two(msg_in) their_hhkey = receive() my_hhkey = sha256(sha256(key).digest()).digest() assery my_hhkey == their_hhkey hkey = sha256(key).digest() send(hkey) # and then Alice does this: their_hkey = receive() my_hkey = sha256(key).digest() assert my_hkey == their_hkey The shared "key" can be used as an AES data-encryption key, and/or an HMAC key to provide data integrity. It can also be used to derive other session keys as necessary. --footnotes--
About
pure-python implementation of the SPAKE2 Password-Authenticated Key Exchange algorithm
Resources
License
Stars
Watchers
Forks
Packages 0
No packages published