Побег из КриптоПро или же 1.2.840.113549.1.12.1.80
Думаю знакомая ситуация некоторым людям: Экспортируем контейнер в PFX(P12) и при попытке работы с ним получаем ошибку:
$ openssl pkcs12 -in csp.pfx Enter Import Password: Bag Attributes localKeyID: 01 00 00 00 Microsoft CSP Name: Crypto-Pro GOST R 34.10-2012 KC1 CSP friendlyName: ****_*****_00.00.22_00.00.00 Error outputting keys and certificates EVP_PBE_CipherInit:unknown pbe algorithm:../crypto/evp/evp_pbe.c:95:TYPE=1.2.840.113549.1.12.1.80 PKCS12_pbe_crypt:pkcs12 algor cipherinit error:../crypto/pkcs12/p12_decr.c:41: PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:../crypto/pkcs12/p12_decr.c:94:
Сегодня я покажу вам частичное решение данной проблемы(частичное из за лени разработчика гостовского движка для OpenSSL).
Заходим на GostCrypto и открываем наш PFX (P12):
В данном случае c1 6e 37 8a be 17 ad bc 7c 29 e4 f5 ea 4e ee d9
- это соль, 2000 - количество итераций, а c4 a7 be ... c8 4c c4
- зашифрованный шифром криптопро ключ.
Берем и качаем скрипт на Go и открываем его и меняем значения переменных на:
PASS :="123"; // - Ваш пароль от PFX/P12 SALT := "C16E378ABE17ADBC7C29E4F5EA4EEED9" // Соль, соответственно
После запуска скрипта мы получим ключ и соль для Магмы (он же ГОСТ 28187-89):
KEY = c2bb428f981f30d8e623db786d9bd780e7d9f785a950211530142ae46fab8dce SALT = C16E378ABE17ADBC
Записываем шифрованный ключ в KEY.in
и через OpenSSL декодируем:
openssl enc -engine gost -d -gost89 -in KEY.in -out KEY.out -nosalt -K ключ -iv солб
В случае успеха в файле KEY.out
будет лежать практически расшифрованный криптоключ:
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
Данная структура это "блоб" приватного ключа, который описан в рекомендациях ТК-26 и отсюда можно выделить следующие поля:
UKM = FEF0268E68E6A7EA CEK_ENC = 7987275594A59F491E62F636F794BDD49A5CD547E0D901DF3AD58DA9EFFC2657 CEK_MAC = 68369E8A
Как я понял из рекомендаций необходимо сделать unwrap ключа, GoGost не умеет это делать, но зато умеет PyGost, сделав указав параметры выше и KEY
получил 31967658c0647acdbd2c8a8d55cc031803208d94292c16221f68d9d7caa5d73e
. В каком направлении двигаться дальше понятия не имею.
Стоит также отметить что гостовский движок для OpenSSL поддерживает расшифровку данного "блоба", но как отметил vGimly, так и я убедился в личном разговоре - автор движка полностью незаинтересован в данной затее. Такие вот дела. To be continued....
UPD#1 - как оказалось я немножко слепой и не обратил внимание что результат unwrap это и есть приватный ключ, только вместо 04 в начале стоит 3, получается в итоге приватный ключ 042031967658C0647ACDBD2C8A8D55CC031803208D94292C16221F68D9D7CAA5D73E
таким образом тему можно считать закрытой
UPD#2 - Как выяснилось это все работало только на ГОСТ 2001, а на ГОСТ 2012 это не работает :)
Ссылки
Статья vGimly - https://vgimly.blogspot.com/2019/03/2.html
Мой телеграмм канал - https://t.me/li0ard_notes