
É uma tema que já estava para postar tem um tempo, desde um trabalho que fiz ano passado na faculdade. Irei abordar a criptografia do tipo RSA, mas o procedimento é o mesmo para os demais tipos de criptografia assimétrica, mudando só logicamente a identificação de qual criptografia estamos trabalhando. Temos que ter em mente a classe KeyPairGenerator, que irá gerar uma instância de KeyPair que é a representação de um par de chaves (uma privada e uma pública). Do KeyPair podemos extrair a instância de PrivateKey e a instância de PublicKey, que no caso nem preciso explicar quem são.
Vamos começar então criando a instância de KeyPair através do KeyPairGenerator.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); | |
generator.initialize(512); | |
KeyPair keyPair = generator.generateKeyPair(); |
Esse código exemplifica como criar um par de chaves (Privada e Pública) para criptografia do tipo RSA. Perceba que criamos um gerador de par de chaves do tipo “RSA” (poderíamos usar por exemplo o “DH”) e inicializarmos esse gerador com 512, que significa que o tamanho de nossas chave será de 512 bits, o mínimo para esse tipo de criptografia. Logo após isso, temos o comando onde o gerador criar uma instância de KeyPair ou par de chaves.
Mas como capturo a chave pública e privada de uma instância de KeyPair? Simples:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PrivateKey privateKey = keyPair.getPrivate(); | |
PublicKey publicKey = keyPair.getPublic(); |
O próximo passo é capturar a instância de Cipher, que irá realizar a criptografia e decriptografia do que quisermos. A captura de Cipher é muito similar a do KeyPairGenerator, já que ambos são singleton:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Cipher cipher = Cipher.getInstance("RSA"); |
Novamente, poderíamos usar por exemplo o “DH” ao invés de “RSA”. Logo em seguida, se quisermos fazer uma criptografia inicializaremos o Cipher informando o modo Cipher.ENCRYPT_MODE e a nossa instância de PublicKey. Se formos realizar o procedimento inverso, decriptografia, informaremos o modo Cipher.DECRYPT_MODE e a instância de nossa PrivateKey.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cipher.init(Cipher.ENCRYPT_MODE, publicKey); | |
cipher.init(Cipher.DECRYPT_MODE, privateKey); |
Para realizar o modo que informamos, criptografar ou decriptografar, basta chamarmos o método doFinal() da instância de Cipher, que recebe um vetor de bytes e retorna um vetor de bytes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
String criptografado = new String(cipher.doFinal("Tássio Auad".getBytes())); | |
String decriptografado = new String(cipher.doFinal(criptografado .getBytes())); |
Segue abaixo uma classe completa para se trabalhar com criptografia RSA, usando as linhas de código explicadas acima.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class RsaCipher { | |
private PublicKey publicKey; | |
private PrivateKey privateKey; | |
public RsaCipher(PublicKey publicKey, PrivateKey privateKey) { | |
this.publicKey = publicKey; | |
this.privateKey = privateKey; | |
} | |
public static KeyPair genKeyPair() throws NoSuchAlgorithmException { | |
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); | |
generator.initialize(512); | |
KeyPair keyPair = generator.generateKeyPair(); | |
return keyPair; | |
} | |
public String encrypt(String string) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException { | |
Cipher cipher = Cipher.getInstance("RSA"); | |
cipher.init(Cipher.ENCRYPT_MODE, publicKey); | |
return new String(cipher.doFinal(string.getBytes())); | |
} | |
public String decrypt(String string) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IOException, BadPaddingException, IllegalBlockSizeException { | |
Cipher cipher = Cipher.getInstance("RSA"); | |
cipher.init(Cipher.DECRYPT_MODE, privateKey); | |
return new String(cipher.doFinal(string.getBytes())); | |
} | |
} |