Simple Elliptic Curve Cryptography in Python compatible with seccure
Instead of RSA, you can use an Elliptic Curve algorithm for public/private key cryptography. The main advantage is that keys are a lot smaller. With RSA you need keyservers to distribute public keys. With Elliptic Curves, you can just write: my public key is *jMVCU^[QC&q*v_8C1ZAFBAgD.
There are two drawbacks: first, Elliptic Curve cryptography is even harder to understand than plain RSA and secondly, there are only a few implementation of Elliptic Curve cryptography. In fact: I did not find any maintained Elliptic Curve package for Python.
Thus I wrote a Python package compatible with the excellent commandline utility seccure written by Poettering. Here are some examples of how to use the original commandline seccure and how to do the same thing in Python.
For a private key, you just pick a (long!) password. You can derive the public key with seccure as follows:
$ seccure-key
Assuming curve p160.
Enter private key: my private key
The public key is: 8W;>i^H0qi|J&$coR5MFpR*Vn
In Python
>>> import seccure
>>> str(seccure.passphrase_to_pubkey(b'my private key'))
'8W;>i^H0qi|J&$coR5MFpR*Vn'
Now, to encrypt a message for the public key:
$ seccure-encrypt -o private.msg '8W;>i^H0qi|J&$coR5MFpR*Vn'
Assuming MAC length of 80 bits.
Go ahead and type your message ...
This is a very secret message!
^D
In Python:
>>> ciphertext = seccure.encrypt(b'This is a very secret message\n', b'8W;>i^H0qi|J&$coR5MFpR*Vn')…
>>> ciphertext
'\x00\x146\x17\xe9\xc1\x1a\x7fkX\xec\xa0n,h
To decrypt the encrypted message:
$ seccure-decrypt -i private.msg
Assuming MAC length of 80 bits.
Assuming curve p160.
Enter private key: my private key
This is a very secret message!
Integrity check successful, message unforged!
In Python:
>>> seccure.decrypt(ciphertext, b'my private key')
'This is a very secret message\n'
To create a signature
$ seccure-sign
Assuming curve p160.
Enter private key: my private key
Go ahead and type your message ...
This message will be signed
^D
Signature: $HPI?t(I*1vAYsl$|%21WXND=6Br*[>k(OR9B!GOwHqL0s+3Uq
In Python:
>>> seccure.sign(b'This message will be signed\n', b'my private key')
'$HPI?t(I*1vAYsl$|%21WXND=6Br*[>k(OR9B!GOwHqL0s+3Uq'
And to verify a signature:
$ seccure-verify '8W;>i^H0qi|J&$coR5MFpR*Vn' '$HPI?t(I*1vAYsl$|%21WXND=6Br*[>k(OR9B!GOwHqL0s+3Uq'
Go ahead and type your message ...
This message will be signed
^D
Signature successfully verified!
In Python:
>>> seccure.verify(b'This message will be signed\n', b'$HPI?t(I*1vAYsl$|%21WXND=6Br*[>k(OR9B!GOwHqL0s+3Uq', b'8W;>i^H0qi|J&$coR5MFpR*Vn')
True
You can find the Python library on Github.
Update: added support for Python 2.6, 2.7, 3.2 and 3.3.
8 comments
Preserved from the WordPress version of this blog. Commenting is closed.
Thomas Sileo
Awesome, I love what you done, how does py-secure deal with files that doesn’t fit in RAM ?
Thanks!
Bas Westerbaan
You can just use
pubkey.encrypt_to(file_out). This will return a file-like object to which you can write. In this way, the whole input and output don’t have to be in RAM. Actually, thepubkey.encryptfunction is written usingpubkey.encrypt_towith aStringIO, see https://github.com/bwesterb/py-seccure/blob/fc427fe1b0868a292586e058c13f1ad49577b664/src/__init__.py#L437Thomas Sileo
I saw it, and I written two helpers (encrypt_file and decrypt_file), I just sent you a pull request, I’m planning to use it in bakthat (http://docs.bakthat.io), currently it only support symmetric encryption and I’ll add elliptic curve cryptography support thanks to py-seccure.
Bas Westerbaan
I pulled it! Thanks for your contribution.
Jesús Cea
Please, publish this in PYPI! :).
Bas Westerbaan
It already is: https://pypi.python.org/pypi/seccure
pip install seccureJesús Cea
Oh, GREAT!. If only it would work on Python 3… };-).
Do you need help on this regard?. I could collaborate.
Bas Westerbaan
I sent you an e-mail!