Certificados digitais de conexões RPC

7 minuto(s) de leitura

Atualizado em:

1. Introdução

Os componentes do Decred usam certificados digitais X509v3 para validar identidade e encriptar a comunicação entre eles (ponta-a-ponta).

Figura 1 - Acesso localhost pode não usar certificados digitais
Figura 1 - Acesso localhost pode não usar certificados digitais

Quando dcrd, dcrwallet e Decrediton são executados, tentam localizar a chave privada (rpc.key) e o certificado digital (rpc.cert), que contém a chave pública. Se não forem encontrados, serão gerados automaticamente.

Saiba mais sobre criptografia assimétrica e certificados digitais em Uma breve noção de criptografia.

2. Comunicação local

É possível iniciar os componentes do Decred sem suporte a criptografia apenas para comunicação localhost (no mesmo dispositivo). As opções de linha de comando são:

$ ./dcrd --notls [--testnet]
$ ./dcrwallet --noservertls --noclienttls [--testnet]
$ ./dcrctl --notls [--testnet] [comando]
$ ./dcrctl --notls [--testnet] --wallet [comando]

3. Comunicação em rede

Para permitir que um componente cliente de RPC (dcrwallet, dcrctl e Decrediton) se conecte a um componente servidor de RPC (dcrd, dcrwallet) em outro host, será necessário copiar o certificado digital do servidor de RPC para o cliente de RPC.

No esquema a seguir, os certificados foram copiados entre os hosts e o nome do componente foi adicionado como prefixo para facilitar a identificação.

Figura 2 - Conexão depende da validação do certificado digital
Figura 2 - Conexão depende da validação do certificado digital

Como esses certificados são auto-assinados (self-signed), não dependem de uma autoridade certificadora (CA) para validá-los.

Os certificados são gerados com uma extensão do protocolo X509v3, chamada Subject Alternative Name. Essa extensão armazena no certificado nomes DNS e endereços IP válidos para o servidor. Assim, se o servidor (dcrd ou dcrwallet) tiver seu nome ou endereço IP trocado será necessário gerar outro certificado e copiá-lo para os clientes (dcrwallet, dcrctl e Decrediton).

Por questões de segurança, quando dcrd e dcrwallet não forem executados no mesmo dispositivo, não é recomendável usar as mesmas credenciais (usuário e senha) e o mesmo certificado digital no dcrd e no dcrwallet.

É possível construir outros cenários, bastando apenas adaptar os comandos e parâmetros:

  • dcrd e dcrwallet em um dispositivo; dcrclient em outro;
  • dcrd em um dispositivo; dcrwallet e dcrclient em outro;
  • dcrd e dcrclient em um dispositivo; dcrwallet em outro;

3.1. Exemplos de comunicação em rede

Nas linhas 1 e 2, dcrd e dcrwallet atuam como servidores e carregam certificado e chave privada através das opções --rpccert e --rpckey. Ainda na linha 2, o dcrwallet também atua como cliente, assim como na figura 1, por isso usa a opção --cafile para indicar o certificado do dcrd. Nas linhas 3 e 4, dcrctl atua como cliente RPC dos dois componentes. Clientes apenas indicam o certificado do servidor na opção --cafile e não usam --rpclisten porque não esperam conexão em nenhuma porta.

$ ./dcrd --rpclisten=0.0.0.0 --rpccert=$DCRD_CERT --rpckey=$DCRD_KEY
$ ./dcrwallet --rpclisten=0.0.0.0 --rpccert=$DCRW_CERT --rpckey=$DCRW_KEY -c $DCRD_IP -u $DCRD_USER -P $DCRD_PASS --cafile=$DCRD_CERT
$ ./dcrctl -s $DCRD_IP -u $DCRD_USER -P $DCRD_PASS -c $DCRD_CERT [comando]
$ ./dcrctl -w $DCRW_IP -u $DCRW_USER -P $DCRW_PASS -c $DCRW_CERT --wallet [comando]

Para Testnet, basta incluir a opção --testnet.

Parâmetro Localização
$DCRD_USER rpcuser, no dcrd.conf
$DCRD_PASS rpcpass, no dcrd.conf
$DCRD_CERT Certificado digital (inclui a chave pública). Por padrão é rpc.cert.
$DCRD_KEY Chave privada do certificado digital. Por padrão é rpc.key.
$DCRD_IP Se rpclisten for 0.0.0.0, corresponde a qualquer endereço IP. Se não for, deve ser o IP informado em rpclisten.
$DCRW_USER username, no dcrwallet.conf
$DCRW_PASS password, no dcrwallet.conf
$DCRW_CERT Certificado digital (inclui a chave pública). Por padrão é rpc.cert.
$DCRW_KEY Chave privada do certificado digital. Por padrão é rpc.key.
$DCRW_IP Se rpclisten for 0.0.0.0, corresponde a qualquer endereço IP. Se não for, deve ser o IP informado em rpclisten.

4. Gerando o certificado no OpenSSL

Os certificados X509v3 podem ser criados com o OpenSSL instalado no Linux. Pode ser útil para usuários que:

  • por questões de conformidade precisam alterar métodos criptográficos ou prazo de validade do certificado que por padrão é 3650 dias;
  • precisam alterar o hostname ou o endereço IP;
  • precisam incluir mais endereços IP ou hostnames;

Esta seção usa o cenário descrito na figura a seguir como exemplo para os comandos do OpenSSL.

Figura 3 - Exemplo de cenário para uso do OpenSSL
Figura 3 - Exemplo de cenário para uso do OpenSSL

Os comandos a seguir devem ser executados no dispositivo que executará o dcrd.

a) Crie a chave privada ECDSA 521-bit. Será usado o nome ‘dcrd’ no lugar de ‘rpc’.

$ openssl ecparam -name secp521r1 -genkey -out dcrd.key

b) Faça uma cópia do arquivo de configuração padrão do OpenSSL para incluir parâmetros para essa geração de certificados:

$ sudo cp /etc/ssl/openssl.cnf /etc/ssl/openssl-decred.cnf

c) Edite o arquivo e procure pela seção [req]. Inclua a última linha.

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req

d) Mais embaixo, na seção [v3_req], inclua a última linha a seguir.

[v3_req]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

e) A última linha do código anterior aponta para a seção [alt_names] que não existe no arquivo e precisa ser criada para incluir outros nomes e endereços IP válidos para esse certificado. Copie e cole as próximas linhas, com as devidas modificações de acordo com o seu ambiente.

[alt_names]
DNS.1 = localhost
DNS.2 = fullnode
IP.1 = 127.0.0.1
IP.2 = 192.168.55.143

f) Crie o pedido do certificado (ssl.csr), com a chave que foi gerada anteriormente (dcrd.key) e o arquivo de configuração que foi editado (openssl-decred.cnf).

$ openssl req -new -out dcrd.csr -key dcrd.key -config /etc/ssl/openssl-decred.cnf -subj "/CN=dcrd cert"

g) Faça o output na tela para conferir o certificado que será assinado.

$ openssl req -text -noout -in dcrd.csr 
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: CN = dcrd cert
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (521 bit)
                pub:
                    04:01:3b:c4:dc:2f:54:1c:7b:96:a9:cb:f4:ef:81:
                    39:08:3d:8a:93:57:93:d5:6a:5c:35:38:b5:fd:6a:
                    8a:b5:e7:a2:21:cd:c6:a8:4d:4f:d9:a1:9d:cd:8e:
                    f1:e0:13:50:2e:6a:e1:80:ab:aa:97:53:89:84:b9:
                    2d:6d:3a:27:28:af:1d:00:aa:e8:39:29:ff:1d:33:
                    b7:14:0e:2f:2d:ab:ab:a5:3f:ef:db:13:b7:8c:ff:
                    2f:78:a3:b7:99:2c:7e:c1:c9:3f:5d:0b:ce:95:32:
                    dc:9f:b5:cb:4f:11:95:71:e1:a1:2d:3f:40:57:16:
                    28:40:17:20:67:1e:ff:87:66:c5:4a:5c:1c
                ASN1 OID: secp521r1
                NIST CURVE: P-521
        Attributes:
        Requested Extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Key Usage: 
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:fullnode, IP Address:127.0.0.1, IP Address:192.168.55.143
    Signature Algorithm: ecdsa-with-SHA256
         30:81:87:02:41:4e:e0:32:bc:cc:85:37:9f:5e:3d:57:5a:20:
         59:ee:4d:a9:b8:1a:2e:7f:36:84:1c:16:e9:cc:99:a2:06:23:
         99:33:98:ce:86:0a:22:23:4f:4c:eb:85:d9:d4:66:40:ca:59:
         af:24:4c:1f:b4:c0:c6:a4:b8:c3:7b:17:07:35:70:3c:02:42:
         01:07:41:6c:25:08:22:55:b2:61:5f:81:3f:78:84:c4:c8:04:
         28:d6:68:28:3c:b4:ee:1e:90:b8:bf:a4:8d:0b:57:51:10:cc:
         4d:97:71:63:e8:43:d7:54:12:9b:d3:b3:01:c4:6a:98:ac:74:
         17:5d:1e:3d:3e:66:40:d6:8b:71:e9:3d

O pedido de geração do certificado inclui uma seção de dados, que contém informações sobre hierarquia, a chave pública, outros atributos como o tipo de uso permitido (assinatura digital, não-repúdio e troca de chaves) e os nomes de hosts e IPs válidos para uso desse certificado e a assinatura digital do pedido do certificado. Essas informações são mostradas na seção de código antes deste parágrafo e no esquema da figura a seguir.

Figura 4 - Criação do pedido do certificado
Figura 4 - Criação do pedido do certificado

A criação do certificado gera um hash das informações de hierarquia, chave pública, atributos e extensões. A assinatura do pedido do certificado não é usada.

Em um certificado self-signed o hash é assinado com a própria chave privada do par. Para certificados que fazem parte de uma cadeia hierárquica o hash é assinado com a chave privada do certificado da CA (Certification Authority), que é a entidade confiável (confiável no sentido de que outros usuários já confiam no seu certificado digital - já está instalado).

Figura 5 - Criação do certificado self-signed ou assinado pela CA
Figura 5 - Criação do certificado self-signed ou assinado pela CA

h) Se todas as informações estão corretas, crie o certificado self-signed. Repare na opção -signkey, que aponta para a chave dcrd.key criada no passo a) assinar o certificado dcrd.cert.

$ openssl x509 -req -days 3650 -in dcrd.csr -signkey dcrd.key -out dcrd.cert -extensions v3_req -extfile /etc/ssl/openssl-decred.cnf
Signature ok
subject=CN = dcrd cert
Getting Private key

i) Faça o output na tela para conferir o certificado assinado.

$ openssl x509 -text -in dcrd.cert
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            cb:24:66:90:57:e7:92:8b
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN = dcrd cert
        Validity
            Not Before: Mar 29 23:32:56 2018 GMT
            Not After : Mar 26 23:32:56 2028 GMT
        Subject: CN = dcrd cert
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (521 bit)
                pub:
                    04:01:3b:c4:dc:2f:54:1c:7b:96:a9:cb:f4:ef:81:
                    39:08:3d:8a:93:57:93:d5:6a:5c:35:38:b5:fd:6a:
                    8a:b5:e7:a2:21:cd:c6:a8:4d:4f:d9:a1:9d:cd:8e:
                    f1:e0:13:50:2e:6a:e1:80:ab:aa:97:53:89:84:b9:
                    2d:6d:3a:27:28:af:1d:00:aa:e8:39:29:ff:1d:33:
                    b7:14:0e:2f:2d:ab:ab:a5:3f:ef:db:13:b7:8c:ff:
                    2f:78:a3:b7:99:2c:7e:c1:c9:3f:5d:0b:ce:95:32:
                    dc:9f:b5:cb:4f:11:95:71:e1:a1:2d:3f:40:57:16:
                    28:40:17:20:67:1e:ff:87:66:c5:4a:5c:1c
                ASN1 OID: secp521r1
                NIST CURVE: P-521
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Key Usage: 
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:fullnode, IP Address:127.0.0.1, IP Address:192.168.55.143
    Signature Algorithm: ecdsa-with-SHA256
         30:81:88:02:42:01:89:e9:75:a2:92:7e:83:a2:10:06:1a:17:
         0e:7c:40:b6:bc:05:11:a1:f7:c0:9c:4d:5b:0b:5a:84:d8:e8:
         d2:9d:49:60:63:43:54:5f:cc:dd:d6:47:1d:92:7b:53:14:a7:
         d2:d2:d9:f0:3d:2c:04:b7:80:96:5c:a3:6d:da:c2:81:a9:02:
         42:00:ed:d4:65:40:d0:2f:27:87:4f:61:f0:d5:f4:5d:be:82:
         9c:01:a0:db:ff:14:3c:d0:1f:3e:4f:20:9d:27:ae:e0:3b:9b:
         50:4c:84:2f:b8:0f:34:d9:2c:23:04:1e:c6:5b:d1:19:a6:3c:
         9d:79:3a:08:8f:d8:f3:a2:02:8f:3b:94:c6
-----BEGIN CERTIFICATE-----
MIIB7TCCAU6gAwIBAgIJAMskZpBX55KLMAoGCCqGSM49BAMCMBQxEjAQBgNVBAMM
CWRjcmQgY2VydDAeFw0xODAzMjkyMzMyNTZaFw0yODAzMjYyMzMyNTZaMBQxEjAQ
BgNVBAMMCWRjcmQgY2VydDCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEATvE3C9U
HHuWqcv074E5CD2Kk1eT1WpcNTi1/WqKteeiIc3GqE1P2aGdzY7x4BNQLmrhgKuq
l1OJhLktbTonKK8dAKroOSn/HTO3FA4vLaurpT/v2xO3jP8veKO3mSx+wck/XQvO
lTLcn7XLTxGVceGhLT9AVxYoQBcgZx7/h2bFSlwco0YwRDAJBgNVHRMEAjAAMAsG
A1UdDwQEAwIF4DAqBgNVHREEIzAhgglsb2NhbGhvc3SCCGZ1bGxub2RlhwR/AAAB
hwTAqDePMAoGCCqGSM49BAMCA4GMADCBiAJCAYnpdaKSfoOiEAYaFw58QLa8BRGh
98CcTVsLWoTY6NKdSWBjQ1RfzN3WRx2Se1MUp9LS2fA9LAS3gJZco23awoGpAkIA
7dRlQNAvJ4dPYfDV9F2+gpwBoNv/FDzQHz5PIJ0nruA7m1BMhC+4DzTZLCMEHsZb
0RmmPJ15OgiP2POiAo87lMY=
-----END CERTIFICATE-----

Repita os comandos (exceto a parte do openssl.cnf se o dcrwallet for executado no mesmo dispositivo) para criar os arquivos dcrw.cert e dcrw.key. Copie os arquivos conforme indicado na figura 3 e substitua os nomes dos arquivos na linha de comando:

$ ./dcrd --rpclisten=192.168.55.143 --rpccert=dcrd.cert --rpckey=dcrd.key
$ ./dcrwallet --rpclisten=192.168.55.144 --rpccert=dcrw.cert --rpckey=dcrw.key -c 192.168.55.143 -u $DCRD_USER -P $DCRD_PASS --cafile=dcrd.cert
$ ./dcrctl -s 192.168.55.143 -u $DCRD_USER -P $DCRD_PASS -c dcrd.cert [comando]
$ ./dcrctl -w 192.168.55.144 -u $DCRW_USER -P $DCRW_PASS -c dcrw.cert --wallet [comando]