2014-04-16 28 views
2

我寫一個算法的實現了使用RSA加密和AES加密的公鑰和私鑰加密。在這種方法中,AES密鑰應該使用RSA CipherInputStream進行解密。的Java cipherinputstream關閉所有輸入數據爲0

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是靜態變量,專用密鑰是一個有效的RSA密鑰。

任何幫助發現問題將不勝感激!

+1

@Cyber​​neticTwerkGuruOrc尋找'input.read(aesKey);'。雖然這不是讀取輸入流的方式,當然... –

回答

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. 
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[])方法(其基本上包含相同的代碼如上)。