简体   繁体   English

Java cipherinputstream将所有输入数据都设为0

[英]Java cipherinputstream turns all input data to 0

I am writing an implementation of an algorithm for public and private key encryption using an RSA cipher and an AES cipher. 我正在编写一个使用RSA密码和AES密码的公用和专用密钥加密算法的实现。 In this method, the AES key is supposed to be deciphered by using an RSA CipherInputStream. 在这种方法中,应该使用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();
 } 

the FileInputStream gives me the encoded key (it is not the problem) but when passed through the CipherInputStream, the data becomes all zeroes. FileInputStream给了我编码密钥(这不是问题),但是当通过CipherInputStream传递时,数据变为全零。

aesKey and aesKeySpec are static variables, privateKey is a valid RSA key. aesKey和aesKeySpec是静态变量,privateKey是有效的RSA密钥。

Any help in finding the problem would be much appreciated! 任何发现问题的帮助将不胜感激!

Looking at the source, CipherInputStream does a great job of eating exceptions thrown by the crypto layer. 从源头CipherInputStreamCipherInputStream可以很好CipherInputStream加密层引发的异常。 I would avoid its use entirely in favour of a simple Cipher object, eg 我会完全避免使用它来支持简单的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.

You are ignoring the return value of the InputStream.read(byte[]) method: 您将忽略InputStream.read(byte[])方法的返回值:

input.read(aesKey);

This call is not guaranteed to read the number of bytes equal to the length of the passed byte array in one go. 不能保证此调用一次性读取等于传递的字节数组长度的字节数。 You should use a cycle and repeatedly read from the input stream into the remaining part of the array: 您应该使用一个循环,并从输入流中反复读取到数组的其余部分:

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;
    }
}

Or you can wrap the stream into DataInputStream and use DataInputStream.readFully(byte[]) method (which essentially contains the same code as above). 或者,您可以将流包装到DataInputStream并使用DataInputStream.readFully(byte[])方法(该方法实质上包含与上述相同的代码)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM