1

一部のバイトを暗号化するために AES 暗号を使用しようとしていますが、サイレント エラーが返されます。つまり、次のように入力します。

byte[] raw = new String("Test","UTF8").getBytes("UTF8");

何も返されません。問題はByteArrayInput/OutputStreamsだと思いますが、他の方法でそれを行う方法がわかりません..

これが問題のコードです。

public byte[] encrypt(byte[] in) {
    byte[] encrypted = null;
    try {
        aesCipher.getInstance("AES/CBC/PKCS5Padding");
        aesCipher.init(Cipher.ENCRYPT_MODE, aeskeySpec);
        ByteArrayInputStream bais = new ByteArrayInputStream(in);
        ByteArrayOutputStream baos = new ByteArrayOutputStream(bais.available());
        CipherOutputStream os = new CipherOutputStream(baos, aesCipher);
        copy(bais, os);
        os.flush();
        byte[] raw = baos.toByteArray();
        os.close();
        encrypted = Base64.encodeBase64(raw);

    } catch (FileNotFoundException ex) {
        Logger.getLogger(FileEncryption.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(FileEncryption.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(FileEncryption.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(FileEncryption.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(FileEncryption.class.getName()).log(Level.SEVERE, null, ex);
    }
    return encrypted;
}

同じクラスで機能する別の関数を次に示します。

public void encrypt(File in, File out) {


    try {
        aesCipher.getInstance("AES/CBC/PKCS5Padding");
        aesCipher.init(Cipher.ENCRYPT_MODE, aeskeySpec);
        FileInputStream is;
        is = new FileInputStream(in);
        CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out), aesCipher);
        copy(is, os);
        os.close();
    } catch (FileNotFoundException ex) {
        Logger.getLogger(FileEncryption.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(FileEncryption.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(FileEncryption.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(FileEncryption.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(FileEncryption.class.getName()).log(Level.SEVERE, null, ex);
    }

}

private void copy(InputStream is, OutputStream os) throws IOException {
    int i;
    byte[] b = new byte[2048];
    while ((i = is.read(b)) != -1) {
        os.write(b, 0, i);
    }
}
4

1 に答える 1

2

最初に私の目を引くのは、次の行です。

aesCipher.getInstance("AES/CBC/PKCS5Padding");

aesCipherが type の変数であると仮定すると、Cipherここで static を呼び出しCipher.getInstance、結果を破棄します (変数に割り当てません)。つまり、この行はまったく効果がなく、aesCipherこの行の前と同じです。

null以前だった場合はそのままでnull、次の行 (非静的メソッドを呼び出す) で NullPointerException が返されます。コードが不明な例外を黙って飲み込んでいる場合 (これは表示されているコードの外にある可能性があります)、これは一般的な問題です。

これ以外flushに、CipherOutputStream の は実際にはバッファー全体をフラッシュするのではなく、パディングを追加せずに書き込むことができるブロックの数だけをフラッシュすると思います。close()hereの代わりに使用しflush()ます (2 番目の例でも機能しているようです)。


総評:小さな自己完結型の完全なコンパイル可能な例があれば、推測だけでなく、それを試して明確な答えを得ることができたでしょう。たとえば、「何も返さない」は、メソッドの動作を説明するのに適していません。メソッドはnull、空の配列を返したり、例外をスローしたり、永久にブロックしたりしますか?

于 2011-10-06T10:17:32.473 に答える