¿Qué necesito para distribuir claves (CERT), para Python con la conexión / SSL sockets?

StackOverflow https://stackoverflow.com/questions/4609859

  •  25-09-2019
  •  | 
  •  

Pregunta

Estoy intentando escribir una aplicación cliente-servidor genérico que será capaz de intercambiar datos entre los servidores. He leído sobre un buen número de documentos de OpenSSL, y tengo preparado correctamente mi propia CA y ha creado un certificado (y la clave privada) para propósitos de prueba.

estoy atascado con Python 2.3, así que no puedo utilizar la biblioteca estándar "ssl". En su lugar, tengo que cargar con pyOpenSSL, lo que no parece malo, pero no hay muchos documentos que hay sobre ella.

Mi pregunta no es realmente acerca de conseguir que funcione. Estoy más confundido acerca de los certificados y donde tienen que ir.

Aquí están mis dos programas que hacer de trabajo:

Servidor:

#!/bin/env python

from OpenSSL import SSL
import socket
import pickle

def verify_cb(conn, cert, errnum, depth, ok):
    print('Got cert: %s' % cert.get_subject())
    return ok


ctx = SSL.Context(SSL.TLSv1_METHOD)
ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)

# ??????
ctx.use_privatekey_file('./Dmgr-key.pem')
ctx.use_certificate_file('Dmgr-cert.pem')
# ??????
ctx.load_verify_locations('./CAcert.pem')

server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))

server.bind(('', 50000))
server.listen(3)

a, b = server.accept()

c = a.recv(1024)
print(c)

Cliente:

from OpenSSL import SSL
import socket
import pickle


def verify_cb(conn, cert, errnum, depth, ok):
    print('Got cert: %s' % cert.get_subject())
    return ok

ctx = SSL.Context(SSL.TLSv1_METHOD)
ctx.set_verify(SSL.VERIFY_PEER, verify_cb)

# ??????????
ctx.use_privatekey_file('/home/justin/code/work/CA/private/Dmgr-key.pem')
ctx.use_certificate_file('/home/justin/code/work/CA/Dmgr-cert.pem')
# ?????????
ctx.load_verify_locations('/home/justin/code/work/CA/CAcert.pem')

sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sock.connect(('10.0.0.3', 50000))

a = Tester(2, 2)
b = pickle.dumps(a)
sock.send("Hello, world")

sock.flush()
sock.send(b)
sock.shutdown()
sock.close()

He encontrado esta información de ftp://ftp.pbone.net/mirror/ftp.pld-linux.org/dists/2.0/PLD/i586/PLD/RPMS/python-pyOpenSSL -examples-0.6-2.i586.rpm que contiene algunos scripts de ejemplo.

Como se puede recoger, no entiendo completamente los tramos entre el "# ????????". No entiendo por qué el certificado y la clave privada se necesitan tanto en el cliente y el servidor. No estoy seguro de donde cada uno debe ir, pero no debería sólo es necesario para distribuir una parte de la clave (probablemente la parte pública)? Socava el propósito de tener las claves asimétricas si todavía necesita tanto en cada servidor, ¿verdad?

He intentado eliminar alterna o bien la tecla p o certificado a cada cuadro, y me sale el siguiente error no importa cual elimino:

  

OpenSSL.SSL.Error: [( 'rutinas SSL', 'SSL3_READ_BYTES', 'alerta SSLv3 fracaso apretón de manos'), ( 'rutinas SSL', 'SSL3_WRITE_BYTES', 'insuficiencia ssl apretón de manos')]

Podría alguien explicar si este es el comportamiento esperado para SSL. ¿Es realmente necesario para distribuir la clave privada y el certificado público a todos mis clientes? Estoy tratando de evitar cualquier problema de seguridad enormes, y fugas de claves privadas tendería a ser un grande ...

Gracias por la ayuda!

=============================================== ===================

Gracias a la CAF para ayudarme a averiguar el problema. Sobre la base de su recomendación, he creado dos nuevos pares de certificado: hombre del espacio y dmgr. Entonces puse las dos partes "astronauta" (de llave, CERT) en el programa cliente, y lo mismo para las teclas "dmgr".

Básicamente, sólo los siguientes dos líneas en Cliente cambió, aunque no había suficiente de trabajo con openssl en el lado.

ctx.use_privatekey_file('/home/justin/code/work/CA/private/Dmgr-key.pem')
ctx.use_certificate_file('/home/justin/code/work/CA/Dmgr-cert.pem')

Versión corregida:

ctx.use_privatekey_file('/home/justin/code/work/CA/private/spaceman-key.pem')
ctx.use_certificate_file('/home/justin/code/work/CA/spacemancert.pem')
¿Fue útil?

Solución

En una transacción SSL, cada lado puede presentar un certificado para verificar su identidad al otro lado. Para ello, se necesita tener la clave privada correspondiente a dicho certificado. Estos están destinados a ser dos diferentes certificados, por lo que cada lado tendrá dos claves privadas diferentes.

Este certificado / clave privada pareja es el que va a configurar usando use_privatekey_file() y use_certificate_file(). Este debe ser un diferente Certificado / par de claves en el servidor y el cliente.

Al verificar el certificado compañeros, este caso es necesario comprobar:

  • que el certificado es válida (es decir, firmado por una CA que usted confía para esta aplicación, no ha caducado, no revocado); y
  • Corresponde a los pares que pensar que estés conectado con (es decir, el certificado coincide con la identidad que las demandas de pares). Esta identidad se almacena dentro del campo SubjectName del certificado, y es de aplicación específica cómo asignar esto a una identidad entre pares (que podría ser un nombre de usuario de inicio de sesión, un nombre DNS, o alguna otra cosa).
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top