0% found this document useful (0 votes)
107 views

Python Security Cryptography

This document provides an overview of cryptography and security topics in Python, including common Python cryptography libraries, hashing functions, symmetric and asymmetric encryption algorithms, and digital signatures. It discusses the PyCrypto library and how to use it for hashing, AES encryption, RSA key generation and encryption/decryption, and signing/verifying data with RSA.

Uploaded by

Emanuel Zamora
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
107 views

Python Security Cryptography

This document provides an overview of cryptography and security topics in Python, including common Python cryptography libraries, hashing functions, symmetric and asymmetric encryption algorithms, and digital signatures. It discusses the PyCrypto library and how to use it for hashing, AES encryption, RSA key generation and encryption/decryption, and signing/verifying data with RSA.

Uploaded by

Emanuel Zamora
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 61

Python Cryptography

& Security
José Manuel Ortega | @jmortegac
https://speakerdeck.com/jmortega
Security Conferences
INDEX

1 Introduction to cryptography

2 PyCrypto and other libraries


3 Django Security

4 OWASP & Best Practices


5 Steganography
Introduction to cryptography
Key terms
Caesar Chiper
Hash functions(MD5,SHA)
Symetric Encryption(AES)
Asimetric Encription(RSA)
PBKDF2-Key derivation function
 Key: The piece of information that
Key terms allows you to either encrypt or
decrypt your data.
 Plaintext: The information that you
want to keep hidden, in its
unencrypted form. The plaintext can
be any data at all: a picture, a
spreadsheet, or even a whole hard
disk
 Ciphertext: The information in
encrypted form
 Cipher: The algorithm that converts
plaintext to ciphertext and vice-versa
Key terms Salt – randomizes the hash of the key;
advanced prevents rainbow table attacks against
the key
IV (initialization vector) – randomizes
the encrypted message; prevents
rainbow table attacks against the
message
Derived Key – lengthens and
strengthens the key via hashing; used
instead of the original key; slows down
brute-force attacks against the key
Caesar Chiper

>>Ymnx%nx%r~%xjhwjy%rjxxflj3
Hash functions
Calculate the checksum of some data
File integrity checking
Generate passwords
Digital signatures and authentication
MD5
SHA-2(256 and 512 bits)
SHA-3
Hash
functions
https://docs.python.org/2/library/hashlib.html

Hashlib functions
One-way cryptographic hashing

>>03187564433616a654efef944871f1e4
>>bd576c4231b95dd439abd486be45e23d47a2cbb74b5348b3b113cef47463e15a
>>d47b290aa260af8871294e1ad6b473bd48b587593f8dea7b1b5d9271df12ee081
85a13217ae88e95d9bd425f3ada0593f1671004a2b32380039d3c88f685614c
>>8fadab23df7c580915deba5c6f0eb75bd32181f55c547a2b3999db055398095c33f
10b75c823a288e86636797f71b458
MD5 hash function
Checking file integrity

>>d41d8cd98f00b204e9800998ecf8427e
Hash passwords in DB
Websites store hash of a password
hashlib.sha256(‘password').hexdigest()
>>'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8'
Hash passwords in DB
Hash identifier
https://code.google.com/p/hash-identifier

For checking the type of Hash


Symetric encryption
AES
Shared key for encrypt and decrypt
key size (bytes in
cipher
ASCII)
AES-128 128 bits (16 bytes)
AES-192 192 bits (24 bytes)
AES-256 256 bits (32 bytes)
Asymetric encryption
RSA
2 keys(public key and secret key)
Public key(Pk) for encrypt
Secret key(Sk) for decrypt
Public key is derived from secret key
Asymetric encryption
Encryption vs Signing
EncryptionWhen encrypting, you use their public
key to write message and they use their private
key to read it.
SigningWhen signing, you use your private
key to write message's signature, and they use your
public key to check if it's really yours.
Digital signature
Signing a message
Only the owner of Pk/Sk pair should be able to
sign the message
PyCrypto
https://pypi.python.org/pypi/pycrypto

Supports Hash operations


Block cipher AES,RSA
Sign/verify documents
>> pip install pycrypto
PyCrypto Hash functions
from Crypto.Hash import SHA256
SHA256.new(‘password').hexdigest()
>>'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8'

from Crypto.Hash import SHA512


SHA512.new(‘password').hexdigest()
>>'b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb98
0b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86'
PyCrypto AES

>>>
d1a2ea7f9661fae8b46b3904b0193ab81516653f73216dfeb5f51afde3d405b2
a secret message
Generating key from password
PyCrypto PBKDF
import Crypto.Random
from Crypto.Protocol.KDF import PBKDF2

password = 'europython' A salt is a random sequence added to the password string


iterations = 5000 before using the hash function. The salt is used in order to
key = '' prevent dictionary attacks and rainbow tables attacks.
salt = Crypto.Random.new().read(32)

key = PBKDF2(password, salt, dkLen=32, count=iterations)


print 'Random salt (in hex):'
print salt.encode('hex')
print 'PBKDF2-derived key (in hex) of password after %d iterations: ' % iterations
print key.encode('hex')
Random salt (in hex):
724138b9d987a04bf05d285db678824f9b7e2b1232229711c2e0e2e556a0c19a
PBKDF2-derived key (in hex) of password after 5000 iterations:
d725de7de88e27d16c9c4f224d4c87159735708419d1c949074962b48ce26900
Generate an RSA secret and public key pair

PyCrypto RSA
from Crypto.PublicKey import RSA

def generate_RSA(bits=1024):
#Generate an RSA keypair with an exponent of 65537 in PEM format
#param: bits The key length in bits
#Return secret key and public key
new_key = RSA.generate(bits, e=65537)
public_key = new_key.publickey().exportKey("PEM")
secret_key = new_key.exportKey("PEM")
return secret_key, public_key
Generate an RSA secret and public key pair

PyCrypto RSA
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYS9ITbjKu5i9i36FgzKg/HO3o
6CKGJ1c5E57qVlmYF6L1BcgH+eE+XiwJ6fWyShaVnZDuvUapWgQeOGZ60QBJ/vpu
DdwqsuGoTeJNqaRT9ButJa+o+0tchRKBcM6zKUXYWc7kdAlxEpO2OXZEqxD7bd1O
oxv7mEjqBpVXgNEVrwIDAQAB
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCYS9ITbjKu5i9i36FgzKg/HO3o6CKGJ1c5E57qVlmYF6L1BcgH
+eE+XiwJ6fWyShaVnZDuvUapWgQeOGZ60QBJ/vpuDdwqsuGoTeJNqaRT9ButJa+o
+0tchRKBcM6zKUXYWc7kdAlxEpO2OXZEqxD7bd1Ooxv7mEjqBpVXgNEVrwIDAQAB
AoGAc0qqzTTWP5tYciRTmeE02RqAbJoXULHFkRruaf5WsxHptk3bIVakkr9d3V91
NbRqpnby+hjlvly701jlE8LW0QIccII9oWyV6kMSTEJMth9RlXpCbQY285pwg+bF
zyEhQJmjMj1hMDJLQ8dXLCeqXZ37etYGHTT2XQ+q5TOW4YkCQQC5WDQHBhYa/Mzt
UlXemLxv1ERaxt8zmXSX0bKjIkaYMv1SF3FskiN9Rm/zXvil3HuiySBq9g6/fPbN
T1+dtiZTAkEA0lpsRUqamIbii18aBBQGs/FbrUa71ahpoU7+8wXMxNYQBfVGvlzs
J+tKxSecMO196Hl4l5I14ASEs+4wKK5vtQJARe4gmzHRr1cIntY87eKk3nCxZaq5
Vkek9Q86nlB1YEGE0K9lrTgqSb8EyEdh+3qH73CBWboC8H7ew7IZ+nBaXwJBAJEO
K8Vomcz+jvB/B0iyqqChmo+VzGecuCK1f9gEMt21o90H893H5E3u0mO8WdffnciX
I1KaT66ITx5o7SrQh1UCQGqP8B9bpzXjxMuLUJuL1DoRP4QBGHoXokdu8gKAlPzp
ZK8BKRSPRobwlNFlXWfXLAWIFwXIeqOblI20U/oNwNE=
-----END RSA PRIVATE KEY-----
PyCrypto RSA
from Crypto.PublicKey import RSA
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Cipher import PKCS1_OAEP
from base64 import b64decode
def encrypt_RSA(public_key, message):
def decrypt_RSA(secret_key, message):
key = (public_key, "r").read()
key = (secret_key, "r").read()
rsakey = RSA.importKey(key)
rsakey = RSA.importKey(key)
rsakey = PKCS1_OAEP.new(rsakey)
rsakey = PKCS1_OAEP.new(rsakey)
encrypted = rsakey.encrypt(message)
decrypted =
return encrypted.encode('base64') rsakey.decrypt(b64decode(message))
return decrypted
PyCrypto Sign/verify
from Crypto.PublicKey import RSA
from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5
from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA256
from Crypto.Hash import SHA256 from base64 import b64decode
from base64 import b64encode, b64decode
def verify_sign(public_key, signature, data): ‘
def sign_data(secret_key, data): #Verifies with a public key that the data was signed by their
key = (secret_key, "r").read() #private key
rsakey = RSA.importKey(key) pub_key = (public_key, "r").read()
signer = PKCS1_v1_5.new(rsakey) rsakey = RSA.importKey(pub_key)
signer = PKCS1_v1_5.new(rsakey)
digest = SHA256.new()
digest = SHA256.new()
digest.update(b64decode(data)) digest.update(b64decode(data))
sign = signer.sign(digest) if signer.verify(digest, b64decode(signature)):
return b64encode(sign) return True
return False
PyCrypto RSA/Sign/verify
True
True
True
public_key
<_RSAobj @0x2b56648 n(1024),e>
encrypted data
('I\xe6\xff\\
M$\x12\xbb\x95\xee\x02\xcf\x82Im\tf+\x1f\xaeU\xbdv`
^\x94\xfa\xe6_\x8b\xed\x8d\xa3\xab\xfc
\xae\x17\x07=|\x18\xca\x18j\xc5\x1d\x01\xad`\xd6W
E\xfbU\xd1\x12\x0c-
\xb6\x9c\xc4\x07\xaa\x93<\xb5zw&\x98\xa2\xdc\x8e\
x9e-
\x06gQ\xcf\xfa\xc8r/\xd5\x98|\xd5\xcdg\xb2\xda\xcd:
d\xaf\xde\xe2\xcd\xcd\xf5{p`\x07\xbb~\x1b\xa4hHJ#c\
tE6\xfa\xc3\x87\x8d\xf2O8,\xe2W',)
signature
(445755122549853282247622461459180943435051515
5918916324891286777775175591376873419505852842
3900156177220742858645089371096255086061177099
8101038368420840785203067622854793789417670298
3088451295738677105320376959152029164761636442
8930467543317371804318093617486393498897888949
152557196686676342045445446511829L,)
decrypt_data EUROPHYTON2015
True
Best practices
Avoid hashing methods like MD5 or SHA-1,use at
least SHA-2 or SHA-3
Key Stretching for strong passwords
Preventing Brute-force or dictionary attacks
for i in xrange(iterations):
m = hashlib.sha512()
m.update(key + password + salt)
key = m.digest()
https://cryptography.io
Cryptography
$ pip install cryptography

Support for Python 3


Support for modern algorithms such as AESGCM and HKDF
Improved debugability and testability
Secure API design
https://cryptography.io
Cryptography
https://cryptography.io
Cryptography
Django Security
https://www.securedjango.com

Are you vulnerable to the heartbleed bug?


Are you enforcing SSL correctly?
Did you set the proper flags for your cookies?
Did you remember to disable weak ciphers?
 How are you managing your secret keys?
 Are you sure you authorise users correctly?
Django Security
https://www.securedjango.com

We can use frameworks for building API REST


Tastypie http://django-tastypie.readthedocs.org/en/latest
django-rest-framework http://django-rest-framework.org
dj-webmachine
http://benoitc.github.com/dj-webmachine

Django-secure package
Django Security
https://www.securedjango.com

What provide these frameworks?


Cross-site scripting(XSS) Protection
Cross-site request forgery(CSRF) Protection
SQL Injection Protection
Clickjacking Protection
Supports SSL/HTTPS
Secure Password Storage with PBKDF2 algorithm and SHA256
Data Validation
Django Security
https://www.ponycheckup.com/
Django Security
https://www.ponycheckup.com/
Django Security
https://www.ponycheckup.com/
Security best practices
Always use HTTPS if you have anything non-public
Proper SSL deployment
Enable HTTPS with a proper server certificate
Enforce HTTPS on your entire domain
Configure redirects to enforce HTTPS usage
Set the secure flag on all cookies
Django only send session cookies over HTTPS
SESSION_COOKIE_SECURE = true
CSRF_COOKIE_SECURE_true
Security best practices
Keep in secrets keys and credentials
Put DEBUG=false in production in settings.py
Use ALLOWED_HOSTS variable in production for
setting a list of request allowed hosts names
Limit access to admin with IP`s filter
ALLOWED_HOSTS =[*]
ALLOWED_HOSTS =['.yourdomain.com']
Password storage
PBKDF2 + SHA256 by default
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.SHA1PasswordHasher',
'django.contrib.auth.hashers.MD5PasswordHasher',
'django.contrib.auth.hashers.CryptPasswordHasher')
https://github.com/django/django/blob/master/django/contrib/auth/hashers.py/

Password storage
class PBKDF2PasswordHasher(BasePasswordHasher):
"""
Secure password hashing using the PBKDF2 algorithm (recommended)
Configured to use PBKDF2 + HMAC + SHA256.
The result is a 64 byte binary string. Iterations may be changed
safely but you must rename the algorithm if you change SHA256.
"""
algorithm = "pbkdf2_sha256"
iterations = 24000
digest = hashlib.sha256

def encode(self, password, salt, iterations=None):


assert password is not None
assert salt and '$' not in salt
if not iterations:
iterations = self.iterations
hash = pbkdf2(password, salt, iterations, digest=self.digest)
hash = base64.b64encode(hash).decode('ascii').strip()
return "%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash)
OWASP
OWASP
SQL injection

Cross site Scripting(XSS)


SQL injection
Never trust user-submitted data
Django generates properly-escaped parameters SQL
Using cursor method and bind parameter is the best option for
avoid SQL INJECT
from django.db import connection

def select_user(request):
user = request.GET['username']
sql = "SELECT * FROM users WHERE username = %s"
cursor = connection.cursor()
cursor.execute(sql, [user])
SQL injection
Django ORM –QuerySets -Models
Django automatically gives you a database-abstraction API that lets
you create, retrieve, update and delete objects
Write python classes and it will convert to SQL securely
from django.db import models

class Blog(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()

>>b = Blog(name=‘My Bblog', description=‘django security')


>>> b.save()
SQL injection
SQLMAP
Cross site Scripting
Allows an attacker obtain session information
Used with in phising sites
Django’s render template system automatically escapes all variable
values in HTML
from django.shortcuts import render

def render_page(request):
user = request.GET['username']
return render(request, ‘page.html', {‘user’: user})
Security best practices in forms
Validate form data with Django Forms package
Use POST method in HTML Forms
Use Meta.Fields in ModelForms
Steganography
Hiding data(text/images) within images

Where is stored the data?


Steganography
In the pixels in RGB Components
Altering the Least Significant Bit(LSB)
Use one bit per pixel for storing data
Libraries in python
Stepic http://domnit.org/stepic/doc
Libraries
Stegano https://code.google.com/p/stegano-cb

$ slsb.py --hide -i python.png -o python-secret.png –m “euro..”

$ slsb.py --hide -i python.png -o python-secret.png –f img.png


Tools
Cryptopng https://pypi.python.org/pypi/cryptoPNG/0.1
Hide text in image(LSB)
Reveal text from image(LSB)
Hide image inside an image
GitHub https://github.com/jmortega/europython
Book http://inventwithpython.com/hacking/index.html

Hacking Secret Ciphers with python


Free online
Thank you!
José Manuel Ortega| @jmortegac

You might also like