Dúvidas sobre criptografia

Seguinte pessoal, não estou conseguindo descriptografar textos que foram criptografados em modos diferentes de ECB. Para quem não sabe há varios modos de criptografia, são eles: ECB, CBC, CFB, OFB e PCBC. Até é possível o java criptografar em qualquer modo, mas pra descriptografar não dá… só em ECB. Queria saber o pq disso já que é pra um trabalho da facul que estaria terminado se não fosse por esse detalhe. Bom aí vai o código do descriptografar:

public Object descriptografar(Key chaveFinal, String textoHexa, String algoritmo, String padding, String modo) throws NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidParameterException
{
janelaPrincipal.addTextoLog(“Descriptografando dados…”);

byte[] byteTexto = hexaParaByte(textoHexa);

Key chave = chaveFinal;

Cipher cifra = Cipher.getInstance(algoritmo + “/” + modo + “/” + padding);
cifra.init(Cipher.DECRYPT_MODE, chave);

byte[] byteFinal = cifra.doFinal(byteTexto);

ResultadoDescriptografar objResultado = new ResultadoDescriptografar(new String(byteFinal));

return objResultado;
}

public static byte[] hexaParaByte(String h) throws IllegalArgumentException
{
if (h.length() % 2 != 0)
{
throw new IllegalArgumentException();
}

byte[] b = new byte[h.length() / 2];

int j = 0;

for (int i = 0; i < h.length(); i += 2)
{
String doisChar = h.substring(i, i + 2);
b[j] = Integer.decode(“0x” + doisChar).byteValue();
j++;
}

return b;
}

Bom, valeu desde já.

Olá

Qual o padding que está passando para cada DES operating mode? PKCS#5?

Para rememorar aos demais vou recapitular o q são os modos DES

O que vai encriptar?
    :arrow: audio ou video -> use OFB

    Precisa encriptar um byte de cada vez?
       :arrow: Sim -> use CFB8

       Precisa desencriptar alguns blocos independentes dos outros>?
          :arrow: Sim -> use ECB

          Quer garantia que um simples erro cause erro em todo o resto do processo?
             :arrow: Sim -> use PCBC
             :arrow: Não -> use CBC

[]s
Luca

Sim, estou usando o padding PCKS5Padding mesmo, aliás, andei dando uma procurada na net e achei outros dois modos SSL3 e OAEP mas não consequi implementá-los? Então fica outra dúvida… Mas valeu

Aham, por exemplo, quando você tem o modo CBC, você precisa passar na hora de criptografar e na hora de decifrar o vetor de inicialização, ou IV.

Veja o javadoc de javax.crypto.spec.IvParameterSpec, java.security.spec.AlgorithmParameterSpec e java.security.AlgorithmParameters entre outros.

Outras coisas podem estar acontecendo com os outros modos, é questão de especificar corretamente os parâmetros para cada modo.

mas então, pq usando o modo ECB isso não é necessário? vou dar uma olhada nessas classes

Porque o modo ECB não requer o vetor de inicialização (IV).

bom, poderias me mostrar um exmeplo de implementação? nunca mexi com o AlgorithmParameterSpec…

A minha preguiça mata, porque achei um exemplo de IvParameterSpec e modo CBC em

http://www.javaalmanac.com/egs/javax.crypto/DesFile.html

em vez de fazer um (e acrescentar à minha coleção de exemplinhos que costumo fazer…)

mas assim, como eu crio um vetor de inicialização? que bytes eu devo especificar? sempre os mesmos? pros outros modos o exemplo é análogo?

bom, valeu por tudo desde já

Vamos lá.
A primeira coisa é que seria interessante, antes de mais nada, ver se você pode ler alguma coisa sobre criptografia em geral (existe o tutorial da RSA Labs em www.rsasecurity.com/rsalabs se não me engano, ou então peça emprestado para alguém (ou compre se você quiser gastar dinheiro) o livro “Enterprise Java Security”, que de quebra ensina um monte de coisa sobre criptografia Java.
Além disso existe um livro que é o “Applied Cryptography” de Bruce Schneier, que é obrigatório para qualquer um que queira entender criptografia (não, não é orientado para Java).
A segunda coisa é que o vetor de inicialização é um fator de segurança que foi adicionado ao modo CBC para que um mesmo dado, criptografado duas vezes, dê dois resultados diferentes. Normalmente é um valor aleatório, transmitido “em claro” (ou seja, você deve transmitir para o destinatário da mensagem criptografada o valor do IV, juntamente com os bytes criptografados).
Às vezes algumas aplicações fixam o valor do IV como zero, mas isso torna o modo menos seguro.

Olá

Dei uma googlada para complementar as ótimas respostas do thingol:

Livro onde aprendi criptografia com Java (já sabia sem Java, mas este livro ensina tudo)
Java Security Handbook

Melhor livro que conheço sobre criptografia em geral (leitura facil sem entrar em fórmulas como o Applied Cryptography que é todo matemático):
Practical Cryptography

2 capítulos do ótimo livro que o thingol indicou:
Enterprise Java Security Fundamentals
The Theory of Cryptography

tutorial em espanhol sobre JCA, Java Criptography Architecture
Tutorial sobre JCA.

Capítulo 6 do livro Java Cryptography (bem antigo) do Knudsen
Authentication

[]s
Luca

entao, se eu setar o valor do IV como zero, eu não precisaria salvar por exemplo a chave num arquivo pra descriptografar?

É. Existem alguns protocolos que fazem exatamente isso (setam o IV para zero). Como disse, não é muito seguro, mas pode ser usado.

Aproveitando esse tópico, estou realmente precisando de um help com criptografia … se alguém ai puder ajudar meu problema está postado aqui: http://www.escribe.com/software/crypto/m4047.html

Em tempo … é em C e num tem nada a ver com java :oops: , mas to precisando muito de ajuda :cry:

thanks

Olá

DES modo CBC

Encriptação:

  • O primeiro bloco de 8 bytes de texto (P1) é posto em XOR contra um vetor de inicialização (IV) (dados pseudo randômicos) e então encriptado para produzir o primeiro bloco de 8 bytes criptografado (C1)

(P1 ) XOR (IV) --> DES --> (C1)

  • Cada bloco de texto criptografado (Cn) que é produzido é posto em XOR com o próximo bloco de 8 bytes de texto (Pn+1) e então é encriptado para produir o próximo bloco de texto criptografado (Cn+1)

(P2) XOR (C1) --> DES–> (C2)
(P3) XOR (C2) --> DES–> (C3)
. . . . . . . . . . . . . . . . . .
(Pn+1) XOR (Cn) --> DES–> (Cn+1)

No bloco final o padding PKCS#5 pode ser usado igualzzinho ao modo ECB mas outras técnicas podem ser usadas para produir texto criptografado com o mesmo tamanho que o texto aberto.

Desencriptação:

  • O primeiro bloco de 8 bytes de texto criptografado (C1) é desencriptado e então posto em XOR contra o mesmo vetor vetor de inicialização da encriptação (IV) para produzir o primeiro bloco de 8 bytes descriptografado (P1)

(C1 ) --> DES XOR (IV) --> (P1)
(C2 ) --> DES XOR (C1) --> (P2)
(C3 ) --> DES XOR (C2) --> (P3)
. . . . . . . . . . . . . . . . . . . . . . . . …
(Cn+1 ) --> DES XOR (Cn) --> (Pn+1)

Para inicializar Cipher com um IV
javax.crypto.spec.IVParameterSpec encapsula um vetor de inicialização no JCE. Para construir um em um byte array use new em IVParameterSpec

Para criar os bytes para o IV devemos usar java.security.secureRandom para gerar um byte array equivalente ao tamanho do bloco do Cipher que estamos usando (DES = 8 bytes)

byte[] randomBytes = new byte[8];
SecureRandom random = new secureRandom();  
// SecureRandom é bem lento, o cryptix usa pseudo randômicos e é bem mais rápido
random.nextBytes(randomBytes);

IVParameterSpec iv = new IVParameterSpec(randomBytes);

Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
. . . . . .

O mesmo IV precisa ser usado ao desencriptar. O macete é colocar o IV no início do texto cifrado (8 bytes no caso do DES).

[]s
Luca