4. Agenda
Introducción a la criptografía1
OWASP & Best Practices4
Seguridad en Django3
PyCrypto y otras librerías2
Tools5
5. definiciones
Clave: Permite encriptar y
desencriptar los datos
TextoPlano: Informatión que
quieres mantener en secreto
Texto Cifrado: Información
de forma encriptadada
Algoritmo de cifrado:
convierte texto plano a
cifrado y viceversa
6. advanced
Salt – Secuencia aleatoria que
se añade a la password
IV (initialization vector) –
previene ataques de
diccionario o mediante
rainbow tables
Derived Key – Fortalece la
generación de claves para que
los ataques de fuerza bruta
tengan menos éxito.
7. Introducción a la criptografía
Cifrado de césar
Funciones hash(MD5,SHA)
Cifrado simétrico(AES)
Cifrado asímétrico(RSA)
PBKDF2-Key derivation function
14. Hash passwords en DB
Websites almacenan el hash de la password
hashlib.sha256(‘password').hexdigest()
>>'5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d15
42d8'
18. Cifrado asimétrico
RSA
2 claves(pública y privada)
Clave pública(Pk) encriptar
Clave secreta(Sk) descifrar
La clave pública se puede generar a
partir de la clave secreta
20. Encriptación vs Firma
EncriptaciónUsas su clave pública para
enviar un mensaje y el destinatario usa su
clave privada para leerlo.
FirmaPara firmar usas tu clave privada, y
el destinatario usa tu clave pública para
verificar que la documento lo ha firmado
quién dice ser.
23. PyCrypto PBKDFimport Crypto.Random
from Crypto.Protocol.KDF import PBKDF2
password = 'europython'
iterations = 5000
key = ''
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
24. 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
28. Mejores prácticas
Evitar usar algoritmos MD5 /SHA-1
Usar al menos SHA-2(256-512 bits)
Uso de técnicas más avanzadas como Key
Stretching
Prevenir ataques de diccionario o fuerza bruta
for i in xrange(iterations):
m = hashlib.sha512()
m.update(key + password + salt)
key = m.digest()
PBKDF
29. Cryptography
Soporte para Python 3
Mejora debug y testing
La usan otras herramientas como PyCrypto,
PyOpenssl, Paramiko
$ pip install cryptography
https://cryptography.io
33. Seguridad en Django
Configuración SSL del servidor
Vulnerabilidad HeartBleed
Uso de algoritmos de cifrado débiles
Gestión de claves secretas
Autorización / autenticación de usuarios
Manejo de cookies del usuario
35. Qué proveen estos frameworks?
Protección Cross-site scripting(XSS)
Protección Cross-site request forgery(CSRF)
Protección SQL Injection
Protección Clickjacking
Soporte SSL/HTTPS
Uso de algoritmos PBKDF2 /SHA256 para el
almacenamiento de passwords
Seguridad en Django
36. Almacenamiento de passwords
PBKDF2 + SHA256 por defecto
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')
37. 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 = 30000
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)
https://github.com/django/django/blob/master/django/contrib/auth/hashers.py/
Almacenamiento de passwords
41. Mejores prácticas
Usar HTTPS para conexiónes seguras
SSL
Habilitar HTTPS junto con un certificado propio
Forzar HTTPS en todo el dominio
Flags de seguridad para las cookies
Django only send session cookies over HTTPS
SESSION_COOKIE_SECURE = true
CSRF_COOKIE_SECURE_true
42. Mejores prácticas
Guardar de forma segura claves secretas y
credenciales
Establecer DEBUG=false en producción en
settings.py
Usar ALLOWED_HOSTS en producción y
asignarle aquellos dominios de los cuales se
tenga control
Limitar accesos admin mediante IP filter
ALLOWED_HOSTS =[*]
ALLOWED_HOSTS =['.yourdomain.com']
45. SQL injection
No confiar en los datos que envía el usuario
Correcto filtrado de los parámetros
Uso de cursores y bind parameter
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])
46. SQL injection
Django ORM –QuerySets –Models
Seguridad transparente para el desarrollador
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
>>b = Blog(name=‘My blog', description=‘django security')
>>> b.save()
48. Cross site Scripting(XSS)
Permite a un atacante obtener información
de la sesión del usuario
Usar el sistema de plantillas de renderizado para escapar los
valores que se pintan en las páginas HTML
from django.shortcuts import render
def render_page(request):
user = request.GET['username']
return render(request, ‘page.html', {‘user’:user})
49. Mejores prácticas Django
Validar datos de formularios con el
paquete Django forms
Peticiones mediante POST
Usar Meta.Fields en ModelForms