Primeiramente temos que criar um keystore contendo nossa chave privada. Utilizaremos para isso a ferramenta Keytool do JDK.
Vamos criar nosso certificado.
keytool -genkeypair -alias certificado -keypass password -keysize 2048 -keystore certificado.jks -storepass password -validity 365 -keyalg RSA
Explicando o comando:
-genkeypair —– será criado um par de chaves (chave pública e privada).
-alias —– será o nome que o certificado terá dentro do keystore
-keypass —– será a senha do certificado (por padrão a senha do certificado deve ser a mesma do keystore)
-keysize —– será o tamanho, em bits, do nosso certificado.
-keystore —– será o local onde iremos armazenar nosso certificado
-storepass —– será a senha do keystore
-validity —– será a validade do nosso certificado.
-keyalg —– será o algorítimo que iremos utilizar para gerar nosso certificado
Ao finalizar o comando serão cobrados alguns parametros:
Qual é o seu nome e o seu sobrenome? [Unknown]: Qual é o nome da sua unidade organizacional? [Unknown]: Qual é o nome da sua empresa? [Unknown]: Qual é o nome da sua Cidade ou Localidade? [Unknown]: Qual é o nome do seu Estado ou Município? [Unknown]: Quais são as duas letras do código do país desta unidade? [Unknown]: CN=Sobrenome, OU=Unidade, O=Empresa, L=Cidade, ST=Estado, C=Pais Está correto? [não]:
Pronto, o certificado esta pronto. Agora precisamos extrair o csr do arquivo. O arquivo CSR é a requisição de assinatura do certificado.
keytool -certreq -alias certificado -keyalg RSA -file dominio.csr -keystore certificado.jks
explicando o comando:
-certreq —- gera a requisição do certificado
-file —- o arquivo que será criado para manter o csr
O arquivo CSR deve parecer com o seguinte:
Em posse desse arquivo você deverá entrar em contato com alguma empresa certificadora (certisign, serasa, etc) e enviar o arquivo para gerarem o certificado. Depois de um bom tempo você irá receber alguns arquivos. Nestes arquivos você irá receber as cadeias de verificação e o próprio certificado. Em posso do certificado gerado pela entidade certificadora, vamos ao processo completo para geração do arquivo PFX (arquivo contendo as chaves pública e privada).
Primeiro, vamos carregar as cadeias de verificação para dentro do nosso keystore gerado no primeiro passo.
keytool -import -alias raiz -file raiz.cer -keystore certificado.jks keytool -import -alias ca -file ca.cer -keystore certificado.jks
Pronto, importamos todas as cadeias. Note que o nome do arquivo e do alias podem ser diferentes e a quantidade de cadeias também, então é preciso importar todas as cadeias antes de importar o certificado.
Agora vamos importar o certificado.
keytool -import -alias certificado -file certificado.cer -keystore certificado.jks
Note que o alias utilizado é o mesmo alias que foi criado. Ao listar o seu keystore você verá a
a seguinte tela:
Para listar utilize o seguinte comando:
keytool -list -keystore certificado.jks -storepass password
Note que existem duas entradas trustedCertEntry e uma entrada PrivateKeyEntry. Isso significa que existem dois certificados confiáveis e um certificado com chave privada importados no keystore.
Pronto, o seu certificado, assinado e validado por uma entidade certificadora, esta pronto para iniciar o processo de geração do PFX.
Vamos lá.
1º – Exportar o certificado para um arquivo crt (certificate).
keytool -exportcert -alias certificado -keypass password -keystore certificado.jks -storepass password -file certificado.crt -rfc
Explicando o comando:
-exportcert – será exportado o certificado
-rfc —- a saida será dada no padrão Base64 Encoding
sem a saida -rfc o arquivo será gerado no padrão binario o que complica bastante para exportá-lo. Agora precisamos exportar a chave privada. O comando acima não exporta a chave privada do certificado. Para isso precisamos exportá-la através de um programinha que roda em java. Abaixo o código do programa.
import java.io.*; import java.security.*; public class DumpKey { static public void main(String[] a) { if (a.length<5) { System.out.println("Usage:"); System.out.println("java DumpKey jks storepass alias keypass out"); return; } String jksFile = a[0]; char[] jksPass = a[1].toCharArray(); String keyName = a[2]; char[] keyPass = a[3].toCharArray(); String outFile = a[4]; try { KeyStore jks = KeyStore.getInstance("jks"); jks.load(new FileInputStream(jksFile), jksPass); Key key = jks.getKey(keyName, keyPass); System.out.println("Key algorithm: "+key.getAlgorithm()); System.out.println("Key format: "+key.getFormat()); System.out.println("Writing key in binary form to "+outFile); FileOutputStream out = new FileOutputStream(outFile); out.write(key.getEncoded()); out.close(); } catch (Exception e) { e.printStackTrace(); return; } } }
Nesse programa você precisa informar 5 parametros, o primeiro é o nome do keystore, o segundo a senha do keystore, o terceiro seria o nome do certificado (alias dele), o quarto parametro é a senha do certificado e o quinto parametro o nome do arquivo que deverá ser criado para guardar a chave privada.
java DumpKey certificado.jks password certificado password certificado_bin.key Key algorithm: RSA Key format: PKCS#8 Writing key in binary form to certificado.key
Agora você tem a chave privada criada. Agora vamos tentar visualizar o arquivo certificado.key utilizando o OpenSSL. Abaixo o comando para visualizar a chave.
openssl rsa -in certificado_bin.key -text
read RSA key unable to load Key 2228:error:0906D06C:PEM routines:PEM_read_bio:no start line: pem_lib.c:632:Expecting: ANY PRIVATE KEY
Note que houve um erro, aparentemente o OpenSSL entende somente formatos PEM (Privacy Enhanced Mail). Temos então que converter nosso arquivo certificado_bin.key em um arquivo no padrão PEM. Para isso vamos usar o seguinte comando:
openssl enc -in certificado_bin.key -out certificado.key -a
Agora temos nosso arquivo no padrão PEM, utilize o mesmo código que ocorreu erro para verificar se a chave é válida e note que a saida agora será semelhante a:
MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdS ... g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUSVbo98XAZDN9RZoZ+li3kIKVEbk= Agora vamos editar o nosso arquivo certificado.key para inserir o cabeçalho e o rodapé do arquivo de acordo com o exemplo abaixo: -----BEGIN PRIVATE KEY----- MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdS ... g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUSVbo98XAZDN9RZoZ+li3kIKVEbk= -----END PRIVATE KEY-----
Note que foi inserido no começo do arquivo a linha “begin private key” e no final do arquivo a linha “end private key”.
Agora temos nosso arquivo certificado.key convertido para o formato PEM.
A única coisa que falta, neste momento, é transformarmos nosso certificado .cer em um certificado .pfx. De posse do arquivo crt e do arquivo key usaremos o Openssl para converter o arquivo em formato PFX de acordo com a seguinte linha:
openssl pkcs12 -inkey certificado.key -in certificado.crt -export -out certificado.pfx
O código acima diz o seguinte:
Gere uma chave no padrão PKCS12 onde a chave privada (inkey) esta no arquivo certificado.key, onde o certificado (in) esta no arquivo certificado.crt e exporte-o para o arquivo certificado.pfx.
Bom, isso serve caso você não tenha o arquivo PFX que é utilizado para realizar a comunicação com alguns servidores SSL.
Abraços!!!
Muito obrigado Jonas. Tive muitos problemas também. Fica a dica.
Olá Marcus,
parabens pelo artigo, muito bem explicado e com muita informação valiosissima!
Estou com um problema no programa que você colocou no artigo, ao compila-lo apresenta o seguinte erro:
# javac DumpKey.java
DumpKey.java:30: error: ‘)’ expected
if (a.length<5) {
^
DumpKey.java:30: error: not a statement
if (a.length<5) {
^
DumpKey.java:30: error: ‘;’ expected
if (a.length<5) {
^
3 errors
Gostaria de saber se você pode me ajudar.
Adriano,
Provavelmente na classe tem algum erro de compilação. Na linha 30 do arquivo DumpKey.java tem alguma coisa errada. Poderia olhar ele pra ver o que tem de errado? se faltou alguma coisa. Pode ser porque no artigo o < esta como <, tenta substituir pra ver se funciona, algo do tipo ok?
Olá Marcus, muito obrigado pela ajuda, deu certo!!! Desculpe a ignorancia pois sou leigo em Java.
Abraços
Desculpe eu postar o erro denovo pois ficaram sem formatação:
root@optimus-bala:/Box/Certificados/Teste1# javac DumpKey.java
DumpKey.java:30: error: ‘)’ expected
if (a.length<5) {
^
DumpKey.java:30: error: not a statement
if (a.length<5) {
^
DumpKey.java:30: error: ‘;’ expected
if (a.length<5) {
^
3 errors