在Java中使用CipherOutputStream

时间:2011-10-05 03:04:09

标签: java jce encryption

我正在尝试使用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);
    }
}

1 个答案:

答案 0 :(得分:2)

引起我注意的第一件事是这一行:

aesCipher.getInstance( “AES / CBC / PKCS5Padding”);

假设aesCipherCipher类型的变量,您在这里调用静态Cipher.getInstance并丢弃结果(不将其分配给任何变量)。即此行完全没有效果,aesCipher与此行之前相同。

如果它之前是null,那么它仍然是null,下一行(调用非静态方法)会给你一个NullPointerException。如果您的代码默默地吞噬未知异常(这可能超出了所显示的代码),这是一个普遍的问题。

除此之外,我认为CipherOutputStream上的flush并没有真正刷新整个缓冲区,而只是可以在不添加任何填充的情况下写入多少块。在这里使用close()代替flush()(这似乎也适用于第二个示例)。


一般性评论:small self-contained complete compilable example会让我尝试并给你一个明确的答案,而不仅仅是猜测。例如,“不返回任何内容”不是对方法行为的良好描述 - 方法是返回null,空数组,抛出异常,是否永远阻塞?