2010-02-08 91 views
0

我正在編寫一個應用程序,使用BouncyCastle簽署和信封數據。CMSSignedDataStreamGenerator散列不匹配

我需要簽署大文件,而不是使用CMSSignedDataGenerator(對小文件工作正常),我選擇使用CMSSignedDataStreamGenerator。正在生成簽名文件,但SHA1散列與原始文件不匹配。你可以幫幫我嗎?

Here`s代碼:

try { 

     int buff = 16384; 
     byte[] buffer = new byte[buff]; 
     int unitsize = 0; 
     long read = 0; 
     long offset = file.length(); 
     FileInputStream is = new FileInputStream(file); 
     FileOutputStream bOut = new FileOutputStream("teste.p7s"); 
     Certificate cert = keyStore.getCertificate(alias); 
     PrivateKey key = (PrivateKey) keyStore.getKey(alias, null); 
     Certificate[] chain = keyStore.getCertificateChain(alias); 
     CertStore certStore = CertStore.getInstance("Collection",new CollectionCertStoreParameters(Arrays.asList(chain))); 
     CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); 
     gen.addSigner(key, (X509Certificate) cert, CMSSignedDataGenerator.DIGEST_SHA1, "SunPKCS11-iKey2032"); 
     gen.addCertificatesAndCRLs(certStore); 
     OutputStream sigOut = gen.open(bOut,true); 

     while (read < offset) { 
      unitsize = (int) (((offset - read) >= buff) ? buff : (offset - read)); 
      is.read(buffer, 0, unitsize); 
      sigOut.write(buffer); 
      read += unitsize; 
     } 
     sigOut.close(); 
     bOut.close(); 
     is.close(); 

我不知道我做錯了。

+0

設置緩衝區,以1似乎工作。我認爲它正在處理最後一次緩衝區迭代中的0或空值。有沒有其他解決方法? – Paulo 2010-02-08 18:31:25

回答

1

一個可能的問題是線

is.read(buffer, 0, unitsize); 

FileInputStream.read只保證讀 1和unitsize之間字節。

試着寫

int actuallyRead = is.read(buffer, 0, unitsize); 
sigOut.write(buffer, 0, actuallyRead); 
read += actuallyRead; 
2

我拉斯穆斯·法伯同意,讀/寫循環是不可靠的。

替換此:

while (read < offset) { 
    unitsize = (int) (((offset - read) >= buff) ? buff : (offset - read)); 
    is.read(buffer, 0, unitsize); 
    sigOut.write(buffer); 
    read += unitsize; 
} 

有:

org.bouncycastle.util.io.Streams.pipeAll(is, sigOut);