Java cipherinputstream将所有输入数据转换为0

时间:2014-04-16 15:04:25

标签: java encryption

我正在使用RSA密码和AES密码编写公钥和私钥加密算法的实现。在此方法中,应使用RSA CipherInputStream对AES密钥进行解密。

public void loadKey(File in, byte[] privateKey) throws GeneralSecurityException, IOException {

    PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKey);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PrivateKey pk = kf.generatePrivate(privateKeySpec);
    rsacipher.init(Cipher.DECRYPT_MODE, pk);

    aesKey = new byte[128/8];
    FileInputStream fis = new FileInputStream(in);
    CipherInputStream input = new CipherInputStream(fis, rsacipher);
    input.read(aesKey);
    aesKeySpec = new SecretKeySpec(aesKey, "AES");
    input.close();
    fis.close();
 } 

FileInputStream为我提供了编码密钥(这不是问题)但是当通过CipherInputStream时,数据变为全零。

aesKey和aesKeySpec是静态变量,privateKey是有效的RSA密钥。

非常感谢任何寻找问题的帮助!

2 个答案:

答案 0 :(得分:0)

查看源代码,CipherInputStream可以很好地处理加密层引发的异常。我会完全避免使用简单的Cipher对象,例如

byte[] fileData = FileUtils.readFileToByteArray(in); // from commons-lang
Cipher c = new Cipher("RSA/None/PKCS1Padding");
c.init(Cipher.DECRYPT_MODE, pk);
aesKey = c.doFinal(fileData);
// etc.

答案 1 :(得分:0)

您忽略了InputStream.read(byte[])方法的返回值:

input.read(aesKey);

此调用不保证一次读取等于传递的字节数组长度的字节数。您应该使用一个循环并重复从输入流读取到数组的剩余部分:

int offset = 0;
while (offset < aesKey.length) {
    int read = input.read( aesKey, offset, aesKey.length - offset );
    if (read < 0) {
         throw new EOFException();
    } else {
         offset += read;
    }
}

或者您可以将流包装到DataInputStream并使用DataInputStream.readFully(byte[])方法(基本上包含与上面相同的代码)。