Исправление! Хотя существует различие в способах создания PKCS7 и CMS, согласно комментарию, различие здесь заключается в том, что Bouncy использовал 'сконструированное' кодирование (снеопределенная длина , хотя здесь это менее важно), см. wikipedia . «Построенный» элемент в ASN.1 имеет один префикс длины тега для элемента и дополнительный префикс (ы) длины тега для одного или нескольких элементов, которые составляют значение составного элемента.
$ openssl asn1parse <58653210.cms -inform der -i
0:d=0 hl=2 l=inf cons: SEQUENCE
2:d=1 hl=2 l= 9 prim: OBJECT :pkcs7-signedData
13:d=1 hl=2 l=inf cons: cont [ 0 ]
15:d=2 hl=2 l=inf cons: SEQUENCE
17:d=3 hl=2 l= 1 prim: INTEGER :03
20:d=3 hl=2 l= 15 cons: SET
22:d=4 hl=2 l= 13 cons: SEQUENCE
24:d=5 hl=2 l= 9 prim: OBJECT :sha256
35:d=5 hl=2 l= 0 prim: NULL
37:d=3 hl=2 l=inf cons: SEQUENCE
39:d=4 hl=2 l= 6 prim: OBJECT :2.23.136.1.1.2
47:d=4 hl=2 l=inf cons: cont [ 0 ]
49:d=5 hl=2 l=inf cons: OCTET STRING
51:d=6 hl=4 l= 694 prim: OCTET STRING [HEX DUMP]:308202B202010031
[snip rest of (correct) body]
749:d=6 hl=2 l= 0 prim: EOC
751:d=5 hl=2 l= 0 prim: EOC
753:d=4 hl=2 l= 0 prim: EOC
755:d=3 hl=2 l=inf cons: cont [ 0 ]
757:d=4 hl=4 l=1100 cons: SEQUENCE
[snip certificate]
1861:d=4 hl=4 l= 679 cons: SEQUENCE
[snip certificate]
2544:d=4 hl=2 l= 0 prim: EOC
2546:d=3 hl=4 l= 538 cons: SET
2550:d=4 hl=4 l= 534 cons: SEQUENCE
[snip SignerInfo]
3088:d=3 hl=2 l= 0 prim: EOC
3090:d=2 hl=2 l= 0 prim: EOC
3092:d=1 hl=2 l= 0 prim: EOC
Если мы посмотрим на фактические байты со смещением 49 (в шестнадцатеричном формате), мы найдем
24 80 -- tag for OCTET STRING _constructed_, length indefinite
-- a constructed item contains (consists of) one or more following elements
04 82 02 B6 -- tag for OCTET STRING _primitive_, length 02B6
-- this is the only element within the constructed item
и при 49 + 6 + 0x2b6 = 749 находим 00 00
который является «концом содержимого», заканчивая созданный элемент. Таким образом, внешняя сконструированная строка OCTET на самом деле состоит из одного элемента, который является примитивной строкой OCTET.
По предположению, Bouncy использует built + неопределенный для содержимого и encapContentInfo, а также внешнюю SignedData, содержащую их, чтобы позволитьони должны быть больше, чем умещаются в памяти - то, что в криптографии часто называют «онлайн» (странный термин для этого) или более разумно «потоковое». Но он также использует это для сертификатов и компонентов signerInfos, у которых никогда не было этой проблемы - может быть, просто для удобства?
Солнечные классы, по-видимому, этого не делали, хотя вы не опубликовали данные для подтверждения (или использованный код, на который можно посмотреть).
На самом деле это BER по двум причинам;DER не допускает или сконструированных OCTET STRING или неопределенной длины.
(оригинальный, но неприменимый ответ для справки)
Это небольшая и легко пропускаемая разница между PKCS7 (оригинал RSALabs) и CMS (его преемник IETFized). Он был фактически введен в RFC 2630 в 1999 году, но не был четко задокументирован до RFC 3369 с 5.2.1 в 2002 году. Обратите внимание, что version
(целое число в начале SignedData, которое является внешним Context-0EXPLICIT SEQUENCE) также отличается;в созданной Bouncy версии CMS это 3, в то время как на солнце (для которого вы не показываете источник, но, очевидно, PKCS7) оно равно 1. PKCS7 определяет только версию до 1, поэтому любая (структура с) версией> 1 должен быть CMS.