2019-03-26

Экспорт приватных ключей Гост. ч.2

Снова дошли руки до гостовских ключей.

Итак задача та же: нужно получить "бесплатно" закрытые ключи из "дефакто" стандартного гостовского провайдера в openssl.

Система Windows 10.0.17134.648
Ключ с привязанным секретным ключом установлен через CSP.

Запускаем certmgr.msc. Личное - Сертификаты.
Жмём ПКМ на сертификат с привязанным ключом гост (экспортируемым).
Все задачи - Экспорт.
Далее. - Да, экспортировать закрытый ключ - Далее
Файл обмена личной информацией - PKCS #12 (.PFX).
Галочки можно не трогать - но я снял все. Лишнее не надо.
Далее. Галочку на пароль. Вбиваем 123 и 123 в подтверждение.
Шифрование TripleDES-SHA1 (можно и AES256-SHA256 - hmac проверка будет чуть другой).
Далее - Имя файла выбираем 123-try3.pfx - Далее - "Экспорт выполнен" - Готово.

Файл с приватным ключом лежит на диске. Радуемся но не долго.

$ openssl pkcs12 -info -engine gost -password pass:123 -in 123-try3.pfx
engine "gost" set.
MAC: sha1, Iteration 2000
MAC length: 20, salt length: 20
PKCS7 Data
Shrouded Keybag: undefined, Iteration 2000
Bag Attributes
    localKeyID: 01 00 00 00
    friendlyName: 9d09886d-f53d-4e57-85b1-c3c25b0cd72e
    Microsoft CSP Name: Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider
Error outputting keys and certificates
25769902144:error:06074079:digital envelope routines:EVP_PBE_CipherInit:unknown pbe algorithm:crypto/evp/evp_pbe.c:95:TYPE=1.2.840.113549.1.12.1.80
25769902144:error:23077073:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 algor cipherinit error:crypto/pkcs12/p12_decr.c:41:
25769902144:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:crypto/pkcs12/p12_decr.c:94:

Встречает наш знакомый oid=1.2.840.113549.1.12.1.80.

$ openssl asn1parse -inform der -in 123-try3.pfx
    0:d=0  hl=4 l=1140 cons: SEQUENCE
    4:d=1  hl=2 l=   1 prim: INTEGER           :03
    7:d=1  hl=4 l=1072 cons: SEQUENCE
   11:d=2  hl=2 l=   9 prim: OBJECT            :pkcs7-data
   22:d=2  hl=4 l=1057 cons: cont [ 0 ]
   26:d=3  hl=4 l=1053 prim: OCTET STRING      [HEX DUMP]:
30820419308201D606092A864886F70D010701A08201C7048201C3308201BF308201BB060B2A864886F70D010C0A0102A081B23081AF3024060A2A864886F70D010C015030160410C16E378ABE17ADBC7C29E4F5EA4EEED9020207D0048186C4A7BE9F5DEC55369A1E0B357B2D052256F2052E10642B47CC8A567351E81584FFD7DCB7D2384EEC4566A02A67F9EF7504D7A8FA4CCC51722D53770F2B4B4D0667F030E9060A6C0F4ED3D73342C0C1C86FD9669E9808B98A372BC0AF8919CC502F9C74351C60B43AD89D6F4155035CDA5EBE92C36D3D2C8EA562F0F5584529552258AAC84CC43181F6301306092A864886F70D0109153106040401000000305706092A864886F70D010914314A1E4800390064003000390038003800360064002D0066003500330064002D0034006500350037002D0038003500620031002D00630033006300320035006200300063006400370032006530818506092B060104018237110131781E7600430072007900700074006F002D00500072006F00200047004F0053005400200052002000330034002E00310030002D0032003000300031002000430072007900700074006F006700720061007000680069006300200053006500720076006900630065002000500072006F007600690064006500723082023B06092A864886F70D010701A082022C048202283082022430820220060B2A864886F70D010C0A0103A08201F8308201F4060A2A864886F70D01091601A08201E4048201E0308201DC3082018BA0030201020208661C4EDBFE648D91300806062A8503020203301F310B30090603550406130252553110300E0603550403130770756232303031301E170D3139303332353136343330305A170D3230303332353136343330305A301F310B30090603550406130252553110300E06035504031307707562323030313063301C06062A8503020213301206072A85030202240006072A850302021E0103430004403271B0ABC9CC92142384D0B10ADCBC4124A1D5A9AFD440F6A99AADDD882E70CFDB9AED1682A945DF956E04F8C97E8333CF839B461353BED1A04CD99304372B71A381A83081A5300E0603551D0F0101FF0404030202DC301D0603551D250416301406082B0601050507030206082B06010505070304301D0603551D0E0416041475C3BDAB0E1B5534DD35457A201AC7F46DB1DF5530440603551D23043D303B801475C3BDAB0E1B5534DD35457A201AC7F46DB1DF55A123A421301F310B30090603550406130252553110300E0603550403130770756232303031300F0603551D13040830060101FF020101300806062A850302020303410056D6DF338FE5D629243277F31DB56FCB5B7CBCAF8EFD8F8644CCB7359EACCE86B02131C1A5029750F7D831B907000DFE38DFCD18A98203773384C18B4890FAD13115301306092A864886F70D0109153106040401000000
 1083:d=1  hl=2 l=  59 cons: SEQUENCE
 1085:d=2  hl=2 l=  31 cons: SEQUENCE
 1087:d=3  hl=2 l=   7 cons: SEQUENCE
 1089:d=4  hl=2 l=   5 prim: OBJECT            :sha1
 1096:d=3  hl=2 l=  20 prim: OCTET STRING      [HEX DUMP]:
BA88838B4D071952A12D2AE49E91B16E9D1E4719
 1118:d=2  hl=2 l=  20 prim: OCTET STRING      [HEX DUMP]:
767C58C151C9125E72367411A97E9E706C95905C
 1140:d=2  hl=2 l=   2 prim: INTEGER           :07D0

Из предыдущего поста понятно как проверить целостность pkcs7-data - тут алгоритм видимо стандартный - но я его привёл perl скриптом. Скрипт всё ещё работает. Пароль кодируем в UCS2 - размножаем и дополняем номером версии (3) и солью, хешируем SHA1 ROUNDS раз и делаем HMAC_SHA1.

Номером версии=03
ROUNDS=0x7D0 (2000)
SALT=767C58C151C9125E72367411A97E9E706C95905C
HMAC=BA88838B4D071952A12D2AE49E91B16E9D1E4719

Если выводить с "AES256-SHA256" меняем алгоритм суммы SHA256 и HMAC_SHA256.
Но всё равно никаких 3Des и AES в файле не используется.

$VER=3;
$PASS='123';
$ROUNDS=0x7D0;
$SALT=pack 'H*', '767C58C151C9125E72367411A97E9E706C95905C';
$SHA1_NEED=pack 'H*','BA88838B4D071952A12D2AE49E91B16E9D1E4719';
$BLOB=pack 'H*', <<EOF;
30820419308201D606092A864886F70D010701A08201C7048201C3308201BF308201BB060B2A864886F70D010C0A0102A081B23081AF3024060A2A864886F70D010C015030160410C16E378ABE17ADBC7C29E4F5EA4EEED9020207D0048186C4A7BE9F5DEC55369A1E0B357B2D052256F2052E10642B47CC8A567351E81584FFD7DCB7D2384EEC4566A02A67F9EF7504D7A8FA4CCC51722D53770F2B4B4D0667F030E9060A6C0F4ED3D73342C0C1C86FD9669E9808B98A372BC0AF8919CC502F9C74351C60B43AD89D6F4155035CDA5EBE92C36D3D2C8EA562F0F5584529552258AAC84CC43181F6301306092A864886F70D0109153106040401000000305706092A864886F70D010914314A1E4800390064003000390038003800360064002D0066003500330064002D0034006500350037002D0038003500620031002D00630033006300320035006200300063006400370032006530818506092B060104018237110131781E7600430072007900700074006F002D00500072006F00200047004F0053005400200052002000330034002E00310030002D0032003000300031002000430072007900700074006F006700720061007000680069006300200053006500720076006900630065002000500072006F007600690064006500723082023B06092A864886F70D010701A082022C048202283082022430820220060B2A864886F70D010C0A0103A08201F8308201F4060A2A864886F70D01091601A08201E4048201E0308201DC3082018BA0030201020208661C4EDBFE648D91300806062A8503020203301F310B30090603550406130252553110300E0603550403130770756232303031301E170D3139303332353136343330305A170D3230303332353136343330305A301F310B30090603550406130252553110300E06035504031307707562323030313063301C06062A8503020213301206072A85030202240006072A850302021E0103430004403271B0ABC9CC92142384D0B10ADCBC4124A1D5A9AFD440F6A99AADDD882E70CFDB9AED1682A945DF956E04F8C97E8333CF839B461353BED1A04CD99304372B71A381A83081A5300E0603551D0F0101FF0404030202DC301D0603551D250416301406082B0601050507030206082B06010505070304301D0603551D0E0416041475C3BDAB0E1B5534DD35457A201AC7F46DB1DF5530440603551D23043D303B801475C3BDAB0E1B5534DD35457A201AC7F46DB1DF55A123A421301F310B30090603550406130252553110300E0603550403130770756232303031300F0603551D13040830060101FF020101300806062A850302020303410056D6DF338FE5D629243277F31DB56FCB5B7CBCAF8EFD8F8644CCB7359EACCE86B02131C1A5029750F7D831B907000DFE38DFCD18A98203773384C18B4890FAD13115301306092A864886F70D0109153106040401000000
EOF

use Encode 'encode';
use Digest::SHA qw(hmac_sha1 sha1);
$KEY=encode('UCS-2BE', $PASS."\0");
$KEY=((pack'C',$VER) x 64) . substr($SALT x 4, 0, 64) . substr($KEY x 32, 0, 64);
$KEY=sha1($KEY) for 1..$ROUNDS;
$SHA1_GOT=hmac_sha1($BLOB, $KEY);
use v5.10;
say 'HMAC: ',unpack 'H*', $KEY;
say 'NEED: ',unpack 'H*', $SHA1_NEED;
say 'CALC: ',unpack 'H*', $SHA1_GOT;

Продолжаем. Берём в буфер обмена содержимое pkcs7-data - пишем в файл и парсим asn1.

$ xxd -r -p > 123-try3.pkcs7
(paste)

$ openssl asn1parse -inform der -in 123-try3.pkcs7
    0:d=0  hl=4 l=1049 cons: SEQUENCE
    4:d=1  hl=4 l= 470 cons: SEQUENCE
    8:d=2  hl=2 l=   9 prim: OBJECT            :pkcs7-data
   19:d=2  hl=4 l= 455 cons: cont [ 0 ]
   23:d=3  hl=4 l= 451 prim: OCTET STRING      [HEX DUMP]:
308201BF308201BB060B2A864886F70D010C0A0102A081B23081AF3024060A2A864886F70D010C015030160410C16E378ABE17ADBC7C29E4F5EA4EEED9020207D0048186C4A7BE9F5DEC55369A1E0B357B2D052256F2052E10642B47CC8A567351E81584FFD7DCB7D2384EEC4566A02A67F9EF7504D7A8FA4CCC51722D53770F2B4B4D0667F030E9060A6C0F4ED3D73342C0C1C86FD9669E9808B98A372BC0AF8919CC502F9C74351C60B43AD89D6F4155035CDA5EBE92C36D3D2C8EA562F0F5584529552258AAC84CC43181F6301306092A864886F70D0109153106040401000000305706092A864886F70D010914314A1E4800390064003000390038003800360064002D0066003500330064002D0034006500350037002D0038003500620031002D00630033006300320035006200300063006400370032006530818506092B060104018237110131781E7600430072007900700074006F002D00500072006F00200047004F0053005400200052002000330034002E00310030002D0032003000300031002000430072007900700074006F006700720061007000680069006300200053006500720076006900630065002000500072006F00760069006400650072
  478:d=1  hl=4 l= 571 cons: SEQUENCE
  482:d=2  hl=2 l=   9 prim: OBJECT            :pkcs7-data
  493:d=2  hl=4 l= 556 cons: cont [ 0 ]
  497:d=3  hl=4 l= 552 prim: OCTET STRING      [HEX DUMP]:
3082022430820220060B2A864886F70D010C0A0103A08201F8308201F4060A2A864886F70D01091601A08201E4048201E0308201DC3082018BA0030201020208661C4EDBFE648D91300806062A8503020203301F310B30090603550406130252553110300E0603550403130770756232303031301E170D3139303332353136343330305A170D3230303332353136343330305A301F310B30090603550406130252553110300E06035504031307707562323030313063301C06062A8503020213301206072A85030202240006072A850302021E0103430004403271B0ABC9CC92142384D0B10ADCBC4124A1D5A9AFD440F6A99AADDD882E70CFDB9AED1682A945DF956E04F8C97E8333CF839B461353BED1A04CD99304372B71A381A83081A5300E0603551D0F0101FF0404030202DC301D0603551D250416301406082B0601050507030206082B06010505070304301D0603551D0E0416041475C3BDAB0E1B5534DD35457A201AC7F46DB1DF5530440603551D23043D303B801475C3BDAB0E1B5534DD35457A201AC7F46DB1DF55A123A421301F310B30090603550406130252553110300E0603550403130770756232303031300F0603551D13040830060101FF020101300806062A850302020303410056D6DF338FE5D629243277F31DB56FCB5B7CBCAF8EFD8F8644CCB7359EACCE86B02131C1A5029750F7D831B907000DFE38DFCD18A98203773384C18B4890FAD13115301306092A864886F70D0109153106040401000000

Видим теперь два объекта - второй это сертификат - и нам не нужен. Ключ в первом "мешке". Повторяем для него процедуру.

$ xxd -r -p > 123-try3.pkcs8
(paste)
$ openssl asn1parse -inform der -in 123-try3.pkcs8
    0:d=0  hl=4 l= 447 cons: SEQUENCE
    4:d=1  hl=4 l= 443 cons: SEQUENCE
    8:d=2  hl=2 l=  11 prim: OBJECT            :pkcs8ShroudedKeyBag
   21:d=2  hl=3 l= 178 cons: cont [ 0 ]
   24:d=3  hl=3 l= 175 cons: SEQUENCE
   27:d=4  hl=2 l=  36 cons: SEQUENCE
   29:d=5  hl=2 l=  10 prim: OBJECT            :1.2.840.113549.1.12.1.80
   41:d=5  hl=2 l=  22 cons: SEQUENCE
   43:d=6  hl=2 l=  16 prim: OCTET STRING      [HEX DUMP]:
C16E378ABE17ADBC7C29E4F5EA4EEED9
   61:d=6  hl=2 l=   2 prim: INTEGER           :07D0
   65:d=4  hl=3 l= 134 prim: OCTET STRING      [HEX DUMP]:
C4A7BE9F5DEC55369A1E0B357B2D052256F2052E10642B47CC8A567351E81584FFD7DCB7D2384EEC4566A02A67F9EF7504D7A8FA4CCC51722D53770F2B4B4D0667F030E9060A6C0F4ED3D73342C0C1C86FD9669E9808B98A372BC0AF8919CC502F9C74351C60B43AD89D6F4155035CDA5EBE92C36D3D2C8EA562F0F5584529552258AAC84CC4
  202:d=2  hl=3 l= 246 cons: SET
  205:d=3  hl=2 l=  19 cons: SEQUENCE
  207:d=4  hl=2 l=   9 prim: OBJECT            :localKeyID
  218:d=4  hl=2 l=   6 cons: SET
  220:d=5  hl=2 l=   4 prim: OCTET STRING      [HEX DUMP]:01000000
  226:d=3  hl=2 l=  87 cons: SEQUENCE
  228:d=4  hl=2 l=   9 prim: OBJECT            :friendlyName
  239:d=4  hl=2 l=  74 cons: SET
  241:d=5  hl=2 l=  72 prim: BMPSTRING
  315:d=3  hl=3 l= 133 cons: SEQUENCE
  318:d=4  hl=2 l=   9 prim: OBJECT            :Microsoft CSP Name
  329:d=4  hl=2 l= 120 cons: SET
  331:d=5  hl=2 l= 118 prim: BMPSTRING

Вот мы и добрались до этого unknown gost 1.2.840.113549.1.12.1.80 штатными средствами openssl.

Если загрузить исходный pfx в онлайн просмотрщик - можно было увидеть всю структуру сразу.

    0 30 1140: SEQUENCE {
    4 02    1:  INTEGER 3
    7 30 1072:  SEQUENCE {
   11 06    9:   OBJECT IDENTIFIER data (1.2.840.113549.1.7.1)
   22 a0 1057:   [0] {
   26 04 1053:    OCTET STRING, encapsulates {
   30 30 1049:     SEQUENCE {
   34 30  470:      SEQUENCE {
   38 06    9:       OBJECT IDENTIFIER data (1.2.840.113549.1.7.1)
   49 a0  455:       [0] {
   53 04  451:        OCTET STRING, encapsulates {
   57 30  447:         SEQUENCE {
   61 30  443:          SEQUENCE {
   65 06   11:           OBJECT IDENTIFIER pkcs8ShroudedKeyBag (1.2.840.113549.1.12.10.1.2)
   78 a0  178:           [0] {
   81 30  175:            SEQUENCE {
   84 30   36:             SEQUENCE {
   86 06   10:              OBJECT IDENTIFIER pbeUnknownGost (1.2.840.113549.1.12.1.80)
   98 30   22:              SEQUENCE {
  100 04   16:               OCTET STRING
             :                c1 6e 37 8a be 17 ad bc 7c 29 e4 f5 ea 4e ee d9
  118 02    2:               INTEGER 2000
             :              }
             :             }
  122 04  134:             OCTET STRING
             :              c4 a7 be 9f 5d ec 55 36 9a 1e 0b 35 7b 2d 05 22
             :              56 f2 05 2e 10 64 2b 47 cc 8a 56 73 51 e8 15 84
             :              ff d7 dc b7 d2 38 4e ec 45 66 a0 2a 67 f9 ef 75
             :              04 d7 a8 fa 4c cc 51 72 2d 53 77 0f 2b 4b 4d 06
             :              67 f0 30 e9 06 0a 6c 0f 4e d3 d7 33 42 c0 c1 c8
             :              6f d9 66 9e 98 08 b9 8a 37 2b c0 af 89 19 cc 50
             :              2f 9c 74 35 1c 60 b4 3a d8 9d 6f 41 55 03 5c da
             :              5e be 92 c3 6d 3d 2c 8e a5 62 f0 f5 58 45 29 55
             :              22 58 aa c8 4c c4
             :            }
             :           }
  259 31  246:           SET {
  262 30   19:            SEQUENCE {
  264 06    9:             OBJECT IDENTIFIER localKeyId (1.2.840.113549.1.9.21)
  275 31    6:             SET {
  277 04    4:              OCTET STRING, encapsulates {
  279 01    0:               BOOLEAN true
             :              }
             :             }
             :            }
  283 30   87:            SEQUENCE {
  285 06    9:             OBJECT IDENTIFIER friendlyName (1.2.840.113549.1.9.20)
  296 31   74:             SET {
  298 1e   72:              BMPString "9d09886d-f53d-4e57-85b1-c3c25b0cd72e"
             :             }
             :            }
  372 30  133:            SEQUENCE {
  375 06    9:             OBJECT IDENTIFIER keyProviderNameAttr (1.3.6.1.4.1.311.17.1)
  386 31  120:             SET {
  388 1e  118:              BMPString "Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider"
             :             }
             :            }
             :           }
             :          }
             :         }
             :        }
             :       }
             :      }
  508 30  571:      SEQUENCE {
  512 06    9:       OBJECT IDENTIFIER data (1.2.840.113549.1.7.1)
  523 a0  556:       [0] {
  527 04  552:        OCTET STRING, encapsulates {
  531 30  548:         SEQUENCE {
  535 30  544:          SEQUENCE {
  539 06   11:           OBJECT IDENTIFIER certBag (1.2.840.113549.1.12.10.1.3)
  552 a0  504:           [0] {
  556 30  500:            SEQUENCE {
  560 06   10:             OBJECT IDENTIFIER x509Certificate (1.2.840.113549.1.9.22.1)
  572 a0  484:             [0] {
  576 04  480:              OCTET STRING, encapsulates {
  580 30  476:               SEQUENCE {
  584 30  395:                SEQUENCE {
  588 a0    3:                 [0] {
  590 02    1:                  INTEGER 2
             :                 }
  593 02    8:                 INTEGER
             :                  66 1c 4e db fe 64 8d 91
  603 30    8:                 SEQUENCE {
  605 06    6:                  OBJECT IDENTIFIER id-GostR3411-94-with-GostR3410-2001 (1.2.643.2.2.3)
             :                 }
  613 30   31:                 SEQUENCE {
  615 31   11:                  SET {
  617 30    9:                   SEQUENCE {
  619 06    3:                    OBJECT IDENTIFIER countryName (2.5.4.6)
  624 13    2:                    PrintableString "RU"
             :                   }
             :                  }
  628 31   16:                  SET {
  630 30   14:                   SEQUENCE {
  632 06    3:                    OBJECT IDENTIFIER commonName (2.5.4.3)
  637 13    7:                    PrintableString "pub2001"
             :                   }
             :                  }
             :                 }
  646 30   30:                 SEQUENCE {
  648 17   13:                  UTCTime Mon Mar 25 2019 19:43:00 GMT+0300 (Москва, стандартное время)
  663 17   13:                  UTCTime Wed Mar 25 2020 19:43:00 GMT+0300 (Москва, стандартное время)
             :                 }
  678 30   31:                 SEQUENCE {
  680 31   11:                  SET {
  682 30    9:                   SEQUENCE {
  684 06    3:                    OBJECT IDENTIFIER countryName (2.5.4.6)
  689 13    2:                    PrintableString "RU"
             :                   }
             :                  }
  693 31   16:                  SET {
  695 30   14:                   SEQUENCE {
  697 06    3:                    OBJECT IDENTIFIER commonName (2.5.4.3)
  702 13    7:                    PrintableString "pub2001"
             :                   }
             :                  }
             :                 }
  711 30   99:                 SEQUENCE {
  713 30   28:                  SEQUENCE {
  715 06    6:                   OBJECT IDENTIFIER id-GostR3410-2001 (1.2.643.2.2.19)
  723 30   18:                   SEQUENCE {
  725 06    7:                    OBJECT IDENTIFIER id-GostR3410-2001-CryptoPro-XchA-ParamSet (1.2.643.2.2.36.0)
  734 06    7:                    OBJECT IDENTIFIER id-GostR3411-94-CryptoProParamSet (1.2.643.2.2.30.1)
             :                   }
             :                  }
  743 03   67:                  BIT STRING, unused 0 bits, encapsulates {
  745 04   64:                   OCTET STRING
             :                    32 71 b0 ab c9 cc 92 14 23 84 d0 b1 0a dc bc 41
             :                    24 a1 d5 a9 af d4 40 f6 a9 9a ad dd 88 2e 70 cf
             :                    db 9a ed 16 82 a9 45 df 95 6e 04 f8 c9 7e 83 33
             :                    cf 83 9b 46 13 53 be d1 a0 4c d9 93 04 37 2b 71
             :                  }
             :                 }
  812 a3  168:                 [3] {
  815 30  165:                  SEQUENCE {
  818 30   14:                   SEQUENCE {
  820 06    3:                    OBJECT IDENTIFIER keyUsage (2.5.29.15)
  825 01    1:                    BOOLEAN true
  828 04    4:                    OCTET STRING, encapsulates {
  830 03    2:                     BIT STRING, unused 2 bits
             :                      110111B
             :                    }
             :                   }
  834 30   29:                   SEQUENCE {
  836 06    3:                    OBJECT IDENTIFIER extKeyUsage (2.5.29.37)
  841 04   22:                    OCTET STRING, encapsulates {
  843 30   20:                     SEQUENCE {
  845 06    8:                      OBJECT IDENTIFIER clientAuth (1.3.6.1.5.5.7.3.2)
  855 06    8:                      OBJECT IDENTIFIER emailProtection (1.3.6.1.5.5.7.3.4)
             :                     }
             :                    }
             :                   }
  865 30   29:                   SEQUENCE {
  867 06    3:                    OBJECT IDENTIFIER subjectKeyIdentifier (2.5.29.14)
  872 04   22:                    OCTET STRING, encapsulates {
  874 04   20:                     OCTET STRING
             :                      75 c3 bd ab 0e 1b 55 34 dd 35 45 7a 20 1a c7 f4
             :                      6d b1 df 55
             :                    }
             :                   }
  896 30   68:                   SEQUENCE {
  898 06    3:                    OBJECT IDENTIFIER authorityKeyIdentifier (2.5.29.35)
  903 04   61:                    OCTET STRING, encapsulates {
  905 30   59:                     SEQUENCE {
  907 80   20:                      [0]
             :                       75 c3 bd ab 0e 1b 55 34 dd 35 45 7a 20 1a c7 f4
             :                       6d b1 df 55
  929 a1   35:                      [1] {
  931 a4   33:                       [4] {
  933 30   31:                        SEQUENCE {
  935 31   11:                         SET {
  937 30    9:                          SEQUENCE {
  939 06    3:                           OBJECT IDENTIFIER countryName (2.5.4.6)
  944 13    2:                           PrintableString "RU"
             :                          }
             :                         }
  948 31   16:                         SET {
  950 30   14:                          SEQUENCE {
  952 06    3:                           OBJECT IDENTIFIER commonName (2.5.4.3)
  957 13    7:                           PrintableString "pub2001"
             :                          }
             :                         }
             :                        }
             :                       }
             :                      }
             :                     }
             :                    }
             :                   }
  966 30   15:                   SEQUENCE {
  968 06    3:                    OBJECT IDENTIFIER basicConstraints (2.5.29.19)
  973 04    8:                    OCTET STRING, encapsulates {
  975 30    6:                     SEQUENCE {
  977 01    1:                      BOOLEAN true
  980 02    1:                      INTEGER 1
             :                     }
             :                    }
             :                   }
             :                  }
             :                 }
             :                }
  983 30    8:                SEQUENCE {
  985 06    6:                 OBJECT IDENTIFIER id-GostR3411-94-with-GostR3410-2001 (1.2.643.2.2.3)
             :                }
  993 03   65:                BIT STRING, unused 0 bits
             :                 56 d6 df 33 8f e5 d6 29 24 32 77 f3 1d b5 6f cb
             :                 5b 7c bc af 8e fd 8f 86 44 cc b7 35 9e ac ce 86
             :                 b0 21 31 c1 a5 02 97 50 f7 d8 31 b9 07 00 0d fe
             :                 38 df cd 18 a9 82 03 77 33 84 c1 8b 48 90 fa d1
             :               }
             :              }
             :             }
             :            }
             :           }
 1060 31   21:           SET {
 1062 30   19:            SEQUENCE {
 1064 06    9:             OBJECT IDENTIFIER localKeyId (1.2.840.113549.1.9.21)
 1075 31    6:             SET {
 1077 04    4:              OCTET STRING, encapsulates {
 1079 01    0:               BOOLEAN true
             :              }
             :             }
             :            }
             :           }
             :          }
             :         }
             :        }
             :       }
             :      }
             :     }
             :    }
             :   }
             :  }
 1083 30   59:  SEQUENCE {
 1085 30   31:   SEQUENCE {
 1087 30    7:    SEQUENCE {
 1089 06    5:     OBJECT IDENTIFIER sha1 (1.3.14.3.2.26)
             :    }
 1096 04   20:    OCTET STRING
             :     ba 88 83 8b 4d 07 19 52 a1 2d 2a e4 9e 91 b1 6e
             :     9d 1e 47 19
             :   }
 1118 04   20:   OCTET STRING
             :    76 7c 58 c1 51 c9 12 5e 72 36 74 11 a9 7e 9e 70
             :    6c 95 90 5c
 1140 02    2:   INTEGER 2000
             :  }
             : }

Продолжаем снимать транспортную кодировку.
Получили в данный момент такие цифры:



PASS=123
SALT=C16E378ABE17ADBC7C29E4F5EA4EEED9
ROUNDS=0x7D0
ENCRYPTED KEYBAG:
C4A7BE9F5DEC55369A1E0B357B2D052256F2052E10642B47CC8A567351E81584FFD7DCB7D2384EEC4566A02A67F9EF7504D7A8FA4CCC51722D53770F2B4B4D0667F030E9060A6C0F4ED3D73342C0C1C86FD9669E9808B98A372BC0AF8919CC502F9C74351C60B43AD89D6F4155035CDA5EBE92C36D3D2C8EA562F0F5584529552258AAC84CC4


Получаем ключ для расшифровки (сорри - опять perl).

use Digest::GOST::CryptoPro qw(gost);
$KEY=encode('UCS-2LE', $PASS);
for ($i=1;$i<=$ROUNDS;$i++){$KEY=gost($KEY.$SALT.pack('n',$i))}
say 'PASSWORD=',unpack 'H*',$KEY;

Для предыдущих цифр получаем ключ:
KEY=c2bb428f981f30d8e623db786d9bd780e7d9f785a950211530142ae46fab8dce
Вот раунды хеширования если будете повторять: 310032003300 c16e378abe17adbc7c29e4f5ea4eeed9 0001 fb76e01671ac07908c159f59a0442815acaccc2e77fc25958b99a4626fc738fe c16e378abe17adbc7c29e4f5ea4eeed9 0002 cdae166434edddd770cbc0d7294f4031d83309206bc15a3089cbde622fba0ce7 c16e378abe17adbc7c29e4f5ea4eeed9 0003 ...
9350e6ec445712728c6d7c6c02efb9068f295a3f451af8df33613bfc42412d71 c16e378abe17adbc7c29e4f5ea4eeed9 07d0
Хеш сумму можно получить штатными средствами так:
$ echo 310032003300 c16e378abe17adbc7c29e4f5ea4eeed9 0001 | xxd -r -p > round1
$ gostsum round1
fe38c76f62a4998b9525fc772eccacac152844a0599f158c9007ac7116e076fb round1
$ openssl dgst -engine gost -md_gost94 -hex round1
md_gost94(round1)= fb76e01671ac07908c159f59a0442815acaccc2e77fc25958b99a4626fc738fe
gostsum есть в пакетах, собирается из gost engine от openssl (есть на github) да, и он выдаёт другой порядок байт, что надо учитывать.
Всё это было и в первой части - тут чуть подробнее.
Теперь продолжение:
Снимаем транспортную кодировку с помощью openssl.
Что используем:
Симметричный шифр: gost89 (он же magma)

MODE=CFB (Режим шифрования - он по умолчанию для gost89 в openssl)
IV (Начальный вектор): SALT(0:7) (соль больше блока шифрования магмы - для IV отрезаем её до 8 байт=16  шестнадцатеричных символов = 64 бита - или игнорируем warning)
IV=C16E378ABE17ADBC (игнорируем остаток 7C29E4F5EA4EEED9)
KEY (Ключ - получили выше) 256 бит = 32 байта = 64 hex цифры.
KEY=c2bb428f981f30d8e623db786d9bd780e7d9f785a950211530142ae46fab8dce
$ xxd -r -p > 123-try3.enc
(paste keybag C4A7BE9F5DEC55369A1E0B...)
$ CRYPT_PARAMS=1.2.643.2.2.31.1 openssl enc -engine gost -d -gost89 -in 123-try3.enc -out 123-try3.dec \
-K c2bb428f981f30d8e623db786d9bd780e7d9f785a950211530142ae46fab8dce  -iv C16E378ABE17ADBC7C29E4F5EA4EEED9
На всякий случай задали параметры шифрования через env CRYPT_PARAMS но по умолчанию они же стоят. Должны получить asn1 c экспортным ключом (первый asci символ "0").
$ openssl asn1parse -inform der -in 123-try3.dec
    0:d=0  hl=3 l= 131 cons: SEQUENCE     3:d=1  hl=2 l=   1 prim: INTEGER           :00     6:d=1  hl=2 l=  10 cons: SEQUENCE     8:d=2  hl=2 l=   6 prim: OBJECT            :GOST R 34.10-2001    16:d=2  hl=2 l=   0 prim: NULL    18:d=1  hl=2 l= 114 prim: OCTET STRING      [HEX DUMP]: 0720000024AA00004D41473120000000
306030580408FEF0268E68E6A7EA302804207987275594A59F491E62F636F794BDD49A5CD547E0D901DF3AD58DA9EFFC2657040468369E8AA022030205A0A01C06062A8503020262301206072A85030202240006072A850302021E010404B30785AA
Содержимое блоба - это то, что мы получаем, если экспорт приватного ключа сделать через winapi. То есть транспортную кодировку мы полностью сняли.
Осталось то что получили внутрь openssl прописать :)
Посмотрим что нам даёт криптопро в своей экспортной структуре.
Заголовок структуры 07 - PRIVATEKEYBLOB (06 - PUBLICKEY).
Такой параметр передаётся в функцию ExportKey.
000020 - размер ключа? Или тут всё таки 00002007 ?
АА24 - algid:
algInfo name:DH 34.10-2001
longName:GOST R 34.10-2001 256 DH
algId:43556(AA24)
type:KeyExchange
OID:1.2.643.2.2.98
OID.alg=43556(AA24)
OID_groupId:3:PUBKEY_ALG
4D414731 = MAG1 "Магический заголовок"?
00000020 - опять размер ключа?
Дальше в структуре снова идёт asn1.
Отрезаем заголовок и смотрим что там:
0:d=0  hl=2 l=  96 cons: SEQUENCE
    2:d=1  hl=2 l=  88 cons: SEQUENCE
    4:d=2  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:FEF0268E68E6A7EA
   14:d=2  hl=2 l=  40 cons: SEQUENCE
   16:d=3  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:
7987275594A59F491E62F636F794BDD49A5CD547E0D901DF3AD58DA9EFFC2657
   50:d=3  hl=2 l=   4 prim: OCTET STRING      [HEX DUMP]:68369E8A
   56:d=2  hl=2 l=  34 cons: cont [ 0 ]
   58:d=3  hl=2 l=   2 prim: BIT STRING
   62:d=3  hl=2 l=  28 cons: cont [ 0 ]
   64:d=4  hl=2 l=   6 prim: OBJECT            :GOST R 34.10-2001 DH
   72:d=4  hl=2 l=  18 cons: SEQUENCE
   74:d=5  hl=2 l=   7 prim: OBJECT            :id-GostR3410-2001-CryptoPro-XchA-ParamSet
   83:d=5  hl=2 l=   7 prim: OBJECT            :id-GostR3411-94-CryptoProParamSet
   92:d=1  hl=2 l=   4 prim: OCTET STRING      [HEX DUMP]:B30785AA
Или на онлайн сервисе:
    0 30   96: SEQUENCE {
    2 30   88:  SEQUENCE {
    4 04    8:   OCTET STRING
             :    fe f0 26 8e 68 e6 a7 ea
   14 30   40:   SEQUENCE {
   16 04   32:    OCTET STRING
             :     79 87 27 55 94 a5 9f 49 1e 62 f6 36 f7 94 bd d4
             :     9a 5c d5 47 e0 d9 01 df 3a d5 8d a9 ef fc 26 57
   50 04    4:    OCTET STRING
             :     68 36 9e 8a
             :   }
   56 a0   34:   [0] {
   58 03    2:    BIT STRING, unused 5 bits
             :     101B
   62 a0   28:    [0] {
   64 06    6:     OBJECT IDENTIFIER id-GostR3410-2001DH (1.2.643.2.2.98)
   72 30   18:     SEQUENCE {
   74 06    7:      OBJECT IDENTIFIER id-GostR3410-2001-CryptoPro-XchA-ParamSet (1.2.643.2.2.36.0)
   83 06    7:      OBJECT IDENTIFIER id-GostR3411-94-CryptoProParamSet (1.2.643.2.2.30.1)
             :     }
             :    }
             :   }
             :  }
   92 04    4:  OCTET STRING
             :   b3 07 85 aa
             : }

Вот это нам ещё предстоит расшифровать.
Шифрованный приватный ключ (ещё не совсем сам приватный ключ, годный для openssl):
7987275594A59F491E62F636F794BDD49A5CD547E0D901DF3AD58DA9EFFC2657
Размер уже совпадает с ожидаемым секретным ключом, т.е. тут работает
симметричный алгоритм и никакой дополнительной структуры больше нет.
(Матрёшки asn1 наконец закончились).
Соли, контрольные суммы или что-то ещё:
FEF0268E68E6A7EA
68369E8A
B30785AA

Отсылки на:
id-GostR3410-2001-CryptoPro-XchA-ParamSet
id-GostR3410-2001DH
id-GostR3411-94-CryptoProParamSet
Также тут поработали такие не(до)документированные алгоритмы:
CALG_PRO_EXPORT CALG_PRO12_EXPORT CALG_SIMPLE_EXPORT

Упоминается, что они "работают в соответствии с рекомендациями ТК26" -
но как обратить их работу надо ещё смотреть.

И надо помнить, что у нас есть пароль на экспорт (может быть и не участвует)
и публичный ключ (из сертификата).
Публичный ключ (получить легко)=
3271B0ABC9CC92142384D0B10ADCBC4124A1D5A9AFD440F6A99AADDD882E70CF DB9AED1682A945DF956E04F8C97E8333CF839B461353BED1A04CD99304372B71

Части приватного ключа (при экспорте приватного в формате PEM)=
00DC1DFB629158E86D246F26DADD3289562910A1D65FD74E523A636351B8C33D
4597BEC52D5D4704
(видимо что-то фокс зашифровал)
Экспорт приватного ключа фоксом в pkcs8 без шифра даёт вот это:
{
    privateKeyAlgorithm: {
        name: "GOST R 34.10-2001",
        id: "id-GostR3410-2001",
        namedCurve: "X-256-A",
        sBox: "D-A"
    },
    privateKey: [
        0x04, 0x20, 0x31, 0x96, 0x76, 0x58, 0xc0, 0x64, 0x7a, 0xcd, 0xbd, 0x2c, 0x8a, 0x8d, 0x55, 0xcc,
        0x03, 0x18, 0x03, 0x20, 0x8d, 0x94, 0x29, 0x2c, 0x16, 0x22, 0x1f, 0x68, 0xd9, 0xd7, 0xca, 0xa5,
        0xd7, 0x3e
    ]
}

Приватный ключ=
042031967658C0647ACDBD2C8A8D55CC031803208D94292C16221F68D9D7CAA5D73E
Осталось это получить из шифрованного ключа.
...

Дополнения.

По адресу: https://tc26.ru/standard/rs/%D0%A0%2050.1.111-2016.pdf https://www.s-terra.ru/upload/medialibrary/9bb/rekomendacii-po-standartizacii-kriptografia.pdf нашлось описание хотелок ТК26, оформленных в виде
РЕКОМЕНДАЦИИ ПО СТАНДАРТИЗАЦИИ
ИСПОЛЬЗОВАНИЕ КРИПТОГРАФИЧЕСКИХ АЛГОРИТМОВ,
СОПУТСТВУЮЩИХ ПРИМЕНЕНИЮ СТАНДАРТОВ
ГОСТ Р 34.10-2012 И ГОСТ Р 34.11-2012
Утверждены решением заседания
технического комитета по стандартизации
«Криптографическая защита информации»
(Протокол №13 от 24.04.2014 г.)
В которых в пункте 5.6 "Экспорт и импорт ключей" дают такой алгоритм :
1) Порождается случайный набор UKM.
2) С помощью функции диверсификации, использующей в качестве ключа диверсификации ключ экспорта Ke,
и в качестве значения seed случайный набор UKM, производится формирование ключа, обозначаемого KEKe(UKM).
KEKe(UKM) = KDF(Ke,label,UKM).
3) Вычисляется значение имитовставки по ГОСТ 28147-89 длины 4 байта от данных K
на ключе KEKe(UKM), синхропосылка при этом полагается равной первым 8 байтам
UKM. Полученный набор обозначается через CEK_MAC.
Compute a 4-byte checksum value, gost28147IMIT (UKM, KEK(UKM), CEK).  Call the result CEK_MAC. [rfc4357]
4) Ключ K зашифровывается по алгоритму ГОСТ 28147-89 в режиме простой замены
с использованием ключа KEKe(UKM). Результат зашифрования обозначается через
CEK_ENC.
Encrypt CEK in ECB mode using KEK(UKM).  Call the ciphertext CEK_ENC. [rfc4357]
5) Экспортным представлением ключа полагается набор (UKM | CEK_ENC | CEK_MAC).

входной набор для порождения ключа: KDF(Ke,label,UKM)
выходной набор: UKM, CEK_ENC, CEK_MAC

label=26BDB878 (фиксированный набор - приведён в "рекомендациях")
UKM=FEF0268E68E6A7EA (очевидно самая длинная посылка, т.к. её размер минимум 8 байт)
CEK_ENC=7987275594A59F491E62F636F794BDD49A5CD547E0D901DF3AD58DA9EFFC2657
CEK_MAC=68369E8A или B30785AA (обе цифры длинной 4 байта - и могут быть MAC)
В секции 5.4 дают функцию диверсификации KDF_GOSTR3411_2012_256:
KDF(Kin,label,seed) = HMAC256(Kin,0x01|label|0x00|seed|0x01|0x00)
Осталось "угадать" значение Ke Читаем rfc4357 как "изуродовать" K до Ke:
6.5.  CryptoPro KEK Diversification Algorithm

   Given a random 64-bit UKM and a GOST 28147-89 key K, this algorithm
   creates a new GOST 28147-89 key K(UKM).

    1) Let K[0] = K;
    2) UKM is split into components a[i,j]:
       UKM = a[0]|..|a[7] (a[i] - byte, a[i,0]..a[i,7] - it's bits)
    3) Let i be 0.
    4) K[1]..K[8] are calculated by repeating the following algorithm
       eight times:
     A) K[i] is split into components k[i,j]:
        K[i] = k[i,0]|k[i,1]|..|k[i,7] (k[i,j] - 32-bit integer)
     B) Vector S[i] is calculated:
        S[i] = ((a[i,0]*k[i,0] + ... + a[i,7]*k[i,7]) mod 2^32) |
        (((~a[i,0])*k[i,0] + ... + (~a[i,7])*k[i,7]) mod 2^32);
     C) K[i+1] = encryptCFB (S[i], K[i], K[i])
     D) i = i + 1
    5) Let K(UKM) be K[8].

7.  Secret Key Diversification

   This algorithm creates a GOST 28147-89 key Kd, given GOST R 34.10-94
   or GOST R 34.10-2001 secret key K and diversification data D of size
   4..40 bytes.

    1) 40-byte blob B is created from D by cloning it enough times to
       fill all 40 bytes.  For example, if D is 40-bytes long, B = D; If
       D is 6-bytes long, B = D|D|D|D|D|D|D[0..3].
    2) B is split into 8-byte UKM and 32-byte SRCKEY (B = UKM|SRCKEY).
    3) The algorithm from Section 6.5 is used to create K(UKM) from key
       K and UKM, with two differences:
         * Instead of S[i], vector (0,0,0,UKM[i],ff,ff,ff,ff XOR UKM[i])
           is used.
         * During each encryption step, only 8 out of 32 GOST 28147-89
           rounds are done.
    4) Kd is calculated:
       Kd = encryptCFB (UKM, K(UKM), SRCKEY).
Лезем в код github/gost_engine Внутри test_keyexpimp.c проверочные значения одного из тестовых примеров из pdf tc26.
    unsigned char kdftree_key[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
    };

    unsigned char kdf_label[] = { 0x26, 0xBD, 0xB8, 0x78 };
    unsigned char kdf_seed[] =  { 0xAF, 0x21, 0x43, 0x41, 0x45, 0x65, 0x63, 0x78 };
    const unsigned char kdf_etalon[] = {
        0x22, 0xB6, 0x83, 0x78, 0x45, 0xC6, 0xBE, 0xF6,
        0x5E, 0xA7, 0x16, 0x72, 0xB2, 0x65, 0x83, 0x10,
        0x86, 0xD3, 0xC7, 0x6A, 0xEB, 0xE6, 0xDA, 0xE9,
        0x1C, 0xAD, 0x51, 0xD8, 0x3F, 0x79, 0xD1, 0x6B,
        0x07, 0x4C, 0x93, 0x30, 0x59, 0x9D, 0x7F, 0x8D,
        0x71, 0x2F, 0xCA, 0x54, 0x39, 0x2F, 0x4D, 0xDD,
        0xE9, 0x37, 0x51, 0x20, 0x6B, 0x35, 0x84, 0xC8,
        0xF4, 0x3F, 0x9E, 0x6D, 0xC5, 0x15, 0x31, 0xF9
    };

// код проверки:
    ret = gost_kdftree2012_256(kdf_result, 64, kdftree_key, 32, kdf_label, 4, kdf_seed, 8, 1);
    if (ret <= 0) {
        ERR_print_errors_fp(stderr);
 err = 5;
    } else {
        hexdump(stdout, "KDF TREE", kdf_result, 64);
        if (memcmp(kdf_result, kdf_etalon, 64) != 0) {
            fprintf(stdout, "ERROR! test failed\n");
     err = 6;
        }
    }

// добавляем "первое" контрольное значение:
    const unsigned char kdf_gost_etalon[] = {
 0xa1, 0xaa, 0x5f, 0x7d, 0xe4, 0x02, 0xd7, 0xb3,
 0xd3, 0x23, 0xf2, 0x99, 0x1c, 0x8d, 0x45, 0x34,
 0x01, 0x31, 0x37, 0x01, 0x0a, 0x83, 0x75, 0x4f,
 0xd0, 0xaf, 0x6d, 0x7c, 0xd4, 0x92, 0x2e, 0xd9
    };

// и его код проверки:
    ret = gost_kdftree2012_256(kdf_result, 32, kdftree_key, 32, kdf_label, 4, kdf_seed, 8, 1);
    if (ret <= 0) {
        ERR_print_errors_fp(stderr);
 err = 9;
    } else {
        hexdump(stdout, "KDF_GOSTR3411_2012_256", kdf_result, 32);
        if (memcmp(kdf_result, kdf_gost_etalon, 32) != 0) {
            fprintf(stdout, "ERROR! test failed\n");
     err = 10;
        }
    }
Работающий код для вычисления KDF() у нас есть. Внутри gost_keywrap.c обнаруживаем функции деривации ключа. Контрольных значений не видно.
Находим контрольные примеры в рекомендациях (5.7 п13):
13) Экспорт и импорт ключей
на параметрах szOID_Gost28147_89_TC26_Z_ParamSet
Ключ K:

 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
Величина UKM:
af 21 43 41 45 65 63 78
label:
26 bd b8 78
 KEKe(UKM) = KDF(Ke,label,UKM):

 a1 aa 5f 7d e4 02 d7 b3 d3 23 f2 99 1c 8d 45 34
 01 31 37 01 0a 83 75 4f d0 af 6d 7c d4 92 2e d9
 CEK_MAC:
 38 d5 8a a3
 CEK_ENC:
 b9 fb 92 42 95 0f 84 3f 0f bd 5b 9a 5e cf 9f 17
 f7 9e 6d 21 58 16 56 de 6d c5 85 dd 62 7a 44 0a
K=042031967658C0647ACDBD2C8A8D55CC031803208D94292C16221F68D9D7CAA5D73E

13 комментариев:

dadv комментирует...

А есть ли в каком-то виде итоговый код? Так, чтобы дать ему PFX-файл и пароль и он бы экспортнул приватный ключ в каком-нибудь виде, пригодном для преобразования в:

-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

Пусть будет perl или неважно, что.

Gimly комментирует...

Можно получить пока только по старинке.

p12fromgost_2016 -> fox-xca 2.0 -> pem

в принципе можно пропатчить p12fromgost чтобы оно записало расшифрованный ключ после снятия экспортного шифрования. или даже взяло на вход ключ pfx и записало pem.

Ну или продолжать дебажить эту p12 на участке расшифровки. Алгоритмы в принципе не только известны, документированы но и (частично) реализованы внутри openssl gost_engine. Остаётся понять как их правильно применять и на каких ключах-векторах-данных.

Сам разработчик gost-engine обозвал затею "красивой высокой теорией" и не полез в это.

bna комментирует...

Есть какой-нибудь прогресс?

Версия P12FromGostCSP которая есть в интернете и не требует лицензионного ключа не сохраняет сертификаты с GOST 2012.

Лирическое отступление: Каждый год приходится платить за рутокен с сертификатом (за простые числа), а теперь еще надо каждый год покупать P12FromGostCSP, которая стоит дороже самого сертификата, чтобы изменив несколько байт, образно говоря, получить сертификат (уже купленный), который можно будет подсунуть в openssl. Упыри.

Еще есть вариант взломать P12FromGostCSP, чтобы она запускалась без файла лицензии LIC.DAT (надеюсь, что этого будет достаточно)

Вам можно чем-нибудь помочь?

bna комментирует...
Этот комментарий был удален автором.
bna комментирует...

Все-таки нашел работающую версию программы P12FromGostCSP (не требует файл лицензии): Pfx файл. Подпись документа

Ссылка в ответе под вопросом.

Так же продублирую здесь: P12FromGostCSP

Анонимный комментирует...

Спасибо тебе святой человек! сколько я её искал. Они с этим лицензированием дров наломали. Сказали бы заплатите 100к и дадим вам, я был бы готов, но ад с лицензиями у Лисси , которые глючат, привязываются к юзеру и прочий бред.

reddiego комментирует...

Здравствуйте! Можете еще раз прислать ссылку на программу?

bna комментирует...

reddiego, ссылка на zippyshare рабочая

Женек комментирует...

Блин, все понятно, но как сгенерить KEK?)
похоже что через ключ согласования VKO_GOSTR3410, но тогда где спрятан открытый и закрытый ключ... либо какой-то статический ключ нужен... попробовал получить через PBKDF2, но тоже чет не вышло... проверку не прошел ключ по мак,
хрен где че найдешь, ребус какой-то)

Женек комментирует...

кстати вот есть выгрузка из реестра и из папки кто-то сделал, можно немного схожего кода глянуть по выгрузке
https://github.com/kmvi/cp-extract-data

Анонимный комментирует...

Коллеги, есть решение для ГОСТ 2012
https://github.com/iliadmitriev/privkey2012

Анонимный комментирует...

продублируйте, пож, ссылку на P12FromGostCSP

Анонимный комментирует...

фыв