Pratica - Criptografia

Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

Redes de Computadores – Unioeste

Prof. Luiz Antonio

Aula Prática 10 - Criptografia1

1. Algoritmos de chave simétrica: DES e AES

public class Pratica10 {

public static void main(String[] args) {


try {
//criptografia simetrica - DES, 3DES e AES
//gerar a chave
KeyGenerator gerador =
KeyGenerator.getInstance("AES");
SecretKey chave = gerador.generateKey();
System.out.println("Chave: "+
Base64.getEncoder().encodeToString(
chave.getEncoded()));

String textoAberto = "the quick brown fox "


+ "jumps over the lazy dog";

//criptografar
Cipher cif = Cipher.getInstance("AES");
cif.init(Cipher.ENCRYPT_MODE, chave);

byte[] buffer = cif.doFinal(textoAberto.getBytes());

System.out.println("Texto aberto : "+


textoAberto.length() + textoAberto);

System.out.println("Texto cifrado: "+


buffer.length +
new String(Base64.getEncoder().encode(buffer)));

cif.init(Cipher.DECRYPT_MODE, chave);
buffer = cif.doFinal(buffer);

System.out.println("Texto recuperado: "+


new String(buffer));

} catch (NoSuchAlgorithmException ex) {


ex.printStackTrace();
} catch (NoSuchPaddingException ex) {
ex.printStackTrace();
} catch (InvalidKeyException ex) {
ex.printStackTrace();
} catch (IllegalBlockSizeException ex) {
ex.printStackTrace();
} catch (BadPaddingException ex) {
ex.printStackTrace();
}
}
}

1 Java Cryptography Architecture (JCA) Reference Guide


(http://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/Crypto
Spec.html)
2. Algoritmos de chave pública e privada
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package pratica10;

import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

/**
*
* @author larodrigues
*/
public class Assimetrica {

public static void main(String[] args) {


try {
KeyPairGenerator gen =
KeyPairGenerator.getInstance("RSA");
KeyPair chave = gen.genKeyPair();
System.out.println("priv: "+chave.getPrivate());
System.out.println("pub : "+chave.getPublic());

String textoAberto = "the quick brown fox "


+ "jumps over the lazy dog";

//criptografar
Cipher cif = Cipher.getInstance("RSA");
cif.init(Cipher.ENCRYPT_MODE, chave.getPrivate());

byte[] buffer = cif.doFinal(textoAberto.getBytes());

System.out.println("Texto aberto : "+


textoAberto.length() + textoAberto);
System.out.println("Texto cifrado: "+
buffer.length +
new String(Base64.getEncoder().encode(buffer)));

cif.init(Cipher.DECRYPT_MODE, chave.getPublic());
buffer = cif.doFinal(buffer);

System.out.println("Texto recuperado: "+


new String(buffer));

} catch (NoSuchAlgorithmException ex) {


ex.printStackTrace();
} catch (NoSuchPaddingException ex) {
ex.printStackTrace();
} catch (InvalidKeyException ex) {
ex.printStackTrace();
} catch (IllegalBlockSizeException ex) {
ex.printStackTrace();
} catch (BadPaddingException ex) {
ex.printStackTrace();
}
}

}
3. Hash MD5 e SHA-1

MD5
● hash de 128 bits = 16 bytes
● muito utilizado por softwares com protocolo P2P, verificação de integridade e logins.

SHA-1 (secure hash algorithm)


● hash de 160 bits = 20 bytes
● É o algoritmo utilizado no eMule para identificar arquivos duplicados.
● Ataque de colisão em 2005 (mesmo hash para 2 entradas distintas), diversas empresas
deixarão de usar a partir de 2017

SHA-256
● hash de 256 bits = 32 bytes
● Faz parte da família SHA-2 (224, 256, 384 ou 512 bits) adotada em 2010
● Usado numa grande variedade de aplicações e protocolos de segurança, incluindo TLS, SSL,
PGP, SSH, S/MIME e IPSec, BitCoin

A API do Message Digest (java.security.MessageDigest)2

Para que se possa gerar textos criptografados, é necessário seguir os seguintes passos.
1. Obter uma instância do algoritmo a ser usado.
2. Passar a informação que se deseja criptografar para o algoritmo.
3. Efetuar a criptografia.

Para se obter uma instância de um algoritmo de criptografia, utiliza-se o método getInstance() da


classe MessageDigest.

MessageDigest md = MessageDigest.getInstance("MD5");
MessageDigest md = MessageDigest.getInstance("SHA-1");
MessageDigest md = MessageDigest.getInstance("SHA-256");

Após a chamada a getInstance(), você possui uma referência a um objeto pronto para
criptografar seus dados utilizando o algoritmo especificado. Neste caso o MD5.

2 https://docs.oracle.com/javase/8/docs/api/java/security/MessageDigest.html
Finalmente, para gerar a chave criptografada, você invoca o método digest().
byte[] digest();
byte[] digest(byte[] input);

import java.security.MessageDigest;
import java.util.Base64;

public class Hash {

public static void main(String args[]) {


Try {
//MD5, SHA-1 SHA-256
MessageDigest md = MessageDigest.getInstance("MD5");

String chave = "The quick brown fox jumps over the lazy dog";
byte[] buffer = md.digest(chave.getBytes());
System.out.println(buffer.length+":
"+Base64.getEncoder().encodeToString(buffer));

String chave2 = "The quick brown fox jumps over the lazy cog";
buffer = md.digest(chave2.getBytes());
System.out.println(buffer.length+":
"+Base64.getEncoder().encodeToString(buffer));

} catch (Exception e) {
e.printStackTrace();
}
}
}

4. Assinaturas Digitais

Assinaturas digitais servem para autenticar o dado sendo transmitido. Junto com o dado, uma
assinatura digital é enviada. Comparada a uma chave pública, a assinatura é validada ou rejeitada.

A assinatura possui duas propriedades:


● Dada a chave pública correspondente a chave privada usada para gerar a assinatura, é
possível verificar a autenticidade e integridade dos dados sendo transmitidos.
● A assinatura e a chave pública nada revelam sobre a chave privada.

A classe responsável no java por gerar as assinaturas digitais é chamada, não coincidentemente, de
Signature3.

Objetos signature são criados atavés da chamada ao método da classe Signature chamado.

static Signature getInstance(String algorithm)


Exemplo: Signature sig = Signature.getInstance("SHA1withDSA");
Outros: SHA1withRSA, SHA256withRSA

A geração das chaves é possível através da classe KeyPairGenerator. Assim como a classe
Signature, a KeyPairGenerator necessita de um algoritmo para gerar as chaves.

static KeyPairGenerator getInstance(String algorithm)


Exemplo: KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA"); //RSA

Note que tanto as chaves quanto a assinatura devem ser geradas utilizando-se o mesmo algoritmo de

3 https://docs.oracle.com/javase/8/docs/api/java/security/Signature.html
criptografia. Após a obtenção de um KeyPairGenerator, devemos inicializa-lo através do método
initialize().

void initialize(int keysize)


void initialize(int keysize, SecureRandom random)

Este método requer dois parâmetros: um tamanho de chave e um número aleatório.

A classe responsável por nos fornecer esse numero aleatório é chamada de SecureRandom. Ela gera
números aleatórios que dificilmente se repetirão. O tamanho da chave deve ser compatível com o
algoritmo sendo usado. no caso do DSA, podemos usar um tamanho de 512, 768 ou 1024.

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");


SecureRandom secRan = new SecureRandom();
keyGen.initialize(512, secRan); //outros 768, 1024
KeyPair keyP = keyGen.generateKeyPair();
PublicKey pubKey = keyP.getPublic();
PrivateKey priKey = keyP.getPrivate();
Após inicializada, a KeyPairGenerator está pronta para gerar nossas chaves pública e privada.

De posse de nossa chave privada, podemos utilizá-la para inicializar nosso objeto signature:

sig.initSign(priKey);

A partir de agora, podemos utilizar o método update() para passar ao algoritmo os dados a serem
criptografados. Após o dado ser fornecido, o método sign() deve ser chamado para geração da
assinatura.
Nota: o método sign reseta o status do algoritmo ao seu estado inicial.
String mensagem = "The quick brown fox jumps over the lazy dog";
//Gerar assinatura
sign.update(mensagem.getBytes());
byte[] assinatura = sign.sign();

Aqui terminam as responsabilidades do remetente. Tudo o que ele precisa fazer agora é fornecer a
chave pública juntamente com o dado a ser enviado e a assinatura correspondente.

O destinatário dos dados sendo enviados deverá receber a assinatura digital e ter acesso a chave
pública. Ele então poderá validar a assinatura junto ao dado recebido utilizando sua chave pública.
Geração de Assinaturas com Chave publica e privada – DSA
public static void main(String args[]) {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
SecureRandom secRan = new SecureRandom();
keyGen.initialize(512, secRan);
KeyPair keyP = keyGen.generateKeyPair();
PublicKey pubKey = keyP.getPublic();
PrivateKey priKey = keyP.getPrivate();
System.out.println("publica: "+pubKey);
System.out.println("privada: "+priKey);
//Obtem algoritmo para geração da assinatura
Signature geradorAss = Signature.getInstance("DSA");

//Inicializar geração
geradorAss.initSign(priKey);
String mensagem = "The quick brown fox jumps over the lazy dog";

//Gerar assinatura
geradorAss.update(mensagem.getBytes());
byte[] assinatura = geradorAss.sign();
//Grava a mensagem num arquivo properties
Properties p = new Properties();
p.put("mensagem", mensagem);
p.put("assinatura", byteArrayToHexString(assinatura));
p.store(new FileOutputStream("dado.properties"), null);

//Serializa a chave pública


ObjectOutputStream oout = new ObjectOutputStream(
new FileOutputStream("pubkey.ser"));
oout.writeObject(pubKey);
oout.close();
}
}

Signature clientSig = Signature.getInstance("DSA");


clientSig.initVerify(pubKey);
clientSig.update(mensagem.getBytes());

if (clientSig.verify(assinatura)) {
//Mensagem assinada corretamente
} else {
//Mensagem não pode ser validada
}

Anexo I – Base64 (Java8 - java.util.Base64)


O princípio da codificação Base64 consiste em utilizar 4 caracteres imprimíveis (no formato EUA-
ASCII) para codificar um grupo de 3 bytes (3*8 bits = 24 bits). Percorrendo os dados binários da esquerda
para a direita, grupos de 24 bits são criados concatenando blocos de 3 dados de 8 bits. Cada grupo de 24 bits
é dividido seguidamente em 4 grupos de 6 bits, correspondente a 4 caracteres do alfabeto Base64.
Os 64 símbolos deste alfabeto são escolhidos para serem universalmente legíveis e para não possuir
significado nos principais protocolos de serviço de mensagens (em especial ol SMTP).
A-Z, a-z, 1-9, +/.
A codificação Base64 foi concebida para dados que formam um múltiplo de 24 bits. Assim, se o volume
dos dados a codificar não formar um múltiplo de 24 bits, o resultado da codificação Base64 deve ser
completado por 0 a 3 caracteres “=” a fim de obter um múltiplo de 24 bits. Este 65º caracter pode assim estar
presente apenas no fim dos dados codificados.

You might also like