não descriptografar o que eu crypted

Tenho um problema estranho...

Baseando minha solução emDescriptografar um arquivo codificado como byte []

Então, eu escrevi uma pequena classe Cypher para ajudar com crypting / decrypting ... Ela costumava fazer mock-up de uma chave codificada em algum lugar e outra chave pré-criptografada armazenada em algum outro lugar. Mas isso é um pouco irrelevante.

o processo crypting foi assim:

recuperar a matriz de bytes codificadosusá-lo para descriptografar key2use key2 para descriptografar dadosusar key1 para descriptografar mais dadoster dados descriptografados

Eu estava armazenando os dados criptografados como uma string hexagonal, usei essas duas funções para entrar e sair de lá

private static String byteArrayToHexString(byte[] b)
{
    StringBuffer sb = new StringBuffer(b.length * 2);
    for (int i = 0; i < b.length; i++)
    {
        int v = b[i] & 0xff;
        if (v < 16)
        {
            sb.append('0');
        }
        sb.append(Integer.toHexString(v));
    }
    return sb.toString().toUpperCase();
}

private static byte[] hexStringToByteArray(String s)
{
    byte[] b = new byte[s.length() / 2];
    for (int i = 0; i < b.length; i++)
    {
        int index = i * 2;
        int v = Integer.parseInt(s.substring(index, index + 2), 16); //THIS LINE
        b[i] = (byte) v;
    }
    return b;
}

Isso funcionou sem falhas; na verdade, funcionou tão bem que o implementei no meu projeto real. O projeto não foi executado devido ao fato de que eu não testei completamente.

Acontece que crypts / descriptografa praticamente todos os arquivos OK, exceto um - que não quer descriptografar.

Eu apontei o problema no entanto - esta linha lança uma exceção IllegalNumberFormat; em algum momento eu me familiarizei com estehttp://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6259307 também. Eu poderia e poderia reverter para esse método se alguém descrever uma maneira de ignorar um caso quando uma cadeia de comprimento 2 é convertida em quatro bytes que lançam um IllegalNumberFormatException.

Então, percebi que, como não consigo decodificar um arquivo (e obviamente não posso compartilhá-lo aqui para vocês testarem), eu precisava transformá-lo de alguma forma para torná-lo seguro para o transporte. Digite a classe Base64Coder que codifica para strings base64 ...

Isso parecia ter introduzido uma nova questão - o preenchimento estava sendo prejudicado.

A questão é simples - o que estou fazendo errado? Eu preciso estar em conformidade com esses dados e tem que ser capaz de criptografar / descriptografar de forma adequada e igualmente. Eu gostaria de uma proposta sobre a solução mais leve possível com menos copiar / colar ... pseudocódigo não vai fazer o truque aqui.

Aqui está o que estou fazendo agora ....

public static char[] encrypt2(byte[] value) throws GeneralSecurityException, IOException
{
    SecretKeySpec key1 = getSecretKeySpec(true);
    System.err.println("encrypt():\t" + key1.toString());
    Cipher cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.ENCRYPT_MODE, key1, cipher.getParameters());
    byte[] encrypted = cipher.doFinal(value);

    SecretKeySpec key2 = getSecretKeySpec(false);
    cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.ENCRYPT_MODE, key2, cipher.getParameters());
    byte[] encrypted2 = cipher.doFinal(encrypted);

    return Base64Coder.encode(encrypted2);
}

public static byte[] decrypt2(char[] message) throws GeneralSecurityException, IOException
{
    SecretKeySpec key1 = getSecretKeySpec(false);
    System.err.println("decrypt():\t" + key1.toString());
    Cipher cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.DECRYPT_MODE, key1);
    byte[] decrypted = cipher.doFinal(Base64Coder.decode(message));

    SecretKeySpec key2 = getSecretKeySpec(true);
    cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.DECRYPT_MODE, key2);
    byte[] decrypted2 = cipher.doFinal(decrypted);

    return decrypted2;
}

Observe que as chaves estão totalmente expostas (codificadas) para fins de teste.

Aqui está o meu caso de teste

public static void main(String... args) throws Exception
{
    //      byte[] data = "hello".getBytes();
    File PEM = new File(PATH_TO_FILES + SOURCE_PEM);
    File DER = new File(PATH_TO_FILES + SOURCE_DER);
    File cryptoPEM = new File(PATH_TO_FILES + "cryptopem");
    File cryptoDER = new File(PATH_TO_FILES + "cryptoder");

    byte[] cryptokey = encryptA(ASSET_KEY);
    System.out.println(new String(cryptokey));

    //pem key
    System.out.println("PEM");
    byte[] data = getBytesFromFile(PEM);
    char[] crypted = encrypt2(data);
    //      FileOutputStream fos = new FileOutputStream(cryptoPEM);
    FileWriter fw = new FileWriter(cryptoPEM);
    fw.write(crypted);
    fw.flush();

    //der key
    System.out.println("DER");
    data = getBytesFromFile(DER);
    crypted = encrypt2(data);
    fw = new FileWriter(cryptoDER);
    fw.write(crypted);
    fw.flush();

    //opentext
    System.out.println("checking PEM...");
    crypted = Base64Coder.encode(getBytesFromFile(cryptoPEM));
    byte[] decrypted = decrypt2(crypted,  false);
    byte[] decryptedData = decrypted;

    if (!Arrays.equals(getBytesFromFile(PEM), decryptedData)) { throw new Exception("PEM Data was not decrypted successfully"); }

    System.out.println("checking DER...");
    crypted = Base64Coder.encode(getBytesFromFile(cryptoDER));
    decrypted = decrypt2(crypted,  false);
    decryptedData = decrypted;

    if (!Arrays.equals(getBytesFromFile(DER), decryptedData)) { throw new Exception("DER Data was not decrypted successfully"); }
}

E eu estou recebendo um InvalidBlockSizeException agora .... Por favor, alguém lançar alguma luz sobre isso, eu só quero que isso funcione ...

Substituir 'key2' por um IV para ser usado posteriormente em um "AES / CBC / PKCS5Padding" é uma opção que estou considerando no momento. Essencialmente nada vai mudar, exceto o segundo passo da criptografia. Teórica e metodicamente, eu manteria as coisas iguais - a menos que uma solução melhor fosse descrita.

No final, gostaria de salientar que se trata de uma questão de programador, e não de uma questão de estudante de segurança de TI, de modo que o código adequado é mais valorizado do que uma resposta teórica que cobre casos marginais improváveis.

EDIT: bem, eu não posso dar-lhe os números que causam o IllegalNumberFormatException porque eu perdi o código a partir desta manhã. Eu não consigo replicar o problema, então acho que tentar entender essa parte é inútil.

Aqui está a saída do teste de amostra:

encrypt():  javax.crypto.spec.SecretKeySpec@15dd7
5@��_׵G�j��!�c;D�i�lR?z�j\
PEM
encrypt():  javax.crypto.spec.SecretKeySpec@15dd7
DER
encrypt():  javax.crypto.spec.SecretKeySpec@15dd7
checking PEM...
decrypt():  javax.crypto.spec.SecretKeySpec@15c78
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher

o que significa que o Base64 está meio bagunçado ...

questionAnswers(3)

yourAnswerToTheQuestion