我正在编写一个使用BouncyCastle
对数据进行签名和封包的应用程序。
我需要签署大文件,而不是使用CMSSignedDataGenerator
(适用于小文件),我选择使用CMSSignedDataStreamGenerator
。正在生成签名文件,但SHA1
哈希与原始文件不匹配。你能帮帮我吗?
这是代码:
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 :(得分:2)
我同意Rasmus Faber,读/写循环很狡猾。
替换它:
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);
答案 1 :(得分:1)
一个可能的问题是行
is.read(buffer, 0, unitsize);
FileInputStream.read
只保证在 1和unitsize
字节之间读取。
尝试写作
int actuallyRead = is.read(buffer, 0, unitsize);
sigOut.write(buffer, 0, actuallyRead);
read += actuallyRead;