Хэш CMSSignedDataStreamGenerator не совпадает - PullRequest
0 голосов
/ 08 февраля 2010

Я пишу приложение, которое подписывает и конвертирует данные, используя 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();

Я не знаю, что я делаю неправильно.

Ответы [ 2 ]

2 голосов
/ 13 февраля 2010

Я согласен с Расмусом Фабером, цикл чтения / записи хитрый.

Заменить это:

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 голос
/ 09 февраля 2010

Одной из возможных проблем является линия

 is.read(buffer, 0, unitsize);

FileInputStream.read гарантированно будет читать только между 1 и unitsize байтами.

Попробуйте написать

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