Certificados digitais de conexões RPC
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
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
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
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
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
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]