Подписание PDF-документа с внешним дайджестом [дубликат]

Это все еще не автоматическое, так как я хочу, чтобы была опция - и должна быть какая-то проверка, чтобы убедиться, что это может произойти только для быстрых обновлений (поэтому вручную делать притяжение намного безопаснее! !), но предостережения в стороне вы можете:

git fetch origin
git update-ref refs/heads/other-branch origin/other-branch

обновить позицию вашего локального отделения, не проверяя его.

Примечание: вы потеряете свою текущую ветку положение и перемещение его туда, где находится ветвь происхождения, а это означает, что если вам нужно слить, вы потеряете данные!

17
задан Greenhand 24 October 2015 в 06:20
поделиться

1 ответ

Разница

Разница между подписанием с "SHA256withRSA" и вычислением хэша SHA256 и его подписанием с "RSA" (= "NONEwithRSA") заключается прежде всего в том, что в первом случае вычисленный SHA-256 хеш-значение сначала инкапсулируется в структуру DigestInfo

DigestInfo ::= SEQUENCE {
    digestAlgorithm DigestAlgorithm,
    digest OCTET STRING
}

перед заполнением, а затем зашифровывается, в то время как в последнем случае хеш-значение голого SHA256 дополняется и зашифровывается.

Если они разные, существует ли способ изменить метод 2, чтобы оба метода выдавали один и тот же результат?

Прежде всего вам нужно инкапсулировать хеш-значение в DigestInfo перед подписанием с использованием "NONEwithRSA".

RFC 3447 Раздел 9.2 помогает здесь, указав в примечании 1, что

1. For the six hash functions mentioned in Appendix B.1, the DER
   encoding T of the DigestInfo value is equal to the following:
   ...
   SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00
                04 20 || H.

Задание его работы

В ответ на раздел над ОП обновил свой вопрос с обновленным кодом. К сожалению, он еще не работал для него. Таким образом,

Код OP

Я выполнил код OP ( SignInSteps.java ). Поскольку он не предоставлял секретный ключ, я использовал тестовый ключ моего ( demo-rsa2048.p12 ). Результат:

GreenhandOriginal:
1B9557B6A076226FA4C26A9370A0E9E91B627F14204D427B03294EC4BFC346FDEEFB3A483B1E5A0593F26E9DE87F9202E1064F4D75B24B8FA355B23A560AF263361BB94B2339C3A01952C447CAC862AA9DCAB64B09ABAA0AD50232CDB299D1E4B5F7138F448A87ED32BFF4B5B66F35FFA08F13FD98DFCEC7114710282E463245311DA7A56CBEA958D88137A8B507D8601464535978EFE36EE37EF721260DB7112484F244409F0BD64C823ACFB13D06ABA84A9A0C5AB207E19231D6A71CC80F07FDA2A9654F0F609C2C3396D6DFFBBB10EF4C3D4B5ADFC72EACC044E81F252B699F095CFEF8630B284B1F6BD7201367BD5FDF2BB4C20BD07B9CC20B214D86C729
4B9ECA6DD47C1B230D972E7DA026165F1CE743EC96825E4C13DFE2C6437FE673A13CA622047EE7D2F7C5280198D81550A1CBD17F8E8A3C4C2D53A746FA6464AA5194FC2782527B014F017008D89BB2C80B7FA367C74FE01369986B56BCE7DC573A11ED884511F0CB12160CA5E42D488451AA8961BF5A9F71E6A5E89F19BC8EFAC26DDE989A0369667EE74372F6E558887FE2561EA926B441AB8F0FD3DEDD608A671011313372084B059CAD7E4807AC852C0873C57F216349422771C089678BAC3021D054C4427EADE70219E251617B83E68640DD7D03C3F99E47F79EB71C124F59EDEA724496A4552F2E9E1F90DDE550745E85483D823F146982C6D2008FE9AA

GreenhandUpdated:
method 1: 4B9ECA6DD47C1B230D972E7DA026165F1CE743EC96825E4C13DFE2C6437FE673A13CA622047EE7D2F7C5280198D81550A1CBD17F8E8A3C4C2D53A746FA6464AA5194FC2782527B014F017008D89BB2C80B7FA367C74FE01369986B56BCE7DC573A11ED884511F0CB12160CA5E42D488451AA8961BF5A9F71E6A5E89F19BC8EFAC26DDE989A0369667EE74372F6E558887FE2561EA926B441AB8F0FD3DEDD608A671011313372084B059CAD7E4807AC852C0873C57F216349422771C089678BAC3021D054C4427EADE70219E251617B83E68640DD7D03C3F99E47F79EB71C124F59EDEA724496A4552F2E9E1F90DDE550745E85483D823F146982C6D2008FE9AA
method 2: 4B9ECA6DD47C1B230D972E7DA026165F1CE743EC96825E4C13DFE2C6437FE673A13CA622047EE7D2F7C5280198D81550A1CBD17F8E8A3C4C2D53A746FA6464AA5194FC2782527B014F017008D89BB2C80B7FA367C74FE01369986B56BCE7DC573A11ED884511F0CB12160CA5E42D488451AA8961BF5A9F71E6A5E89F19BC8EFAC26DDE989A0369667EE74372F6E558887FE2561EA926B441AB8F0FD3DEDD608A671011313372084B059CAD7E4807AC852C0873C57F216349422771C089678BAC3021D054C4427EADE70219E251617B83E68640DD7D03C3F99E47F79EB71C124F59EDEA724496A4552F2E9E1F90DDE550745E85483D823F146982C6D2008FE9AA

Таким образом, в отличие от наблюдений OP, сигнатуры равны в случае обновленного кода.

Не допуская ошибок копирования и вставки, все равно могут быть другие

Окружающая среда

Я тестировал с использованием Java 8 (1.8.0_20) с добавленными неограниченными файлами полномочий и BouncyCastle 1.52, 1.49 и 1.46 (с небольшой модификацией тестового кода из-за к изменениям API BC).

OP упомянут в комментарии:

Java - это обновление JRE 8 66. BouncyCastle - bcprov-jdk15on-153.jar.

Таким образом, я обновил Java, до сих пор нет разницы.

Затем я обновил BouncyCastle до 1.53. И действительно, неожиданно результаты различались:

GreenhandOriginal:
1B9557B6A076226FA4C26A9370A0E9E91B627F14204D427B03294EC4BFC346FDEEFB3A483B1E5A0593F26E9DE87F9202E1064F4D75B24B8FA355B23A560AF263361BB94B2339C3A01952C447CAC862AA9DCAB64B09ABAA0AD50232CDB299D1E4B5F7138F448A87ED32BFF4B5B66F35FFA08F13FD98DFCEC7114710282E463245311DA7A56CBEA958D88137A8B507D8601464535978EFE36EE37EF721260DB7112484F244409F0BD64C823ACFB13D06ABA84A9A0C5AB207E19231D6A71CC80F07FDA2A9654F0F609C2C3396D6DFFBBB10EF4C3D4B5ADFC72EACC044E81F252B699F095CFEF8630B284B1F6BD7201367BD5FDF2BB4C20BD07B9CC20B214D86C729
4B9ECA6DD47C1B230D972E7DA026165F1CE743EC96825E4C13DFE2C6437FE673A13CA622047EE7D2F7C5280198D81550A1CBD17F8E8A3C4C2D53A746FA6464AA5194FC2782527B014F017008D89BB2C80B7FA367C74FE01369986B56BCE7DC573A11ED884511F0CB12160CA5E42D488451AA8961BF5A9F71E6A5E89F19BC8EFAC26DDE989A0369667EE74372F6E558887FE2561EA926B441AB8F0FD3DEDD608A671011313372084B059CAD7E4807AC852C0873C57F216349422771C089678BAC3021D054C4427EADE70219E251617B83E68640DD7D03C3F99E47F79EB71C124F59EDEA724496A4552F2E9E1F90DDE550745E85483D823F146982C6D2008FE9AA

GreenhandUpdated:
method 1: 6BAAAC1060B6D0D56AD7D45A1BEECE82391088FF47A8D8179EFBBEB0925C4AC6C9DFC56F672E99F4A6E3C106A866B70513C25AE11B267286C584A136FBC20C4D1E7B10697352DF020BA5D67029A6EF890B2674F02C496CB1F1EBB0D4DBB580EB045DBB0FA0D7D73B418FF63F345658C6C73DA742FE260C9639C94967A928F74F61DACA03310B9986C32D83CAB8C7FC13E80612CCFC0B7E3E35BEA04EAEBDAA55FB8837B4661DC71499B4A0B1D36E1D23D9927CDB55C237D5AB2E5C088F29C6FAFAD9FE64DD4851CEC113560864E9923D485D0C6E092C8EBE82D29C312E5835B38EE9BD6B8B4BCC753EF4EE4D0977B2E781B391839E3EC31C36E5B1AA0CE90227
method 2: 4B9ECA6DD47C1B230D972E7DA026165F1CE743EC96825E4C13DFE2C6437FE673A13CA622047EE7D2F7C5280198D81550A1CBD17F8E8A3C4C2D53A746FA6464AA5194FC2782527B014F017008D89BB2C80B7FA367C74FE01369986B56BCE7DC573A11ED884511F0CB12160CA5E42D488451AA8961BF5A9F71E6A5E89F19BC8EFAC26DDE989A0369667EE74372F6E558887FE2561EA926B441AB8F0FD3DEDD608A671011313372084B059CAD7E4807AC852C0873C57F216349422771C089678BAC3021D054C4427EADE70219E251617B83E68640DD7D03C3F99E47F79EB71C124F59EDEA724496A4552F2E9E1F90DDE550745E85483D823F146982C6D2008FE9AA

Интересно, что только значение для метода 1 в обновленном коде отличается. Таким образом, я посмотрел на промежуточные объекты в этом случае

[BC 1.52]
hash: 03AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4
algo: 2.16.840.1.101.3.4.2.1
info: 3031300D06096086480165030402010500042003AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4

[BC 1.53]
hash: 03AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4
algo: 2.16.840.1.101.3.4.2.1
info: 302F300B0609608648016503040201042003AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4

Таким образом, BouncyCastle 1.53 по-разному кодирует объект DigestInfo! И кодирование в 1.52 (и ниже) является тем, которое ожидается в RFC 3447, раздел 9.2 .

. Посмотрев на дампы ASN.1, вы увидите, что BC 1.52 кодирует алгоритмIdentifier как

 2  13:   SEQUENCE {
   <06 09>
 4   9:     OBJECT IDENTIFIER sha-256 (2 16 840 1 101 3 4 2 1)
      :       (NIST Algorithm)
   <05 00>
15   0:     NULL
      :     }

, в то время как BC 1.53 создает

 2  11:   SEQUENCE {
   <06 09>
 4   9:     OBJECT IDENTIFIER sha-256 (2 16 840 1 101 3 4 2 1)
      :       (NIST Algorithm)
      :     }

Таким образом, в 1.53 параметры алгоритма отсутствуют вообще. Это предполагает изменение линии

AlgorithmIdentifier sha256Aid = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, null);

до

AlgorithmIdentifier sha256Aid = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE);

, и внезапно она работает с BouncyCastle 1.53, значения для метода 1 и метода 2 совпадают! ;)

TL; DR

Не используйте null в качестве параметров SHA-256 при создании экземпляра AlgorithmIdentifier, вместо этого используйте DERNull.INSTANCE.

Как я ...

В комментарии OP указал, что он хотел бы узнать больше о

  1. , как вы проверяете промежуточный объект BouncyCastle и
  2. как вы создаете отвалы ASN.1.

Итак ...

... проверьте промежуточный объект

Довольно простой. Сначала я разделил строку

rsaSignature.update(di.toASN1Primitive().getEncoded());

в обновленном коде как

byte[] encodedDigestInfo = di.toASN1Primitive().getEncoded();
rsaSignature.update(encodedDigestInfo);

, а затем добавил выходы консоли

System.out.println("    hash: " + bytesToHex(outputDigest));
System.out.println("    algo: " + sha256Aid.getAlgorithm());
System.out.println("    info: " + bytesToHex(encodedDigestInfo));

Наконец, я выполнил кода с различными версиями BouncyCastle.

... создавать дампы ASN.1

Существует известная утилита, названная dumpasn1 Питером Гутманом , которая стало ядром многих инструментов командной строки и графического интерфейса для создания и отображения дампов ASN.1. В настоящее время я использую GUIdumpASN-ng .

В данном случае я сохранил содержимое файла byte[] encodedDigestInfo в файле (это можно сделать, например, с помощью Files.write ) и открыли эти файлы в GUIdumpASN-ng.

32
ответ дан mkl 21 August 2018 в 03:50
поделиться
  • 1
    Зачем говорить, что Signature.getInstance("RSA") эквивалентно Signature.getInstance("NoneWithRSA")? Я не могу найти доказательств, подтверждающих это. – James K Polk 23 October 2015 в 22:30
  • 2
    A ср. @ Удаленный ответ ArtjomB: в BouncyCastle ... plain RSA ... внутренне отображен в класс org.bouncycastle.jcajce.provider.asymmetric.rsa.noneRSA и B , что еще может иметь смысл? – mkl 24 October 2015 в 05:22
  • 3
    @mkl Я обновил код в сообщении, но все еще не могу понять. Могли бы вы дать мне руку? – Greenhand 24 October 2015 в 09:20
  • 4
    @Greenhand Я выполнил ваш код, и в случае обновленного кода сгенерированные подписи были идентичны. Какие версии (Java, BouncyCastle) вы используете? Можете ли вы поделиться открытым ключом, связанным с соответствующими личными ключами в ваших тестовых прогонах? – mkl 26 October 2015 в 13:30
  • 5
    @Greenhand BouncyCastle 1.53 изменил свою кодировку AlgorithmIdentifier для параметров null, вместо этого вместо этого DERNull.INSTANCE исправил ее. Подробнее см. мой отредактированный ответ. – mkl 27 October 2015 в 17:13
Другие вопросы по тегам:

Похожие вопросы: