(Esto se basa en mi respuesta a la misma pregunta en SO . A menudo es mejor preguntar en una sola SE sitio.)
El protocolo TLS solo permite el intercambio de certificados, no las claves públicas sin formato. Incluso "claves PGP" (si desea reemplazar X.509 con OpenPGP para la autenticación en TLS , que es mucho menos compatible ) son certificados de hecho (son la combinación firmada de una clave pública y un conjunto de identificadores y atributos).
Como dice Thomas, posiblemente puedas definir tu propio tipo de certificado y convertirlo en una clave pública simple (aunque no estoy seguro de que aún se puedan llamar "certificados" técnicamente).
Desde un punto de vista práctico, debería poder lograr lo que necesita utilizando las pilas SSL / TLS existentes, y ajustar la forma en que tratan los certificados de verificación X.509, con precaución . De hecho, la mayoría de las pilas SSL / TLS exponen la verificación de los certificados X.509 a través de sus API, pero pocos permiten otros tipos de certificados (por ejemplo, OpenPGP) o le permiten personalizar su código fácilmente. La personalización de certificados que no sean X.509 puede ser bastante difícil, puede resultar en errores adicionales si es nuevo en la implementación de SSL / TLS y también sería difícil de implementar en la práctica, ya que todos los clientes potenciales también necesitarían ser compatibles con sus personalizaciones. .
Puede realizar la autenticación del cliente utilizando certificados X.509 de cliente autofirmados y confiar en sus claves públicas ( pero deberá verificar esta clave pública contra algo que su servidor ya conoce, como una lista conocida ). Debe comprender las implicaciones de seguridad para implementar esto primero. Este no es el mismo problema que los certificados de servidor autofirmados. (Sugiero mantener un enfoque más tradicional para verificar el certificado del servidor).
Puede hacer que el cliente envíe un certificado autofirmado (posiblemente utilizando ciertos trucos con respecto a la lista de CA anunciada por el servidor ) y realice la verificación en la pila TLS o más adelante en la aplicación.
Tenga en cuenta que muchos contenedores de aplicaciones (por ejemplo, Tomcat / Jetty en Java) esperan que la capa SSL / TLS verifique el certificado del cliente. Por lo tanto, si omite la autenticación allí (y prefiere hacerlo más adelante dentro del contenedor o como parte de la aplicación), muchos marcos de aplicación se confundirán. Debe tener mucho cuidado para asegurarse de que la autenticación se realice realmente en algún lugar antes de realizar cualquier acción que requiera autenticación en su aplicación.
Por ejemplo, puede estar bien tener un administrador de confianza que permita que cualquier certificado de cliente pase por Tomcat / Jetty, pero no puede confiar en que el atributo de solicitud javax.servlet.request.X509Certificate
haya sido verificado de ninguna manera (que la mayoría de los marcos) de lo contrario esperaría). Necesitaría implementar alguna lógica de verificación dentro de su aplicación: por ejemplo, tener un filtro antes de cualquier función autenticada que compare la clave pública en este certificado de cliente con su lista conocida de claves públicas (o sin embargo, desea hacer coincidir la clave pública con un identificador). Alternativamente, también puede realizar esta verificación dentro de su administrador de confianza personalizado (en Java), esto requerirá menos trabajo dentro de las aplicaciones.
Podría hacer algo similar en una configuración de Apache Httpd + PHP (por ejemplo), usando SSLVerifyClient optional_no_ca
. Una vez más, su aplicación PHP no puede confiar en que el certificado haya sido verificado, por lo que tendría que implementar la verificación también.
No hagas nada de esto a menos que entiendas en qué etapa se verificó la información del certificado que obtuviste.