Giter Site home page Giter Site logo

vguzmanp / simple-crypt Goto Github PK

View Code? Open in Web Editor NEW

This project forked from andrewcooke/simple-crypt

0.0 1.0 0.0 165 KB

Simple, secure encryption and decryption for Python 2.7 and 3

Home Page: http://pypi.python.org/pypi/simple-crypt

Shell 2.40% Python 97.60%

simple-crypt's Introduction

simple-crypt

Simple, secure encryption and decryption for Python 2.7 and 3.

Now on pypi: pip install simple-crypt (note that the pypi name includes a hyphen).

This provides two functions, which encrypt and decrypt data, delegating all the hard work to the pycrypto library (which must also be installed).

Examples

The two calls:

from simplecrypt import encrypt, decrypt

ciphertext = encrypt(password, 'my secret')
plaintext = decrypt(password, ciphertext)

A simple Python 3 program:

from binascii import hexlify
from getpass import getpass
from sys import stdin

from simplecrypt import encrypt, decrypt

# read the password from the user (without displaying it)
password = getpass("password: ")

# read the (single line) plaintext we will encrypt
print("message: ")
message = stdin.readline()

# encrypt the plaintext.  we explicitly convert to bytes first (optional)
ciphertext = encrypt(password, message.encode('utf8'))

# the ciphertext plaintext is bytes, so we display it as a hex string
print("ciphertext: %s" % hexlify(ciphertext))

# now decrypt the plaintext (using the same salt and password)
plaintext = decrypt(password, ciphertext)

# the decrypted plaintext is bytes, but we can convert it back to a string
print("plaintext: %s" % plaintext)
print("plaintext as string: %s" % plaintext.decode('utf8'))

Which, when run, produces something like the following (the actual encrypted message will be different each time, as a random salt is used for each message):

password: ******

message:
hello world
ciphertext: b'73630001b1c39575390d5720f2a80e7a06fbddbf2c844d6b8eaf845d4a9e140d46a54c6729e74b0ddeb1cb82dee81691123faf8f41900c5a6c5b755ed8ae195ff2410290bcb8dc2ee3a2126c594b711d'
plaintext: b'hello world\n'
plaintext as string: hello world

Also, it's perhaps worth noting that the overhead (the extra length of the encrypted data, compared to the message) is constant. It looks a lot here, because the message is very small, but for most practical uses should not be an issue.

Alternatives

This code is intended to be "easy to use" and "hard to use wrong". An alternative for more experienced users (who might, for example, want to use more rounds in the PBKDF, or an explicit key) is python-aead.

As far as I can tell, python-aead uses very similar algorithms to those found here.

Algorithms

The algorithms used follow the recommendations at http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html, as far as I can tell:

  • The password is expanded to two 256 bit keys using PBKDF2 with a 256 bit random salt (increased from 128 bits in release 3.0.0), SHA256, and 100,000 iterations (increased from 10,000 in release 4.0.0).

  • AES256 CTR mode is used to encrypt the data with one key. The first 64 bits of the salt are used as a message nonce (of half the block size); the incremental part of the counter uses the remaining 64 bits (see section B.2 of http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf).

  • An encrypted messages starts with a 4 byte header ("sc" in ASCII followed by either two zero bytes (pre-3.0), or a zero and a one).

  • An SHA256 HMAC (of header, salt, and encrypted message) is calculated using the other key.

  • The final message consists of the header, salt, encrypted data, and HMAC, concatenated in that order.

  • On decryption, the header is checked and the HMAC validated before decryption.

The entire implementation is here.

Discussion and criticism of the design can be found on HN (also), codereview.stackexchange and crypto.stackexchange. Grateful thanks to all commentators (particularly marshray); mistakes remain mine.

Please note that the general design, based on the cryptographic right answers, is intended to give 128 bits of security - any attack would require around 2^128 guesses. This comes from birthday collisions on the 256 bit HMAC and random numbers (since release 3.0). AES256 is used because it provides additional security if, for example, some key bits are revealed through timing attacks (see link above or chapter 7 of Practical Cryptography).

Latest News

Release 4.1 obscures the output of the random number generator. This should not be necessary, but guards against a possible attack if the random number generator is compromised in some way. Functionality and interoperability are otherwise unchanged.

Release 4.0 increases the number of iterations used in the PBKDF (this will make encyption and decryption noticeably slower) and adds a reference to python-aead.

Release 3.0 increases the size of the salt used from 128 to 256 bits.

The header changes with each major version release (after 2.0), so data encrypted by previous releases can be detected and decrypted correctly. However, data encrypted by later major releases (after 2.0) cannot be decrypted by earlier releases (instead, an error with a helpful message is generated).

Release 2.0 was fully compatible with 1.0 on Python 3 (same API and identical results). However, thanks to d10n it also supported Python 2.7 (tested with Python 2.7.5, 3.0.1 and 3.3.2).

I (Andrew Cooke) am not sure Python 2.7 support is such a good idea. You should really use something like keyczar. But there seems to be a demand for this, so better the devil you know...

Warnings

  1. The whole idea of encrypting with a password is not so smart these days. If you think you need to do this, try reading about Google's keyczar which instead uses a keystore (unfortunately, at the time of writing, keyczar does not support Python 3, as far as I can tell, but that should change soon).

  2. When you call these routines the password is stored in memory as a Python string. This means that malicious code running on the same machine might be able to read the password (or even that the password could be written to swap space on disk). One way to reduce the risk is to have the crypto part of your code run as a separate process that exists for a limited time.

  3. All encrypted messages start with a 4 byte header (ASCII "sc", followed by the version number). So an adversary is able to recognise that the data are encrypted (and not simply random). You can avoid this by discarding the first 4 bytes of the encrypted data, but you must of course replace them before decrypting, and the code will not inter-operate between versions.

(c) 2012-2015 Andrew Cooke, [email protected]; 2013 d10n, [email protected]. Released into the public domain for any use, but with absolutely no warranty.

simple-crypt's People

Contributors

andrewcooke avatar d10n avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.