Eu tenho um cenário em que alguns clientes mais antigos só podem dar suporte a assinaturas MD5 e SHA1. Obviamente, estes são geralmente considerados obsoletos, mas ainda preciso apoiá-los. Atualizar esses clientes não é algo que pode ser feito (atualizações de firmware não estão mais sendo publicadas, idealmente eu gostaria de eliminar todos esses dispositivos, mas isso também não é viável).
Suponha que eu ainda possa obter um certificado assinado MD5 ou SHA1.
É possível em qualquer servidor (https) servir certificados diferentes com base na versão TLS de entrada contida no bloco ClientHello enviado pelo cliente na primeira conexão?
Acredito que seja possível escrever um pequeno "proxy" que apenas leia os primeiros bytes recebidos do cliente e, em seguida, splicing a conexão para portas alternativas que atendem a solicitações diferentes no pior caso, mas, se possível, prefiro evite isso se houver servidores da Web existentes que suportem algo assim.
À parte: Pelo que entendi, o protocolo SSL/TLS contém proteção contra ataques de downgrade, portanto, se o servidor suportar 1.2 e o cliente também suportar 1.2, se ocorrer um downgrade para 1.0, a conexão deverá terminar (no caso de um man-in ativo -ataque do meio). Acredito que isso deve mitigar o risco de servir certificados assinados MD5 ou SHA1 pelo menos tanto quanto pode ser feito enquanto ainda oferece suporte a versões SSL/TLS mais antigas.
Eu tive um problema muito parecido. Eu não acredito que você encontrará um servidor que faça o que você pede. Eu também acho que você deveria parar de procurar por um :
Você NÃO deve confiar em certificados MD5 ou SHA1 para proteger quaisquer conexões. Esses certificados são considerados vulneráveis porque existe o risco de alguém falsificar esses certificados. Todos os clientes agora devem rejeitar certificados MD5 e SHA1 antigos.
Você deve evitar qualquer cliente conversando com seus servidores em conexões inseguras. Se algum cliente ou servidor não puder ser atualizado, você deverá colocá-lo em sua própria caixa de proteção segura.
Como resolver o problema
Assim como você, dei suporte a softwares antigos que não puderam ser atualizados. Seja qual for o conselho de segurança, todos nós temos que trabalhar com o que temos.
Eu recomendo stunnel . Isso é executado como um servidor autônomo que encaminha todas as conexões que recebe: criptografando ou descriptografando-as primeiro.
Para usar isso, o ideal é instalá-lo no host antigo. Desative o SSL no software antigo e configure-o para conectar sem criptografia ao stunnel em vez de conectar com criptografia (insegura) ao seu servidor:
Se instalá-lo na mesma caixa não for uma opção, instale-o em uma nova caixa conectada firmemente ao host antigo. Isso poderia ser apenas um pi de framboesa conectado ao mesmo switch:
Se o software antigo se recusar a se conectar sem criptografia, você poderá usar o stunnel novamente, agir como um servidor oferecendo um certificado MD5 ou SHA1 antigo. Novamente, os dois devem estar fisicamente conectados porque você deve pensar em uma conexão com um certificado antigo como se não fosse criptografado:
O Nginx com sua extensão lua e a parte ssl dele pode escolher um certificado para expor com base no início do handshake e no que o cliente enviou,
ClientHello
mas talvez não o que você precisa precisamente (lista de algoritmos suportados).A documentação completa está em https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md e https://github.com/openresty/lua-nginx-module/# ssl_certificate_by_lua_block
Ele afirma:
Você pode acessar facilmente o IP do cliente ou servidor (para multihomed) através da função
raw_client_addr
eraw_server_addr
, assim como o nome do host que o cliente está tentando alcançar lendo a parte SNI comserver_name
. Com base na documentação, não vejo como obter acesso a outra parte do cliente ClientHello, mas talvez você possa encontrar uma solução já com o acima, se puder discriminar seus clientes com base no IP deles, ou se tiver dois nomes de servidor separados, cada um pode-se ficar vinculado a um certificado específico.Lendo https://github.com/openresty/lua-nginx-module/blob/master/src/ngx_http_lua_ssl_certby.c não vejo nenhum método específico acessando a lista de conjuntos de cifras enviados pelo cliente. No entanto, esse pedaço de código obtém todas as informações "SSL" subjacentes da biblioteca openssl, então suspeito que o que você deseja é tecnicamente possível, mas só precisa ser codificado.
Agora dois outros pontos:
1) "Suponha que eu ainda possa obter um certificado assinado MD5 ou SHA1."
Isso pode ser difícil. Pelo menos de uma CA conhecida pública em operação padrão. Requisitos do Fórum CAB ( https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.6.3.pdf ) tem isso na página 38:
e depois:
2) "Pelo que entendi, o protocolo SSL/TLS contém proteção contra ataques de downgrade, portanto, se o servidor suportar 1.2 e o cliente também suportar 1.2, se ocorrer um downgrade para 1.0, a conexão deverá terminar (no caso de um usuário ativo). ataque no meio)."
Sim, mas apenas se estiver usando a extensão
TLS_FALLBACK_SCSV
e provavelmente proibindo a renegociação do cliente durante uma sessão existente. Consulte https://crypto.stackexchange.com/questions/19673/how-does-tls-fallback-scsv-help#19674 para obter explicações, mas citando a parte principal:A página da Wikipedia em https://en.wikipedia.org/wiki/Transport_Layer_Security também discute em detalhes coisas sobre ataques de downgrade.
A propósito, isso é aprimorado no TLS 1.3, citando 4.1.3. Olá do servidor da RFC8446:
e