Git Product home page Git Product logo

humancrypto's Introduction

Cryptography for humans

Build Status

tl;dr

DON'T USE THIS IN PRODUCTION! It's just an idea right now.

Use cryptographic best practices:

  • If it's 2016, use the y2016 module.
  • If it's 44 B.C., use the y44bc module.

Use it for:

Installation

Stable:

pip install humancrypto

Latest:

pip install git+https://github.com/iffy/humancrypto.git

Motivation

Do you want to do something cryptographic, but have a hard time keeping up with changing best practices? This cryptography library makes it easy to know if you're following current best practices.

For instance, in 44 B.C. it was okay to use things like ROT13 to store your passwords. So the y44bc module is provided for that level of password-storage security:

>>> from humancrypto import y44bc
>>> stored_44bc = y44bc.store_password(b'password')

Verify that a given password matches the stored version:

>>> y44bc.verify_password(stored_44bc, b'password')
True
>>> y44bc.verify_password(stored_44bc, b'WRONG')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "humancrypto/pwutil.py", line 73, in verify_password
    raise VerifyMismatchError()
humancrypto.error.VerifyMismatchError

But it's not 44 B.C., it's 2016. We should store passwords using 2016 methods:

>>> from humancrypto import y2016
>>> stored_2016 = y2016.store_password(b'password')

And when we encounter 44 B.C. passwords in 2016, we should upgrade them:

>>> from humancrypto.error import PasswordMatchesWrongYear
>>> password = b'password'
>>> try:
...     y2016.verify_password(stored_44bc, password)
... except PasswordMatchesWrongYear:
...     converted_to_2016 = y2016.store_password(password)
...

Using this library, it's obvious from looking at your code how old your crypto is.

Password Hashing

Library

Store a password using 2016 best practices:

>>> from humancrypto.y2016 import store_password
>>> stored = store_password(b'this is my password')

Check a password hash (for any year):

>>> from humancrypto.y2016 import verify_password
>>> verify_password(stored, b'WRONG PASSWORD')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "humancrypto/pwutil.py", line 73, in verify_password
    raise VerifyMismatchError()
humancrypto.error.VerifyMismatchError
>>> verify_password(stored, b'this is my password')
True

Typical usage for verifying might look like this:

from humancrypto import y2016
from humancrypto.error import PasswordMatchesWrongYear
from humancrypto.error import VerifyMismatchError

def verify_password(stored, password):
    try:
        y2016.verify_password(stored, password)
    except PasswordMatchesWrongYear:
        stored = y2016.store_password(password)
        # ... store the password for the user
    except VerifyMismatchError(Error):
        raise Exception('Bad password')

Command line

Store a password using 2016 best practices:

$ echo 'mypassword' | humancrypto y2016 pw store > stored.out

Verify a password (for any year):

$ echo 'mypassword' | humancrypto y2016 pw verify "$(cat stored.out)"
ok

See humancrypto y2016 pw verify --help for additional information and possible return codes.

Random tokens

Library

Generate a 2016-secure random token:

>>> from humancrypto import y2016
>>> token = y2016.random_bytes()
>>> web_token = y2016.random_urlsafe_token()
>>> hex_token = y2016.random_hex_token()

Command line

Generate a 2016-secure random token:

$ humancrypto y2016 token > token.txt
$ humancrypto y2016 token --urlsafe > urlsafe_token.txt 
$ humancrypto y2016 token --hex > hex_token.txt

RSA

The RSA part of the code is essentially pyca's cryptography + sane defaults. By default, 2048-bit RSA keys are used.

Command line

Create a private key:

humancrypto rsa create-private ca.key

Extract a public key:

humancrypto rsa extract-public ca.key ca.pub

Create a self-signed CA certificate:

humancrypto rsa self-signed-cert ca.key ca.crt --common-name jim

Create a signed certificate for a server key:

humancrypto rsa create-private server.key
humancrypto rsa create-csr server.key server.csr --common-name bob --server
humancrypto rsa sign-csr ca.key ca.crt server.csr server.crt

(And use --client for a client key).

Library

Create a private key:

>>> from humancrypto import PrivateKey
>>> key = PrivateKey.create()
>>> key.save('private.key')

Load a private key from a file (these are all equivalent). There are equivalent methods for CSRs, Certs, Public Keys:

>>> key = PrivateKey.load(filename='private.key')
>>> key = PrivateKey.load(open('private.key', 'rb').read())
>>> key = PrivateKey.load(key.dump())

Create a self-signed Certificate:

>>> root_cert = key.self_signed_cert({'common_name': u'bob'})
>>> root_cert.subject.attribs['common_name']
u'bob'

Create a server-friendly Certificate Signing Request (CSR):

>>> from humancrypto import CSR
>>> csr = CSR.create(key, {'common_name': u'bob'}, server=True)
>>> csr = key.signing_request({'common_name': u'bob'}, server=True) # equivalent
>>> csr.attribs['common_name']
u'bob'
>>> csr.save('ca.csr')

Use client=True instead of server=True if you want a client.

Sign a CSR:

>>> cert = key.sign_csr(csr, root_cert)
>>> cert.subject.attribs['common_name']
u'bob'
>>> cert.save('ca.cert')

humancrypto's People

Contributors

iffy avatar

Stargazers

 avatar Sam Beveridge avatar

Watchers

 avatar James Cloos avatar  avatar

humancrypto's Issues

Self-signed ca certs are missing parts

Here's a good one from openssl x509 -in ca.crt -text -noout:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            e1:33:a8:d8:9b:c8:67:df
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=Root CA
        Validity
            Not Before: Jun  3 00:12:21 2016 GMT
            Not After : Jun  3 00:12:21 2017 GMT
        Subject: CN=Root CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:c3:fd:45:7d:54:c6:ce:96:b5:b6:23:d3:a6:96:
                    e3:61:6f:60:2b:de:4d:71:6b:a5:de:16:38:93:43:
                    f7:8e:0f:0d:cb:0b:8a:03:0e:e5:4e:3b:51:68:c5:
                    46:a3:3f:a7:a9:bc:3f:da:2f:5c:6f:83:e3:93:2e:
                    85:31:1b:cd:ab:60:07:b1:48:73:cf:9c:69:ec:34:
                    26:47:f8:ff:b9:1d:ab:7b:13:aa:26:12:e2:20:c2:
                    41:27:2e:a4:80:29:e5:d3:cb:ed:a6:7d:36:28:04:
                    d7:7c:19:4f:54:fe:dc:af:9f:fb:14:ae:0b:17:62:
                    77:44:44:e6:bd:69:ac:68:be:1f:7e:f2:8a:8f:94:
                    1b:d3:6e:8a:1c:56:8d:9c:95:f1:a5:4e:3a:03:aa:
                    bf:8a:81:e1:79:c7:d7:91:1d:44:b0:1a:c3:be:ba:
                    63:cf:a2:44:db:64:5c:6b:86:f1:6e:9b:2b:bc:d1:
                    e6:17:bb:80:99:2f:8d:e8:ae:08:87:15:00:f9:40:
                    5b:1c:2a:f8:05:04:19:9d:ff:43:33:32:c2:44:3f:
                    f8:3f:69:93:3e:41:32:a6:2b:68:a4:73:2b:2a:0e:
                    92:dd:f4:1b:72:8f:00:ea:53:f3:28:32:d8:e3:fe:
                    cb:3e:bc:76:5e:5e:d5:fe:3e:82:c6:9a:3b:f0:a9:
                    91:17
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                CB:ED:3B:20:F7:6D:DE:EF:19:79:24:56:42:7A:68:46:E4:92:B7:D5
            X509v3 Authority Key Identifier: 
                keyid:CB:ED:3B:20:F7:6D:DE:EF:19:79:24:56:42:7A:68:46:E4:92:B7:D5
                DirName:/CN=Root CA
                serial:E1:33:A8:D8:9B:C8:67:DF

            X509v3 Basic Constraints: 
                CA:TRUE
            X509v3 Key Usage: 
                Certificate Sign, CRL Sign
    Signature Algorithm: sha256WithRSAEncryption
        16:df:d8:07:78:62:2a:25:2b:d5:0a:bf:e0:fa:ad:67:6c:84:
        f6:a1:c8:0c:b2:bc:4a:bf:45:ae:e6:9f:97:1e:35:67:93:a4:
        9a:e5:e4:0b:4d:29:ba:05:44:b0:5b:1b:eb:da:68:2b:18:d4:
        2c:c7:1a:94:7e:17:b4:fa:bc:bb:02:23:b7:dd:b0:e0:35:32:
        0b:c6:23:1c:47:5c:c6:23:6c:02:27:3c:26:54:50:92:4b:ae:
        5e:e1:04:65:87:d9:a5:76:d9:d5:4a:3c:d2:33:11:76:82:24:
        6b:a5:11:08:0b:90:79:56:35:75:23:46:0c:78:b4:5d:0d:dc:
        82:da:c3:d6:6c:af:6e:c2:f1:aa:77:73:f8:8d:de:30:f7:69:
        db:31:65:71:1c:39:5c:ad:d2:36:ac:41:45:79:bd:65:50:bf:
        d6:f1:d3:4c:6b:79:27:b6:53:93:16:1a:8e:28:71:09:42:79:
        e0:92:4f:f5:f4:88:c9:3a:b7:0f:43:33:bb:ee:0f:20:be:ae:
        d9:2f:ed:49:c9:12:5c:30:32:53:8e:c7:9c:bc:b8:48:19:83:
        64:fb:6e:1b:51:59:6b:1c:a2:4e:1c:f7:72:6c:32:0d:4f:1e:
        e5:19:a7:11:41:c9:3c:ed:91:8a:16:f0:31:9a:e4:0a:ed:1f:
        ba:3a:71:61

And here's the currently-generated ca.crt from humancrypto:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            fe:7b:2b:0f:fb:c4:4b:76:b9:3b:c0:c6:41:d0:4c:17
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=jim
        Validity
            Not Before: Jun 20 15:48:55 2016 GMT
            Not After : Jun 21 15:48:55 2018 GMT
        Subject: CN=jim
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:d6:14:2f:e3:d8:8d:3b:ea:ea:65:b1:f6:3d:70:
                    e3:c4:1f:7e:0b:9a:52:93:53:2c:5e:fd:d5:7f:22:
                    a3:5a:73:0e:21:25:6e:8d:39:cc:58:37:7d:19:df:
                    2f:d7:d3:96:66:15:3e:17:92:3f:bd:9a:31:4e:d8:
                    42:89:da:cf:ca:88:5b:32:77:8b:52:8c:72:db:c8:
                    32:82:1e:b5:cc:e2:7c:e5:ac:a9:82:80:5d:c9:f6:
                    67:ac:ac:6b:79:10:ae:e4:31:c9:87:a8:9f:33:c9:
                    81:04:37:88:35:c4:62:fe:be:b3:df:7d:47:86:c9:
                    f2:3f:b9:66:7d:f5:31:b3:e2:d1:a9:49:ba:33:22:
                    c9:56:a4:07:97:b0:56:20:ec:b3:07:98:19:88:92:
                    91:66:79:70:2c:a6:8b:7b:a9:2b:2e:4e:9f:35:94:
                    64:c2:55:7b:1b:f7:4c:25:02:cd:66:ac:32:ea:62:
                    e3:ed:14:43:fb:18:b8:6f:55:7b:b7:5d:0c:c6:2a:
                    01:85:16:9b:d4:e2:27:b3:df:23:26:1a:35:c9:c9:
                    80:ed:cf:c0:7d:be:47:7f:8c:68:ea:d2:54:ba:0b:
                    05:d7:0b:a6:de:b2:ea:06:15:dd:53:1e:62:df:ad:
                    87:1e:1b:5e:09:8b:ae:3f:c7:33:62:39:73:9c:bd:
                    32:39
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0
    Signature Algorithm: sha256WithRSAEncryption
        21:4b:ec:67:19:18:a3:9f:86:43:2d:08:5e:7d:ab:e2:7c:54:
        0e:f2:5d:cb:ae:0b:8d:2d:ed:ab:d7:48:3b:dd:8b:6d:f5:01:
        c0:aa:0a:86:c5:5f:d4:b4:77:9b:b2:f0:1e:ca:df:ec:e5:7a:
        a7:42:6e:90:d9:07:2f:3b:40:51:6d:ef:d0:cb:05:c3:42:c5:
        8a:37:34:e7:fc:18:59:f0:71:d0:5d:b2:7f:3a:a2:9f:1b:d4:
        24:38:7e:f2:e3:e9:05:ee:e7:22:66:74:32:cc:b5:b8:46:06:
        39:94:fe:ef:86:6c:6e:3c:95:38:aa:02:f7:97:6e:3c:62:6a:
        89:c0:63:d6:f8:7f:5d:69:71:dd:85:7f:b8:4a:8d:3c:72:29:
        82:45:f9:2b:32:4f:5e:9b:5e:30:fc:e2:f6:7a:24:c4:ee:27:
        70:44:10:ae:be:85:c6:3a:1a:c3:98:12:4a:4d:b5:59:6d:0a:
        b5:fd:4a:00:90:4e:75:42:67:24:05:66:22:46:cd:1f:92:f3:
        16:63:f8:ce:a4:f0:dc:0d:62:83:36:9f:c6:18:c8:82:a2:79:
        f0:cf:98:94:59:b6:e4:d4:83:e8:bf:e5:8e:17:73:da:00:d0:
        d8:a2:f5:1f:e2:9a:14:43:48:63:89:f5:f1:93:d0:c7:85:e9:
        84:43:e6:c0

error 20 at 0 depth lookup:unable to get local issuer certificate

Instead of producing OK the following produces error 20 at 0 depth lookup:unable to get local issuer.

#!/bin/bash
set -x

cat <<EOF > ca.crt
-----BEGIN CERTIFICATE-----
MIIC7zCCAligAwIBAgIJANuC2ji3uLw/MA0GCSqGSIb3DQEBBQUAMFkxCzAJBgNV
BAYTAkFEMQswCQYDVQQIEwJLWTEMMAoGA1UEBxMDZm9vMQswCQYDVQQKEwJiYTEO
MAwGA1UEAxMFYmEgQ0ExEjAQBgkqhkiG9w0BCQEWA2JhcjAeFw0xNjExMTUyMTQ4
NTZaFw0yNjExMTMyMTQ4NTZaMFkxCzAJBgNVBAYTAkFEMQswCQYDVQQIEwJLWTEM
MAoGA1UEBxMDZm9vMQswCQYDVQQKEwJiYTEOMAwGA1UEAxMFYmEgQ0ExEjAQBgkq
hkiG9w0BCQEWA2JhcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2UXCNWyI
YN0+HxHW8q9/kouXTByk/Vg3feY+XjukPkRZHGi6hJkEqBAV21hfVpijZOR6YJU7
fbDzINcTD7i9oZCbufvjyITjvo4XQkV2BXHNp0cxAgQyjSXrFrJyFYfFQzgb7VgQ
fe0Y7L/+JKzS3PKyhKPXMabo9ETuN+eO8hsCAwEAAaOBvjCBuzAdBgNVHQ4EFgQU
SHBM0vcdnjSQiNswfDxfVu6m7hAwgYsGA1UdIwSBgzCBgIAUSHBM0vcdnjSQiNsw
fDxfVu6m7hChXaRbMFkxCzAJBgNVBAYTAkFEMQswCQYDVQQIEwJLWTEMMAoGA1UE
BxMDZm9vMQswCQYDVQQKEwJiYTEOMAwGA1UEAxMFYmEgQ0ExEjAQBgkqhkiG9w0B
CQEWA2JhcoIJANuC2ji3uLw/MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
gYEAi0dRSS349L4x9XkJby1FXwO7hPp+J4X9eivAwmMQXRXDb1ZwanEU7yknrDqn
RiGZoGkyX0ksbkSMI7KoHq2C3g3qpdBt4fAdi8mV6TbTqMoq4gzWatsHO4uUu9up
aNpxL364SklFf8tPzsXCQlv/DghbpaVgwGJdX7xWdvfhdjo=
-----END CERTIFICATE-----
EOF

cat <<EOF > ca.key
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANlFwjVsiGDdPh8R
1vKvf5KLl0wcpP1YN33mPl47pD5EWRxouoSZBKgQFdtYX1aYo2TkemCVO32w8yDX
Ew+4vaGQm7n748iE476OF0JFdgVxzadHMQIEMo0l6xaychWHxUM4G+1YEH3tGOy/
/iSs0tzysoSj1zGm6PRE7jfnjvIbAgMBAAECgYAgFPHZS55TlzeOBOdVTF6s99mu
Tmh6VCVVfMLmzS2yWAtEa55m5+VNH5rqmYDyW3V891OuoTp4k8FCrx9Maf3t8KqL
Jjt2rATv869pdoDoYGjLFtEMd0A3kvh/y7zws8HLazZLHdLGrvuj+VTYxxHn2/iS
h8VnJD+gzP/aszJWmQJBAPNZElYYW9qRv06eR9eO6bELneMYaG1qcgL9+NNRK5U4
9WdkY5tYjnpq7Gt+P6HWBzkQkVskF0auxaOPosmc+0UCQQDkkaBaJSJXhzKh7TBY
hIrM7CpdFP6jHirEHId/gKrcjR6RQqCC6xW75amjtYPZ8wxvrlFY1q/GB7tuUkoC
6F3fAkAMKv8EuREWu8TyHG4BNE8xICCT82t9VR5AUgy4HE3ulzuGIPnuEZ6GNoR9
14E9CWOxEcgC46oaSbDuPcdpB2V1AkEAm/MMUFUj0EqLblXx9YNBXL4JzYakklDj
5vh8Lq9wZJjYcU3fTFPveUsianNPaeZd5tkt4YphVaEy7fuxSbiXSwJBAPKMiZ6W
vZ0SUv795gk01Y2KL7yDyOqftouEz5Dsw0nqwvwmpb6/YOjZWt5a/DD71/qHRpcd
IXeYM2YnQrURypc=
-----END PRIVATE KEY-----
EOF



humancrypto rsa create-private 1.key
humancrypto rsa create-csr 1.key 1.csr
humancrypto rsa sign-csr ca.key ca.crt 1.csr 1.crt
openssl verify -verbose -CAfile ca.crt 1.crt

Check the modulus of ca.crt and ca.key to prove they belong together:

openssl x509 -noout -modulus -in ./ca.crt
openssl rsa -noout -modulus -in ./ca.key

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.