{"id":292106,"date":"2019-07-16T09:00:34","date_gmt":"2019-07-16T09:00:34","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=292106"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=292106","title":{"rendered":"\u041a\u0440\u0438\u043f\u0442\u043e\u0410\u0420\u041c \u043d\u0430 \u0431\u0430\u0437\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 PKCS#12. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0434\u043f\u0438\u0441\u0438 CadES-X Long Type 1. \u0427\u0430\u0441\u0442\u044c 3"},"content":{"rendered":"\n<div class=\"post__text post__text-html js-mediator-article\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/si\/bu\/q7\/sibuq775i85ksk84xdzzzqjpc_8.png\" align=\"left\" alt=\"image\"> \u041f\u0440\u043e\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u0430, \u043d\u0430\u0447\u0430\u0442\u0430\u044f \u043a\u0430\u043a <a href=\"https:\/\/habr.com\/ru\/post\/440754\/\"><font color=\"blue\">\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0449\u0438\u043a \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432<\/font><\/a>, \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/457288\/\"><font color=\"blue\">\u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438 PKCS#11<\/font><\/a> \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 (PKCS#10) \u043d\u0430 \u043a\u0432\u0430\u043b\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442, \u043f\u043e\u043f\u043e\u043b\u043d\u0438\u043b\u0430\u0441\u044c, \u043a\u0430\u043a \u0438 \u0431\u044b\u043b\u043e \u0437\u0430\u044f\u0432\u043b\u0435\u043d\u043e, \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438 PKCS#12.   <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0418\u0442\u0430\u043a, \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438 PKCS#12 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u0430 cryptoarmpkcs :<\/b><\/p>\n<div class=\"spoiler_text\">\n<ul>\n<li> <a href=\"http:\/\/museum.lissi-crypto.ru\/docs\/guipkcs7_tclpkcs11\/cryptoarmpkcs_linux32.tar.bz2\">Linux32<\/a><\/li>\n<li> <a href=\"http:\/\/museum.lissi-crypto.ru\/docs\/guipkcs7_tclpkcs11\/cryptoarmpkcs_linux64.tar.bz2\">Linux64<\/a><\/li>\n<li> <a href=\"http:\/\/museum.lissi-crypto.ru\/docs\/guipkcs7_tclpkcs11\/cryptoarmpkcs_mac.tar.bz2\">OS X<\/a><\/li>\n<li> <a href=\"http:\/\/museum.lissi-crypto.ru\/docs\/guipkcs7_tclpkcs11\/cryptoarmpkcs_win32.exe\">WIN32<\/a><\/li>\n<li> <a href=\"http:\/\/museum.lissi-crypto.ru\/docs\/guipkcs7_tclpkcs11\/cryptoarmpkcs_win64.exe\">WIN64<\/a><\/li>\n<\/ul>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0443\u0442\u0438\u043b\u0438\u0442\u0443 cryptoarmpkcs \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u00abPKCS12\u00bb:<a name=\"habracut\"><\/a><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/yc\/pz\/wp\/ycpzwpf3bbuztgmjpkvfut8nbbc.png\"><\/p>\n<p>  \u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0443\u0442\u0438\u043b\u0438\u0442\u0430, \u0438\u043c\u0435\u044f \u043d\u0430 \u0440\u0443\u043a\u0430\u0445 <a href=\"https:\/\/habr.com\/ru\/post\/440882\/\"><font color=\"blue\">\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 PKCS#12<\/font><\/a>:<br \/>   \u2014 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430, \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043a\u043b\u0438\u043a\u043d\u0443\u0442\u044c \u043d\u0430 \u0438\u043a\u043e\u043d\u043a\u0443, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0443\u044e\u0441\u044f \u0441\u043f\u0440\u0430\u0432\u0430 \u043e\u0442 \u043f\u043e\u043b\u044f \u00abfriendlyName\u00bb;<br \/>   \u2014 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0438\u0437 \u0442\u0440\u0435\u0445 \u0442\u0438\u043f\u043e\u0432 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043e\u043e\u0439 \u043f\u043e\u0434\u043f\u0438\u0441\u0438 CAdes:<br \/>   \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0432 \u0444\u0430\u0439\u043b\u0435;<br \/>   \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d\u0435;<br \/>   \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0437\u0430\u043a\u0440\u044b\u0442\u044b\u0439 \u043a\u043b\u044e\u0447 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d\u0435.<br \/>  \u0414\u0432\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u043c \u0442\u043e\u043a\u0435\u043d\u0435 (\u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 PKCS#11 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d \u0442\u043e\u043a\u0435\u043d). \u041e\u0442\u043c\u0435\u0442\u0438\u043c \u0442\u0430\u043a\u0436\u0435, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u0440\u044b\u0442\u044b\u0435 \u043a\u043b\u044e\u0447\u0438. \u041d\u043e \u044d\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u0430\u0436\u043d\u0430, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c <a href=\"https:\/\/habr.com\/ru\/post\/403563\/\"><font color=\"blue\">\u0441 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u043c\u0438 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438 PKCS#11<\/font><\/a>.<br \/>  \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 PKCS#11, \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 PKCS#12 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u043e\u0439, \u0442.\u0435. \u043e\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0445\u0440\u0430\u043d\u0438\u0442 \u0432 \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435 (\u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043d\u0430 \u043f\u0430\u0440\u043e\u043b\u0435) \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u044b\u0439 \u043a\u043b\u044e\u0447 \u043a \u043d\u0435\u043c\u0443 \u0438 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u0422\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443 \u043d\u0430 \u0431\u0430\u0437\u0435 \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u043e\u0439 \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u044b <a href=\"https:\/\/tc26.ru\/\"><font color=\"blue\">\u0422\u041a-26<\/font><\/a> \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0435 \u00ab\u0420 50.1.112-2016. <a href=\"https:\/\/tc26.ru\/standard\/rs\/%D0%A0%2050.1.112-2016.pdf\"><font color=\"blue\">\u0422\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440<\/font><\/a>.\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d \u0438 \u0432\u0432\u0435\u0434\u0435\u043d \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u041f\u0440\u0438\u043a\u0430\u0437\u043e\u043c \u0424\u0435\u0434\u0435\u0440\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0441\u0442\u0432\u0430 \u043f\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0440\u0435\u0433\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0438 \u043c\u0435\u0442\u0440\u043e\u043b\u043e\u0433\u0438\u0438 \u043e\u0442 23 \u043d\u043e\u044f\u0431\u0440\u044f 2016 \u0433. No 1753-\u0441\u0442.<br \/>  \u041a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 PKCS#12 \u0438\u0437 \u043a\u0440\u0438\u043f\u0442\u043e\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 MS CSP <a href=\"https:\/\/habr.com\/ru\/post\/440882\/\"><font color=\"blue\">\u0445\u043e\u0440\u043e\u0448\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e<\/font><\/a> \u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0441\u0442\u0430\u0442\u0435\u0439 \u043d\u0430 \u0425\u0430\u0431\u0440.<br \/>  \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 PKCS#12 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u0430 tcl, \u043f\u043e\u043c\u0438\u043c\u043e \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e <a href=\"https:\/\/github.com\/a513\/TclPKCS11\"><font color=\"blue\">TclPKCS11<\/font><\/a>. \u041f\u0435\u0440\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 Lcc, \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u043e\u0439 \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439 \u0422\u041a-26.   <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u043c\u0430\u043d\u0434\u044b, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435  \u043f\u0430\u043a\u0435\u0442\u043e\u043c Lcc \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0437\u0434\u0435\u0441\u044c:<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/\/ Digest commands \/\/ gost3411_2012 Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012\", gost3411_2012_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_ctx_create\", gost3411_2012_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_ctx_update\", gost3411_2012_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_ctx_final\", gost3411_2012_ctx_final_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_ctx_delete\", gost3411_2012_ctx_delete_Cmd, NULL, NULL); \/\/ gost3411_94 Tcl_CreateObjCommand(interp, \"lcc_gost3411_94\", gost3411_94_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_ctx_create\", gost3411_94_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_ctx_update\", gost3411_94_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_ctx_final\", gost3411_94_ctx_final_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_ctx_delete\", gost3411_94_ctx_delete_Cmd, NULL, NULL); \/\/ sha1 Tcl_CreateObjCommand(interp, \"lcc_sha1\", sha1_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_sha1_ctx_create\", sha1_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_sha1_ctx_update\", sha1_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_sha1_ctx_final\", sha1_ctx_final_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_sha1_ctx_delete\", sha1_ctx_delete_Cmd, NULL, NULL); \/\/ HMAC commands \/\/ gost3411hmac Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_hmac\", gost3411_2012_hmac_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_hmac_ctx_create\", gost3411_2012_hmac_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_hmac_ctx_update\", gost3411_2012_hmac_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_hmac_ctx_final\", gost3411_2012_hmac_ctx_final_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_hmac_ctx_delete\", gost3411_2012_hmac_ctx_delete_Cmd, NULL, NULL); \/\/ gost3411_94_hmac Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_hmac\", gost3411_94_hmac_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_hmac_ctx_create\", gost3411_94_hmac_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_hmac_ctx_update\", gost3411_94_hmac_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_hmac_ctx_final\", gost3411_94_hmac_ctx_final_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_hmac_ctx_delete\", gost3411_94_hmac_ctx_delete_Cmd, NULL, NULL); \/\/ PKCS#5 commands Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_pkcs5\", gost3411_2012_pkcs5_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_pkcs5\", gost3411_94_pkcs5_Cmd, NULL, NULL); \/\/ PKCS#12 PBA Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_pkcs12_pba\", gost3411_94_pkcs12_pba_Cmd, NULL, NULL); \/\/ gost3411_2012 KDF Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_256_kdf\", gost3411_2012_256_kdf_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_256_kdf_tree\", gost3411_2012_256_kdf_tree_Cmd, NULL, NULL); \/\/ PRF TLS Tcl_CreateObjCommand(interp, \"lcc_gost3411_94_prf_tls\", gost3411_94_prf_tls_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_256_prf_tls\", gost3411_2012_256_prf_tls_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3411_2012_512_prf_tls\", gost3411_2012_512_prf_tls_Cmd, NULL, NULL); \/\/ gost3410-2012 commands \/\/ 256 bits Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_256_getGroupByOid\", gost3410_2012_256_getGroupByOid_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_256_getGroupByDerOid\", gost3410_2012_256_getGroupByDerOid_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_256_getGroupById\", gost3410_2012_256_getGroupById_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_256_createPrivateKey\", gost3410_2012_256_createPrivateKey_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_256_createPublicKey\", gost3410_2012_256_createPublicKey_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_256_sign\", gost3410_2012_256_sign_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_256_verify\", gost3410_2012_256_verify_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_256_vko\", gost3410_2012_256_vko_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_256_keg\", gost3410_2012_256_keg_Cmd, NULL, NULL); \/\/ 512 bits Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_512_getGroupByOid\", gost3410_2012_512_getGroupByOid_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_512_getGroupByDerOid\", gost3410_2012_512_getGroupByDerOid_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_512_getGroupById\", gost3410_2012_512_getGroupById_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_512_createPrivateKey\", gost3410_2012_512_createPrivateKey_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_512_createPublicKey\", gost3410_2012_512_createPublicKey_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_512_sign\", gost3410_2012_512_sign_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_512_verify\", gost3410_2012_512_verify_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_512_vko\", gost3410_2012_512_vko_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost3410_2012_512_keg\", gost3410_2012_512_keg_Cmd, NULL, NULL); \/\/ gost3410-2001-vko (with 3411-94) Tcl_CreateObjCommand(interp, \"lcc_gost3410_2001_vko\", gost3410_2001_vko_Cmd, NULL, NULL); \/\/ Magma commands \/\/ ECB Tcl_CreateObjCommand(interp, \"lcc_magma_ecb_ctx_create\", magma_ecb_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_ecb_ctx_update\", magma_ecb_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_ecb_ctx_delete\", magma_ecb_ctx_delete_Cmd, NULL, NULL); \/\/ CBC Tcl_CreateObjCommand(interp, \"lcc_magma_cbc_ctx_create\", magma_cbc_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_cbc_ctx_update\", magma_cbc_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_cbc_ctx_delete\", magma_cbc_ctx_delete_Cmd, NULL, NULL); \/\/ CTR Tcl_CreateObjCommand(interp, \"lcc_magma_ctr_ctx_create\", magma_ctr_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_ctr_ctx_update\", magma_ctr_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_ctr_ctx_delete\", magma_ctr_ctx_delete_Cmd, NULL, NULL); \/\/ OFB Tcl_CreateObjCommand(interp, \"lcc_magma_ofb_ctx_create\", magma_ofb_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_ofb_ctx_update\", magma_ofb_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_ofb_ctx_delete\", magma_ofb_ctx_delete_Cmd, NULL, NULL); \/\/ CFB Tcl_CreateObjCommand(interp, \"lcc_magma_cfb_ctx_create\", magma_cfb_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_cfb_ctx_update\", magma_cfb_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_cfb_ctx_delete\", magma_cfb_ctx_delete_Cmd, NULL, NULL); \/\/ OMAC Tcl_CreateObjCommand(interp, \"lcc_magma_omac_ctx_create\", magma_omac_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_omac_ctx_update\", magma_omac_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_omac_ctx_final\", magma_omac_ctx_final_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_omac_ctx_delete\", magma_omac_ctx_delete_Cmd, NULL, NULL); \/\/ CTR_ACPKM Tcl_CreateObjCommand(interp, \"lcc_magma_ctr_acpkm_ctx_create\", magma_ctr_acpkm_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_ctr_acpkm_ctx_update\", magma_ctr_acpkm_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_ctr_acpkm_ctx_delete\", magma_ctr_acpkm_ctx_delete_Cmd, NULL, NULL); \/\/ OMAC_ACPKM Tcl_CreateObjCommand(interp, \"lcc_magma_omac_acpkm_ctx_create\", magma_omac_acpkm_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_omac_acpkm_ctx_update\", magma_omac_acpkm_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_omac_acpkm_ctx_final\", magma_omac_acpkm_ctx_final_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_omac_acpkm_ctx_delete\", magma_omac_acpkm_ctx_delete_Cmd, NULL, NULL); \/\/ key export\/import Tcl_CreateObjCommand(interp, \"lcc_magma_key_export\", magma_key_export_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_magma_key_import\", magma_key_import_Cmd, NULL, NULL); \/\/ Kuznyechik commands \/\/ ECB Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ecb_ctx_create\", kuznyechik_ecb_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ecb_ctx_update\", kuznyechik_ecb_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ecb_ctx_delete\", kuznyechik_ecb_ctx_delete_Cmd, NULL, NULL); \/\/ CBC Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_cbc_ctx_create\", kuznyechik_cbc_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_cbc_ctx_update\", kuznyechik_cbc_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_cbc_ctx_delete\", kuznyechik_cbc_ctx_delete_Cmd, NULL, NULL); \/\/ CTR Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ctr_ctx_create\", kuznyechik_ctr_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ctr_ctx_update\", kuznyechik_ctr_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ctr_ctx_delete\", kuznyechik_ctr_ctx_delete_Cmd, NULL, NULL); \/\/ OFB Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ofb_ctx_create\", kuznyechik_ofb_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ofb_ctx_update\", kuznyechik_ofb_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ofb_ctx_delete\", kuznyechik_ofb_ctx_delete_Cmd, NULL, NULL); \/\/ CFB Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_cfb_ctx_create\", kuznyechik_cfb_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_cfb_ctx_update\", kuznyechik_cfb_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_cfb_ctx_delete\", kuznyechik_cfb_ctx_delete_Cmd, NULL, NULL); \/\/ OMAC Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_omac_ctx_create\", kuznyechik_omac_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_omac_ctx_update\", kuznyechik_omac_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_omac_ctx_final\", kuznyechik_omac_ctx_final_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_omac_ctx_delete\", kuznyechik_omac_ctx_delete_Cmd, NULL, NULL); \/\/ CTR_ACPKM Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ctr_acpkm_ctx_create\", kuznyechik_ctr_acpkm_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ctr_acpkm_ctx_update\", kuznyechik_ctr_acpkm_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_ctr_acpkm_ctx_delete\", kuznyechik_ctr_acpkm_ctx_delete_Cmd, NULL, NULL); \/\/ OMAC_ACPKM Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_omac_acpkm_ctx_create\", kuznyechik_omac_acpkm_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_omac_acpkm_ctx_update\", kuznyechik_omac_acpkm_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_omac_acpkm_ctx_final\", kuznyechik_omac_acpkm_ctx_final_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_omac_acpkm_ctx_delete\", kuznyechik_omac_acpkm_ctx_delete_Cmd, NULL, NULL); \/\/ key export\/import Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_key_export\", kuznyechik_key_export_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_kuznyechik_key_import\", kuznyechik_key_import_Cmd, NULL, NULL); \/\/ gost28147 commands Tcl_CreateObjCommand(interp, \"lcc_gost28147_getParamsByOid\", gost28147_getParamsByOid_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_getParamsByDerOid\", gost28147_getParamsByDerOid_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_getParamsById\", gost28147_getParamsById_Cmd, NULL, NULL); \/\/ ECB Tcl_CreateObjCommand(interp, \"lcc_gost28147_ecb_ctx_create\", gost28147_ecb_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_ecb_ctx_update\", gost28147_ecb_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_ecb_ctx_delete\", gost28147_ecb_ctx_delete_Cmd, NULL, NULL); \/\/ CBC Tcl_CreateObjCommand(interp, \"lcc_gost28147_cbc_ctx_create\", gost28147_cbc_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_cbc_ctx_update\", gost28147_cbc_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_cbc_ctx_delete\", gost28147_cbc_ctx_delete_Cmd, NULL, NULL); \/\/ CNT Tcl_CreateObjCommand(interp, \"lcc_gost28147_cnt_ctx_create\", gost28147_cnt_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_cnt_ctx_update\", gost28147_cnt_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_cnt_ctx_delete\", gost28147_cnt_ctx_delete_Cmd, NULL, NULL); \/\/ CFB Tcl_CreateObjCommand(interp, \"lcc_gost28147_cfb_ctx_create\", gost28147_cfb_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_cfb_ctx_update\", gost28147_cfb_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_cfb_ctx_delete\", gost28147_cfb_ctx_delete_Cmd, NULL, NULL); \/\/ OMAC Tcl_CreateObjCommand(interp, \"lcc_gost28147_omac_ctx_create\", gost28147_omac_ctx_create_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_omac_ctx_update\", gost28147_omac_ctx_update_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_omac_ctx_final\", gost28147_omac_ctx_final_Cmd, NULL, NULL); Tcl_CreateObjCommand(interp, \"lcc_gost28147_omac_ctx_delete\", gost28147_omac_ctx_delete_Cmd, NULL, NULL); \/\/ KDF Tcl_CreateObjCommand(interp, \"lcc_gost28147_kdf\", gost28147_kdf_Cmd, NULL, NULL);<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 \u0435\u0441\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0413\u041e\u0421\u0422 \u0420 34.10-2012 \u0438 \u0413\u041e\u0421\u0422 \u0420 34.11-2012, \u043d\u043e \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u041a\u0443\u0437\u043d\u0435\u0447\u0438\u043a \u0438 \u041c\u0430\u0433\u043c\u0430.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/8u\/qg\/hk\/8uqghkhec2x6wgcfitomv8nl7vu.png\" align=\"left\">\u0412\u0442\u043e\u0440\u043e\u0439 \u043f\u0430\u043a\u0435\u0442 GostPfx \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 PKCS#11. \u042d\u0442\u0438 \u043f\u0430\u043a\u0435\u0442\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u0431\u0430\u0437\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438\u0437 \u0441\u043e\u0441\u0442\u0430\u0432\u0430 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0421\u041a\u0417\u0418. \u042d\u0442\u0430 \u0441\u043a\u0440\u0443\u043f\u0443\u043b\u0435\u0437\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u0430 \u043c\u043e\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u0433\u043e\u0439 \u0438 \u0442\u043e\u0432\u0430\u0440\u0438\u0449\u0435\u043c, \u0430\u0432\u0442\u043e\u0440\u043e\u043c <a href=\"https:\/\/habr.com\/ru\/post\/310122\/\"><font color=\"blue\">\u043c\u043d\u043e\u0433\u0438\u0445 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0439<\/font> <\/a>\u043a \u043d\u0430\u0448\u0438\u043c \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f\u043c \u0411\u043b\u0430\u0436\u043d\u043e\u0432\u044b\u043c \u0412.\u042e. \u0418\u043c\u0435\u043d\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u044d\u0442\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c\u0443 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u0443\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0435 \u0432 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0435\u043e\u0431\u043e\u0440\u043e\u0442\u0435. \u041f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c PKCS#12 \u043d\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u043e\u043c \u044f\u0437\u044b\u043a\u0435 Tcl \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u0430\u0441\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c. \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/habr.com\/ru\/post\/415423\/\"><font color=\"blue\">openssl<\/font><\/a> \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u043e\u0439 \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438, \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u0433\u043e \u0432 DER-\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435, \u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u0430\u043a\u0435\u0442\u0430 NSS, \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c BER-\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f tag-\u0438 \u0441 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u043e\u0439 (\u0432 \u043f\u043e\u043b\u0435 \u0434\u043b\u0438\u043d\u044b tag-\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 0x80). \u0418 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430 asn \u044f\u0437\u044b\u043a\u0430 Tcl \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 PKCS#12 \u0432\u044b\u044f\u0441\u043d\u043e\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 asn-\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435 BER:  <\/p>\n<pre><code class=\"plaintext\">    if {$length == 0x080} {         return -code error \"Indefinite length BER encoding not yet supported\"     }<\/code><\/pre>\n<p>  \u041f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u043f\u0430\u043a\u0435\u0442\u0430 asn \u043f\u043e\u043a\u0430\u0437\u0430\u043b, \u0447\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u0434\u043c\u0435\u043d\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e ::asn::asnGetLength:  <\/p>\n<pre><code class=\"plaintext\">package require asn #\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e rename ::asn::asnGetLength ::asn::asnGetLength.orig #\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e proc ::asn::asnGetLength {data_var length_var} {     upvar 1 $data_var data  $length_var length     asnGetByte data length     if {$length == 0x080} { #\u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u0438\u043d\u044b \u0442\u044d\u0433\u0430 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b # Indefinite length BER encoding yet supported \tset lendata [string length $data] \tset tvl 1 \tset length 0 \tset data1 $data \twhile {$tvl != 0} { \t    ::asn::asnGetByte data1 peek_tag  \t    ::asn::asnPeekByte data1 peek_tag1 #\u041a\u043e\u043d\u0435\u0446 \u0442\u044d\u0433\u0430 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \t    if {$peek_tag == 0x00 &amp;&amp; $peek_tag1 == 0x00} { \t\tincr tvl -1 \t\t::asn::asnGetByte data1 tag  \t\tincr length 2 \t\tcontinue \t    } #\u041d\u0430\u0447\u0430\u043b\u043e \u0442\u044d\u0433\u0430 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \t    if {$peek_tag1 == 0x80} { \t\tincr tvl \t\tif {$tvl &gt; 0} { \t\t    incr length 2 \t\t} \t\t::asn::asnGetByte data1 tag  \t    } else { \t\tset l1 [string length $data1] \t\t::asn::asnGetLength data1 ll \t\tset l2 [string length $data1] \t\tset l3 [expr $l1 - $l2] \t\tincr length $l3 \t\tincr length $ll \t\tincr length \t\t::asn::asnGetBytes data1 $ll strt \t    } \t} \treturn #        return -code error \"Indefinite length BER encoding not yet supported\"     }     if {$length &gt; 0x080} {     # The retrieved byte is a prefix value, and the integer in the     # lower nibble tells us how many bytes were used to encode the     # length data following immediately after this prefix.         set len_length [expr {$length &amp; 0x7f}]         if {[string length $data] &lt; $len_length} {             return -code error \\ \t\t\"length information invalid, not enough octets left\"          }         asnGetBytes data $len_length lengthBytes         switch $len_length {             1 { binary scan $lengthBytes     cu length }             2 { binary scan $lengthBytes     Su length }             3 { binary scan \\x00$lengthBytes Iu length }             4 { binary scan $lengthBytes     Iu length }             default {                                 binary scan $lengthBytes H* hexstr \t\tscan $hexstr %llx length             }         }     }     return }<\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0430\u044f \u043f\u043e\u0434\u043c\u0435\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c tag-\u0438 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b.   <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0414\u043b\u044f \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 PKCS#12 \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043f\u0430\u043a\u0435\u0442 GostPfx:<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\"> set OS [lindex $tcl_platform(os) 0] # \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442 Lcc # \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442 Lrnd  namespace eval ::GostPfx {   namespace export pfxParse pfxMacDataParse pfxGetAuthSafeTbs pfxHmacVerify   namespace export pfxTbsParse pfxPbeDataParse pfxPbeKey pfxDataDecrypt   namespace export pfxIdentityDataParse pfxCertBagsParse pfxKeyBagsParse   namespace export pfxKeyBagDecrypt pfxKeyDataParse pfxDataEncrypt   namespace export pfxCreateSingleCertKey pfxGetSingleCertKey pfxCreateLocalKeyID       variable INTEGER_TAG 2   variable OCTET_STRING_TAG 4   variable OBJECT_IDENTIFIER_TAG 6   variable SEQUENCE_TAG 16   variable SET_TAG 17   variable BMP_STRING_TAG 30     variable oid_Gost_3411_94 \"1 2 643 2 2 9\"   variable oid_Gost3411_2012_512 \"1 2 643 7 1 1 2 3\"   variable oid_pkcs7_data \"1 2 840 113549 1 7 1\"   variable oid_pkcs7_encrypted_data \"1 2 840 113549 1 7 6\"   variable oid_pkcs5PBES2 \"1 2 840 113549 1 5 13\"   variable oid_pBKDF2 \"1 2 840 113549 1 5 12\"   variable oid_HMACgostR3411_94 \"1 2 643 2 2 10\"   variable oid_tc26_hmac_gost_3411_2012_512 \"1 2 643 7 1 1 4 2\"   variable oid_gost28147_89 \"1 2 643 2 2 21\"   variable oid_PKCS12CertificateBag \"1 2 840 113549 1 12 10 1 3\"   variable oid_PKCS9x509Certificate \"1 2 840 113549 1 9 22 1\"   variable oid_friendlyName \"1 2 840 113549 1 9 20\"   variable oid_localKeyID \"1 2 840 113549 1 9 21\"   variable oid_pkcs8ShroudedKeyBag \"1 2 840 113549 1 12 10 1 2\"   variable oid_tc26_gost_28147_89_param_A \"1 2 643 7 1 2 5 1 1\"   variable oid_GostR3410_2001 \"1 2 643 2 2 19\"   variable oid_GostR3411_94_with_GostR3410_2001 \"1 2 643 2 2 3\"   variable oid_tc26_gost3410_2012_256 \"1 2 643 7 1 1 1 1\"   variable oid_tc26_signwithdigest_gost3410_2012_256 \"1 2 643 7 1 1 3 2\"   variable oid_tc26_gost3410_2012_512 \"1 2 643 7 1 1 1 2\"   variable oid_tc26_signwithdigest_gost3410_2012_256 \"1 2 643 7 1 1 3 3\"    } proc reverse {args} {     set res [list]     if {[llength $args] == 1} {         set args [lindex $args 0]     }     foreach elem $args {         set res [linsert $res 0 $elem]     }     return $res } #----------------------------------------------------------------------------- # asnGetOctetString : Retrieve arbitrary string. #----------------------------------------------------------------------------- proc ::asn::asnGet24OctetString {data_var string_var} {     # Here we need the full decoder for length data.      upvar 1 $data_var data $string_var string          asnGetByte data tag     if {$tag != 0x24} {          return -code error \\             [format \"Expected Octet String 24 (0x24), but got %02x\" $tag]     }     asnGetLength data length     asnGetBytes  data $length temp     set string $temp     return }   # indata =&gt; dict: authSafe macData digestAlg digestParamset hmac  proc ::GostPfx::pfxParse {indata} {   variable INTEGER_TAG    variable SEQUENCE_TAG      set data $indata   set dres [dict create]   set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $SEQUENCE_TAG} {     asn::asnGetSequence data seqValue     set tag_len [asn::asnPeekTag seqValue tag_var tag_type_var constr_var]      if {$tag_var == $INTEGER_TAG} {       asn::asnGetInteger seqValue version       dict set dres \"version\" $version     } else {       error \"pfxParse: Invalid PFX DER structure 1 tag=$tag_var\"     }         set tag_len [asn::asnPeekTag seqValue tag_var tag_type_var constr_var]     if {$tag_var == $SEQUENCE_TAG} {       asn::asnGetSequence seqValue authSafe       dict set dres \"authSafe\" $authSafe     } else {       error \"pfxParse: Invalid PFX DER structure 2\"     }         set tag_len [asn::asnPeekTag seqValue tag_var tag_type_var constr_var]     # Optional     if {$tag_var == $SEQUENCE_TAG} {       asn::asnGetSequence seqValue macData       dict set dres \"macData\" $macData     }   } else {     error \"pfxParse: Invalid PFX DER structure 3\"   }   return $dres }  # macData =&gt; dict: salt iter  proc ::GostPfx::pfxMacDataParse {macData} {   variable INTEGER_TAG    variable OCTET_STRING_TAG    variable OBJECT_IDENTIFIER_TAG    variable SEQUENCE_TAG    set data $macData   set dres [dict create]   set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $SEQUENCE_TAG} {     asn::asnGetSequence data seqValue1     set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]     if {$tag_var == $SEQUENCE_TAG} {       asn::asnGetSequence seqValue1 seqValue2       set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]       if {$tag_var == $OBJECT_IDENTIFIER_TAG} {         asn::asnGetObjectIdentifier seqValue2 digestAlg         dict set dres \"digestAlg\" $digestAlg       } else {         error \"pfxMacDataParse: Invalid MAC data structure\"       }         set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]       # Optional       if {$tag_var == $OBJECT_IDENTIFIER_TAG} {         asn::asnGetObjectIdentifier seqValue2 digestParamset         dict set dres \"digestParamset\" $digestParamset       }     }     set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]     if {$tag_var == $OCTET_STRING_TAG} {       asn::asnGetOctetString seqValue1 hmac       dict set dres \"hmac\" $hmac         }  else {       error \"pfxMacDataParse: Invalid MAC data structure\"     }     } else {     error \"pfxMacDataParse: Invalid MAC data structure\"   }     set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $OCTET_STRING_TAG} {     asn::asnGetOctetString data salt     dict set dres \"salt\" $salt   } else {     error \"pfxMacDataParse: Invalid MAC data structure\"   }     set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $INTEGER_TAG} {     asn::asnGetInteger data iter     dict set dres \"iter\" $iter   } else {     error \"pfxMacDataParse: Invalid MAC data structure\"   }       return $dres  }  # authSafeData =&gt; tbs proc ::GostPfx::pfxGetAuthSafeTbs {authSafeData} {   variable OCTET_STRING_TAG    variable OBJECT_IDENTIFIER_TAG    set data $authSafeData   set tbs \"\"   set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $OBJECT_IDENTIFIER_TAG} {     asn::asnGetObjectIdentifier data oid   } else {     error \"pfxGetAuthSafeTbs: Invalid AuthSafe structure\"   }    set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_type_var == \"CONTEXT\"} {     asn::asnGetContext data contextNumber contextVar encoding_type     ::asn::asnPeekByte contextVar peek_tag      ::asn::asnPeekByte contextVar peek_tag1 1 \tif {$peek_tag == 0x24 &amp;&amp; $peek_tag1 == 0x80} { \t    set contextVar1 $contextVar \t    ::asn::asnGet24OctetString contextVar1 contextVar \t    puts \"pfxGetAuthSafeTbs=0x240x80\" \t}     set tag_len [asn::asnPeekTag contextVar tag_var tag_type_var constr_var]      if {$tag_var == $OCTET_STRING_TAG} {       asn::asnGetOctetString contextVar tbs     } else {       error \"pfxGetAuthSafeTbs: Invalid AuthSafe structure\"     }   } else {     error \"pfxGetAuthSafeTbs: Invalid AuthSafe structure\"   }   return $tbs }  # \u0414\u043b\u044f \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 PBA \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 UTF-16 \u0431\u0435\u0437 BOM # \u0441 \u0434\u0432\u0443\u043c\u044f \u043d\u0443\u043b\u0435\u0432\u044b\u043c\u0438 \u0431\u0430\u0439\u0442\u0430\u043c\u0438 \u0432 \u043a\u043e\u043d\u0446\u0435. # \u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u043e\u043b\u044f \u0432 unicode \u043d\u0443\u0436\u043d\u043e \u043f\u0430\u043f\u0430\u0440\u043d\u043e \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0431\u0430\u0439\u0442\u044b # \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0432\u0430 \u043d\u0443\u043b\u0435\u0432\u044b\u0445 \u0431\u0430\u0439\u0442\u0430 \u0432 \u043a\u043e\u043d\u0435\u0446 \u0441\u0442\u0440\u043e\u043a\u0438.    proc ::GostPfx::passwordToUtf16 {password} {   binary scan [encoding convertto unicode $password] c* bytes   set bytes_len [llength $bytes]   for {set i 0} {$i &lt; $bytes_len} {incr i 2} {     set left [lindex $bytes $i]     set right [lindex $bytes [expr {$i+1}]]     lset bytes $i $right     lset bytes [expr {$i+1}] $left   }   lappend bytes 0 0   set out [binary format c* $bytes]   return $out }  # returns 1 or 0 proc ::GostPfx::pfxHmacVerify {tbs hmac password hmacDigestAlg hmacKeySalt hmacKeyIter} {   variable oid_Gost_3411_94    variable oid_Gost3411_2012_512      if {$hmacDigestAlg == $oid_Gost_3411_94} {       set passwordUtf16 [passwordToUtf16 $password]     set hmacPbaKey [lcc_gost3411_94_pkcs12_pba $passwordUtf16 $hmacKeySalt $hmacKeyIter]     set hmacPba [lcc_gost3411_94_hmac $tbs $hmacPbaKey]     if {$hmacPba != $hmac} {       # \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0422\u041a 26 v 1.0 \u043a\u043b\u044e\u0447 HMAC \u043d\u0443\u0436\u043d\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443       set hmacPbaKey [string range [lcc_gost3411_94_pkcs5 $password $hmacKeySalt $hmacKeyIter 96] 64 95]       set hmacPba [lcc_gost3411_94_hmac $tbs $hmacPbaKey]       if {$hmacPba != $hmac} {         #puts \"hmacPba != hmac\"       } else {         #puts \"TC 26 v 1.0 PBA HMAC OK\"         return 1       }     } else {       #puts \"Obsolete PBA HMAC OK\"       return 1     }   } else {     if {$hmacDigestAlg == $oid_Gost3411_2012_512} {       set hmacPbaKey [string range [lcc_gost3411_2012_pkcs5 $password $hmacKeySalt $hmacKeyIter 96] 64 95]       set hmacPba [lcc_gost3411_2012_hmac 64 $tbs $hmacPbaKey]       if {$hmacPba != $hmac} {         #puts \"hmacPba != hmac\"       } else {         #puts \"TC 26 v 2.0 PBA HMAC OK\"         return 1       }     } else {       error \"pfxHmacVerify: Unsupported digest algorithm: $hmacDigestAlg\"     }   }   return 0 }  proc ::GostPfx::p7mParse {p7m} {   variable OCTET_STRING_TAG    variable OBJECT_IDENTIFIER_TAG    variable SEQUENCE_TAG    variable INTEGER_TAG   variable oid_pkcs7_data       set seqValue2 $p7m     set dres [dict create]           set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]           if {$tag_type_var == \"CONTEXT\"} {             asn::asnGetContext seqValue2 contextNumber contextData encoding_type             set tag_len [asn::asnPeekTag contextData tag_var tag_type_var constr_var]             if {$tag_var == $SEQUENCE_TAG} {               asn::asnGetSequence contextData seqValue3               set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]               if {$tag_var == $INTEGER_TAG} {                 asn::asnGetInteger seqValue3 version                 set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]                 if {$tag_var == $SEQUENCE_TAG} {                   asn::asnGetSequence seqValue3 seqValue4                   set tag_len [asn::asnPeekTag seqValue4 tag_var tag_type_var constr_var]                   if {$tag_var == $OBJECT_IDENTIFIER_TAG} {                     asn::asnGetObjectIdentifier seqValue4 oid2                     if {$oid2 == $oid_pkcs7_data} {                       set tag_len [asn::asnPeekTag seqValue4 tag_var tag_type_var constr_var]                       if {$tag_var == $SEQUENCE_TAG} {                         asn::asnGetSequence seqValue4 certsPbeData                                           dict set dres \"certsPbeData\" $certsPbeData                         set tag_len [asn::asnPeekTag seqValue4 tag_var tag_type_var constr_var]                         if {$tag_type_var == \"CONTEXT\"} { \t\t\t  ::asn::asnPeekByte seqValue4 peek_tag  \t\t\t  ::asn::asnPeekByte seqValue4 peek_tag1 1 \t\t\t  if {$peek_tag == 0xA0 &amp;&amp; $peek_tag1 == 0x80} { \t\t\t\tset seqValue4_80 $seqValue4 \t\t\t\tset seqValue4 [string range $seqValue4_80 2 {end-2}]                         \tasn::asnGetOctetString seqValue4 encrCerts  \t\t\t  } else {                             asn::asnGetContext seqValue4 contextNumber encrCerts encoding_type                           }                           dict set dres \"encrCerts\" $encrCerts                         } else {                           error \"pfxTbsParse: Invalid encrypted certificates structure 1\"                         }                         } else {                         error \"pfxTbsParse: Invalid encrypted certificates structure 2\"                       }                     } else {                       error \"pfxTbsParse: Invalid encrypted certificates structure 3\"                     }                   } else {                     error \"pfxTbsParse: Invalid encrypted certificates structure 4\"                   }                 } else {                   error \"pfxTbsParse: Invalid encrypted certificates structure 5\"                 }               } else {                 error \"pfxTbsParse: Invalid encrypted certificates structure 6\"               }             } else {               error \"pfxTbsParse: Invalid encrypted certificates structure 7\"             }           } else {               error \"pfxTbsParse: Invalid encrypted certificates structure 8\"     \t  }     \t  return $dres }  proc ::GostPfx::p7dParse {p7d} {   variable OCTET_STRING_TAG    variable OBJECT_IDENTIFIER_TAG    variable SEQUENCE_TAG    variable INTEGER_TAG   variable oid_pkcs7_data      set dres [dict create]      set seqValue2 $p7d           set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]           if {$tag_type_var == \"CONTEXT\"} {             asn::asnGetContext seqValue2 contextNumber contextData encoding_type ############## \t    ::asn::asnPeekByte contextData peek_tag  \t    ::asn::asnPeekByte contextData peek_tag1 1 \t    if {$peek_tag == 0x24 &amp;&amp; $peek_tag1 == 0x80} { \t\tset contextVar1 $contextData \t\t::asn::asnGet24OctetString contextVar1 contextData \t\tputs \"p7dParse=0x240x80\" \t    } #################             set tag_len [asn::asnPeekTag contextData tag_var tag_type_var constr_var]             if {$tag_var == $OCTET_STRING_TAG} {               asn::asnGetOctetString contextData keyBags               dict set dres \"keyBags\" $keyBags             } else {               error \"pfxTbsParse: Invalid key bags structure 1\"             }           } else {             error \"pfxTbsParse: Invalid key bags structure 2\"           }      \t  return $dres }  # tbs =&gt; dict: keyBags certsPbeData encrCerts proc ::GostPfx::pfxTbsParse {tbs} {   variable OCTET_STRING_TAG    variable OBJECT_IDENTIFIER_TAG    variable SEQUENCE_TAG    variable INTEGER_TAG   variable oid_pkcs7_data    variable oid_pkcs7_encrypted_data      set data $tbs   set dres [dict create] #  set dres [list]    set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $SEQUENCE_TAG} {     asn::asnGetSequence data seqValue1      set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]     if {$tag_var == $SEQUENCE_TAG} {       asn::asnGetSequence seqValue1 seqValue2       set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]       if {$tag_var == $OBJECT_IDENTIFIER_TAG} {         asn::asnGetObjectIdentifier seqValue2 oid2          if {$oid2 == $oid_pkcs7_encrypted_data} { \t  set dres [::GostPfx::p7mParse $seqValue2]         } elseif {$oid2 == $oid_pkcs7_data} { #    \t    set gg [dict create]     \t    set gg [list] \t    set gg [::GostPfx::p7dParse $seqValue2] \t    foreach {l l1} $gg { \t\tdict set dres $l $l1 \t    }  \t} else {           error \"pfxTbsParse: Invalid encrypted certificates structure 9 oid2=$oid2, oid_pkcs7_encrypted_data=$oid_pkcs7_encrypted_data\"         }               } else {         error \"pfxTbsParse: Invalid encrypted certificates structure 10\"       }     }     set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]     if {$tag_var == $SEQUENCE_TAG} {       asn::asnGetSequence seqValue1 seqValue2       set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]       if {$tag_var == $OBJECT_IDENTIFIER_TAG} {         asn::asnGetObjectIdentifier seqValue2 oid2         if {$oid2 == $oid_pkcs7_data} { #    \t    set gg [dict create]     \t    set gg [list] \t    set gg [::GostPfx::p7dParse $seqValue2] \t    foreach {l l1} $gg { \t\tdict set dres $l $l1 \t    }          } elseif {$oid2 == $oid_pkcs7_encrypted_data} {     \t    set gg [list] \t    set gg [::GostPfx::p7mParse $seqValue2] \t    foreach {l l1} $gg { \t\tdict set dres $l $l1 \t    }         } else {           error \"pfxTbsParse: Invalid key bags structure 3\"         }       } else {         error \"pfxTbsParse: Invalid key bags structure 4\"       }     }   } else {     error \"pfxTbsParse: Invalid TBS structure 5\"   }   return $dres }  # oid_pkcs5PBES2, ... =&gt; dict: hmacKeySalt hmacKeyIter hmacAlg digestParamset cipherAlg cipherIV cipherParamset proc ::GostPfx::pfxPbeDataParse {pbeData} {   variable OCTET_STRING_TAG    variable OBJECT_IDENTIFIER_TAG    variable SEQUENCE_TAG    variable INTEGER_TAG   variable oid_pkcs5PBES2    variable oid_pBKDF2      set data $pbeData   set dres [dict create]   set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $OBJECT_IDENTIFIER_TAG} {     asn::asnGetObjectIdentifier data oid1     if {$oid1 == $oid_pkcs5PBES2} {       set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]       if {$tag_var == $SEQUENCE_TAG} {         asn::asnGetSequence data seqValue1         set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]         if {$tag_var == $SEQUENCE_TAG} {           asn::asnGetSequence seqValue1 seqValue2           set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]           if {$tag_var == $OBJECT_IDENTIFIER_TAG} {             asn::asnGetObjectIdentifier seqValue2 oid2             if {$oid2 == $oid_pBKDF2} {               set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]               if {$tag_var == $SEQUENCE_TAG} {                 asn::asnGetSequence seqValue2 seqValue3                 set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]                  if {$tag_var == $OCTET_STRING_TAG} {                   asn::asnGetOctetString seqValue3 hmacKeySalt                   dict set dres \"hmacKeySalt\" $hmacKeySalt                   set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]                   if {$tag_var == $INTEGER_TAG} {                     asn::asnGetInteger seqValue3 hmacKeyIter                     dict set dres \"hmacKeyIter\" $hmacKeyIter                     set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]                     if {$tag_var == $SEQUENCE_TAG} {                       asn::asnGetSequence seqValue3 seqValue4                       set tag_len [asn::asnPeekTag seqValue4 tag_var tag_type_var constr_var]                       if {$tag_var == $OBJECT_IDENTIFIER_TAG} {                         asn::asnGetObjectIdentifier seqValue4 hmacAlg                         dict set dres \"hmacAlg\" $hmacAlg                         set tag_len [asn::asnPeekTag seqValue4 tag_var tag_type_var constr_var]                         if {$tag_var == $OBJECT_IDENTIFIER_TAG} {                           asn::asnGetObjectIdentifier seqValue4 digestParamset                           dict set dres \"digestParamset\" $digestParamset                         }                        } else {                         error \"pfxPbeDataParse: Invalid PBKDF2 HMAC algorithm structure\"                       }                     } else {                       error \"pfxPbeDataParse: Invalid PBKDF2 HMAC algorithm structure\"                     }                                       } else {                     error \"pfxPbeDataParse: Invalid PBKDF2 iteration count structure\"                   }                 } else {                   error \"pfxPbeDataParse: Invalid PBKDF2 salt structure\"                 }               } else {                 error \"pfxPbeDataParse: Invalid PBKDF2 structure\"               }                           } else {               error \"pfxPbeDataParse: Invalid PBKDF2 structure\"             }           } else {             error \"pfxPbeDataParse: Invalid PBKDF2 structure\"           }           }         set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]         if {$tag_var == $SEQUENCE_TAG} {           asn::asnGetSequence seqValue1 seqValue2           set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]           if {$tag_var == $OBJECT_IDENTIFIER_TAG} {             asn::asnGetObjectIdentifier seqValue2 cipherAlg             dict set dres \"cipherAlg\" $cipherAlg             set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]             if {$tag_var == $SEQUENCE_TAG} {               asn::asnGetSequence seqValue2 seqValue3               set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]               if {$tag_var == $OCTET_STRING_TAG} {                 asn::asnGetOctetString seqValue3 cipherIV                 dict set dres \"cipherIV\" $cipherIV                 set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]                 if {$tag_var == $OBJECT_IDENTIFIER_TAG} {                   asn::asnGetObjectIdentifier seqValue3 cipherParamset                   dict set dres \"cipherParamset\" $cipherParamset                 }               } else {                 error \"pfxPbeDataParse: Invalid PBE cipher IV structure\"               }             } else {               error \"pfxPbeDataParse: Invalid PBE cipher params structure\"             }           } else {             error \"pfxPbeDataParse: Invalid PBE cipher algorithm structure\"           }         } else {           error \"pfxPbeDataParse: Invalid PBE cipher algorithm structure\"         }               } else {         error \"pfxPbeDataParse: Invalid PBE structure\"        }     } else {       error \"pfxPbeDataParse: Invalid PBE structure\"      }   } else {     error \"pfxPbeDataParse: Invalid PBE structure\"    }   return $dres }  # generates cipher key proc ::GostPfx::pfxPbeKey {password hmacAlg hmacKeySalt hmacKeyIter} {   variable oid_HMACgostR3411_94    variable oid_tc26_hmac_gost_3411_2012_512      set key \"\"   if {$hmacAlg == $oid_HMACgostR3411_94} {     set key [lcc_gost3411_94_pkcs5 $password $hmacKeySalt $hmacKeyIter 32]   } else {     if {$hmacAlg == $oid_tc26_hmac_gost_3411_2012_512} {       set key [lcc_gost3411_2012_pkcs5 $password $hmacKeySalt $hmacKeyIter 32]     } else {       error \"pfxPbeKey: Unsupported PKCS5 HMAC algorithm $hmacAlg\"     }   }   return $key }  # encrData =&gt; decrData proc ::GostPfx::pfxDataDecrypt {data alg paramset key iv} {   variable oid_gost28147_89 puts \"pfxDataDecrypt: paramset=$paramset\"    set out \"\"   if {$alg == $oid_gost28147_89} {     set dotted_paramset [string map {\" \" \".\"} $paramset]     set par [lcc_gost28147_getParamsByOid $dotted_paramset]     if {$par &gt; 0} {       set ctx [lcc_gost28147_cfb_ctx_create $par 0 $key $iv]       if {$ctx &gt; 0} {         set out [lcc_gost28147_cfb_ctx_update $ctx $data]         lcc_gost28147_cfb_ctx_delete $ctx       } else {         error \"pfxDataDecrypt: Invalid cipher key or IV\"       }       lcc_handle_free $par     } else {       error \"pfxDataDecrypt: Unsupported cipher paramset $paramset\"     }   } else {     error \"pfxDataDecrypt: Unsupported cipher algorithm $alg\"     }   return $out }   # plain data =&gt; encrData proc ::GostPfx::pfxDataEncrypt {data alg paramset key iv} {   variable oid_gost28147_89      set out \"\"   if {$alg == $oid_gost28147_89} {     set dotted_paramset [string map {\" \" \".\"} $paramset]     set par [lcc_gost28147_getParamsByOid $dotted_paramset]     if {$par &gt; 0} {       set ctx [lcc_gost28147_cfb_ctx_create $par 1 $key $iv]       if {$ctx &gt; 0} {         set out [lcc_gost28147_cfb_ctx_update $ctx $data]         lcc_gost28147_cfb_ctx_delete $ctx       } else {         error \"pfxDataEncrypt: Invalid cipher key or IV\"       }       lcc_handle_free $par     } else {       error \"pfxDataEncrypt: Unsupported cipher paramset $paramset\"     }   } else {     error \"pfxDataEncrypt: Unsupported cipher algorithm $alg\"     }   return $out }   # SET =&gt; dict: friendlyName localKeyID proc ::GostPfx::pfxIdentityDataParse {identityData} {   variable SEQUENCE_TAG    variable OBJECT_IDENTIFIER_TAG    variable OCTET_STRING_TAG    variable SET_TAG    variable BMP_STRING_TAG   variable oid_friendlyName    variable oid_localKeyID      set data $identityData   set dres [dict create]   set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $SET_TAG} {     asn::asnGetSet data set1     while {1} {       set tag_len [asn::asnPeekTag set1 tag_var tag_type_var constr_var]       if {$tag_var != $SEQUENCE_TAG} {         break       }       asn::asnGetSequence set1 seqValue3       set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]       if {$tag_var == $OBJECT_IDENTIFIER_TAG} {         asn::asnGetObjectIdentifier seqValue3 oid3         set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]         if {$tag_var == $SET_TAG} {           asn::asnGetSet seqValue3 set2           set tag_len [asn::asnPeekTag set2 tag_var tag_type_var constr_var]           if {$oid3 == $oid_friendlyName} {             if {$tag_var == $BMP_STRING_TAG} {               asn::asnGetString set2 friendlyName               dict set dres \"friendlyName\" $friendlyName             } else {               error \"pfxIdentityDataParse: friendlyName is not BMP STRING\"             }           } else {             if {$oid3 == $oid_localKeyID} {               if {$tag_var == $OCTET_STRING_TAG} {                 asn::asnGetOctetString set2 localKeyID                 dict set dres \"localKeyID\" $localKeyID               }             } else {               error \"pfxIdentityDataParse: localKeyID is not OCTET STRING\"             }           }         } else {           error \"pfxIdentityDataParse: Invalid structure\"         }                       } else {         error \"pfxIdentityDataParse: Invalid structure\"       }     }   } else {     error \"pfxIdentityDataParse: Invalid structure\"   }   return $dres }  # certBags =&gt; { {dict: certificat  friendlyName localKeyID} ...} proc ::GostPfx::pfxCertBagsParse {certBags} {   variable SEQUENCE_TAG    variable OBJECT_IDENTIFIER_TAG    variable OCTET_STRING_TAG    variable SET_TAG    variable BMP_STRING_TAG   variable oid_PKCS12CertificateBag    variable oid_PKCS9x509Certificate    variable oid_friendlyName    variable oid_localKeyID      set data $certBags   set lres {}   set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $SEQUENCE_TAG} {     asn::asnGetSequence data seqValue1     set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]     while {$tag_var == $SEQUENCE_TAG} {       asn::asnGetSequence seqValue1 seqValue2       set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]       if {$tag_var == $OBJECT_IDENTIFIER_TAG} {         asn::asnGetObjectIdentifier seqValue2 oid1         if {$oid1 == $oid_PKCS12CertificateBag} {           set dcert [dict create]           set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]           if {$tag_type_var == \"CONTEXT\"} {             asn::asnGetContext seqValue2 contextNumber context1 encoding_type             set tag_len [asn::asnPeekTag context1 tag_var tag_type_var constr_var]             if {$tag_var == $SEQUENCE_TAG} {               asn::asnGetSequence context1 seqValue3               set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]               if {$tag_var == $OBJECT_IDENTIFIER_TAG} {                 asn::asnGetObjectIdentifier seqValue3 oid2                 if {$oid2 == $oid_PKCS9x509Certificate} {                   set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]                   if {$tag_type_var == \"CONTEXT\"} {                     asn::asnGetContext seqValue3 contextNumber context2 encoding_type                     set tag_len [asn::asnPeekTag context2 tag_var tag_type_var constr_var]                     if {$tag_var == $OCTET_STRING_TAG} {                       asn::asnGetOctetString context2 certificate             \t      dict set dcert \"certificate\" $certificate                     } else {                       error \"pfxCertBagsParse: Invalid structure 0\"                     }                                       } else {                     error \"pfxCertBagsParse: Invalid structure 1\"                   }                 } else {                   error \"pfxCertBagsParse: Invalid structure 2\"                 }               } else {                 error \"pfxCertBagsParse: Invalid structure 3\"               }             } else {               error \"pfxCertBagsParse: Invalid structure 4\"             }                      } else {             error \"pfxCertBagsParse: Invalid structure 5\"           }           set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]                      set did [pfxIdentityDataParse $seqValue2]           if {[dict exists $did friendlyName]} {             dict set dcert \"friendlyName\" [dict get $did friendlyName]           }           if {[dict exists $did localKeyID]} {             dict set dcert \"localKeyID\" [dict get $did localKeyID]           }         } else {           error \"pfxCertBagsParse: Invalid structure 6\"         }       } else {         error \"pfxCertBagsParse: Invalid structure 7\"       }       lappend lres $dcert                    set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]     }       } else {     error \"pfxCertBagsParse: Invalid structure 8\"   }    return [reverse $lres] #  return $lres }  # SEQUENCE, {SEQUENCE, oid_pkcs8ShroudedKeyBag, ...} =&gt; { {dict: keyBag friendlyName localKeyID} ... } proc ::GostPfx::pfxKeyBagsParse {keyBags} {   variable SEQUENCE_TAG    variable OBJECT_IDENTIFIER_TAG    variable OCTET_STRING_TAG    variable SET_TAG   variable oid_pkcs8ShroudedKeyBag       set data $keyBags   set lres {}   set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $SEQUENCE_TAG} {     asn::asnGetSequence data seqValue2     while {1} {       set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]       if {$tag_var != $SEQUENCE_TAG} {         break       }       asn::asnGetSequence seqValue2 seqValue3       set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]       if {$tag_var == $OBJECT_IDENTIFIER_TAG} {         asn::asnGetObjectIdentifier seqValue3 oid2         if {$oid2 == $oid_pkcs8ShroudedKeyBag} {            set dbag [dict create]           set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]           if {$tag_type_var == \"CONTEXT\"} {             asn::asnGetContext seqValue3 contextNumber context2 encoding_type             set tag_len [asn::asnPeekTag context2 tag_var tag_type_var constr_var]             if {$tag_var == $SEQUENCE_TAG} {               asn::asnGetSequence context2 keyBag               dict set dbag keyBag $keyBag                                    } else {               error \"pfxKeyBagsParse: Invalid structure\"             }                                     } else {             error \"pfxKeyBagsParse: Invalid structure\"           }               set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]           if {$tag_var == $SET_TAG} {             set did [pfxIdentityDataParse $seqValue3]             if {[dict exists $did friendlyName]} {               dict set dbag friendlyName [dict get $did friendlyName]             }             if {[dict exists $did localKeyID]} {               dict set dbag localKeyID [dict get $did localKeyID]             }           }                              lappend lres $dbag         } else {           error \"pfxKeyBagsParse: Invalid structure\"         }           } else {         error \"pfxKeyBagsParse: Invalid structure\"       }         }   } else {     error \"pfxKeyBagsParse: Invalid structure\"   }               return $lres }  # keyBag password =&gt; decrKey  proc ::GostPfx::pfxKeyBagDecrypt {keyBag password} {   variable SEQUENCE_TAG   variable OCTET_STRING_TAG      set decrKey \"\"   set data $keyBag   set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $SEQUENCE_TAG} {     asn::asnGetSequence data pbeData     set dpbe [pfxPbeDataParse $pbeData]     if {[dict exists $dpbe hmacKeySalt]} {       set hmacKeySalt [dict get $dpbe hmacKeySalt]     }     if {[dict exists $dpbe hmacKeyIter]} {       set hmacKeyIter [dict get $dpbe hmacKeyIter]     }     if {[dict exists $dpbe hmacAlg]} {       set hmacAlg [dict get $dpbe hmacAlg]     }     if {[dict exists $dpbe digestParamset]} {       set digestParamset [dict get $dpbe digestParamset]     }     if {[dict exists $dpbe cipherAlg]} {       set cipherAlg [dict get $dpbe cipherAlg]     }     if {[dict exists $dpbe cipherIV]} {       set cipherIV [dict get $dpbe cipherIV]     }     if {[dict exists $dpbe cipherParamset]} {       set cipherParamset [dict get $dpbe cipherParamset]     }          set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]     if {$tag_var == $OCTET_STRING_TAG} {       asn::asnGetOctetString data encrKey      } else {       error \"pfxKeyBagDecrypt: Invalid structure\"     }     set cipherKey [pfxPbeKey $password $hmacAlg $hmacKeySalt $hmacKeyIter]     set decrKey [pfxDataDecrypt $encrKey $cipherAlg $cipherParamset $cipherKey $cipherIV]   } else {     error \"pfxKeyBagDecrypt: Invalid structure\"   }          return $decrKey }  # decrKey =&gt; dict: version keyAlg gost3410Paramset gost3411Paramset keyValue proc ::GostPfx::pfxKeyDataParse {decrKey} {   variable SEQUENCE_TAG    variable INTEGER_TAG    variable OBJECT_IDENTIFIER_TAG    variable OCTET_STRING_TAG    set dKey [dict create]   set data $decrKey   set tag_len [asn::asnPeekTag data tag_var tag_type_var constr_var]   if {$tag_var == $SEQUENCE_TAG} {     asn::asnGetSequence data seqValue1     set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]     if {$tag_var == $INTEGER_TAG} {       asn::asnGetInteger seqValue1 version       dict set dKey version $version       set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]       if {$tag_var == $SEQUENCE_TAG} {         asn::asnGetSequence seqValue1 seqValue2         set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]         if {$tag_var == $OBJECT_IDENTIFIER_TAG} {           asn::asnGetObjectIdentifier seqValue2 keyAlg           dict set dKey keyAlg $keyAlg           set tag_len [asn::asnPeekTag seqValue2 tag_var tag_type_var constr_var]           if {$tag_var == $SEQUENCE_TAG} {             asn::asnGetSequence seqValue2 seqValue3             set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]             if {$tag_var == $OBJECT_IDENTIFIER_TAG} {               asn::asnGetObjectIdentifier seqValue3 gost3410Paramset               dict set dKey gost3410Paramset $gost3410Paramset               set tag_len [asn::asnPeekTag seqValue3 tag_var tag_type_var constr_var]               if {$tag_var == $OBJECT_IDENTIFIER_TAG} {                 asn::asnGetObjectIdentifier seqValue3 gost3411Paramset                 dict set dKey gost3411Paramset $gost3411Paramset               }             } else {               error \"pfxKeyDataParse: Invalid key paramset structure\"             }              } else {             error \"pfxKeyDataParse: Invalid key paramset structure\"           }                     } else {           error \"pfxKeyDataParse: Invalid key algorithm structure\"         }                 } else {         error \"pfxKeyDataParse: Invalid key algorithm structure\"       }           set tag_len [asn::asnPeekTag seqValue1 tag_var tag_type_var constr_var]       if {$tag_var == $OCTET_STRING_TAG} {         asn::asnGetOctetString seqValue1 octets1         set tag_len [asn::asnPeekTag octets1 tag_var tag_type_var constr_var]         if {$tag_var == $OCTET_STRING_TAG} {           asn::asnGetOctetString octets1 keyValue           dict set dKey keyValue $keyValue         } else {           error \"pfxKeyDataParse: Invalid key value structure\"         }       } else {         error \"pfxKeyDataParse: Invalid key value structure\"       }           } else {       error \"pfxKeyDataParse: Invalid key info structure\"     }      } else {     error \"pfxKeyDataParse: Invalid key info structure\"   }         return $dKey }  # =&gt; dict:  proc ::GostPfx::pfxGetSingleCertKey {indata password} {      set dres [dict create]      #puts \"pfxParse\"   set dpfx [pfxParse $indata]   if {[dict exists $dpfx authSafe]} {     set authSafe [dict get $dpfx authSafe]   }   if {[dict exists $dpfx macData]} {     set macData [dict get $dpfx macData]   }      #puts \"pfxMacDataParse\"   set dhmac [pfxMacDataParse $macData]    if {[dict exists $dhmac salt]} {     set hmacKeySalt [dict get $dhmac salt]   }   if {[dict exists $dhmac iter]} {     set hmacKeyIter [dict get $dhmac iter]   }   if {[dict exists $dhmac digestAlg]} {     set hmacDigestAlg [dict get $dhmac digestAlg]   }   if {[dict exists $dhmac hmac]} {     set hmac [dict get $dhmac hmac]   }    #puts \"pfxGetAuthSafeTbs\"   set tbs [pfxGetAuthSafeTbs $authSafe]    #puts \"pfxHmacVerify\"   set hmac_ok [pfxHmacVerify $tbs $hmac $password $hmacDigestAlg $hmacKeySalt $hmacKeyIter]   if {$hmac_ok != 1} {     error \"pfxGetSingleKeyCert: Check integrity: Invalid password or container corrupted!\"   }    #puts \"pfxTbsParse\"   set dKeysCertsData [pfxTbsParse $tbs]   if {[dict exists $dKeysCertsData keyBags]} {     set keyBags [dict get $dKeysCertsData keyBags]   }   if {[dict exists $dKeysCertsData certsPbeData]} {     set certsPbeData [dict get $dKeysCertsData certsPbeData]   }   if {[dict exists $dKeysCertsData encrCerts]} {     set encrCerts [dict get $dKeysCertsData encrCerts]   }    #puts \"pfxPbeDataParse\"   set dCertsPbe [pfxPbeDataParse $certsPbeData]   if {[dict exists $dCertsPbe hmacKeySalt]} {     set hmacKeySalt [dict get $dCertsPbe hmacKeySalt]   }   if {[dict exists $dCertsPbe hmacKeyIter]} {     set hmacKeyIter [dict get $dCertsPbe hmacKeyIter]   }   if {[dict exists $dCertsPbe hmacAlg]} {     set hmacAlg [dict get $dCertsPbe hmacAlg]   }   if {[dict exists $dCertsPbe digestParamset]} {     set digestParamset [dict get $dCertsPbe digestParamset]   }   if {[dict exists $dCertsPbe cipherAlg]} {     set cipherAlg [dict get $dCertsPbe cipherAlg]   }   if {[dict exists $dCertsPbe cipherIV]} {     set cipherIV [dict get $dCertsPbe cipherIV]   }   if {[dict exists $dCertsPbe cipherParamset]} {     set cipherParamset [dict get $dCertsPbe cipherParamset]   }    #puts \"pfxPbeKey\"   set cipherKey [pfxPbeKey $password $hmacAlg $hmacKeySalt $hmacKeyIter]    #puts \"pfxDataDecrypt\"   set certBags [pfxDataDecrypt $encrCerts $cipherAlg $cipherParamset $cipherKey $cipherIV]    #puts \"pfxCertBagsParse\"   set lcerts [pfxCertBagsParse $certBags]    set dcert [lindex $lcerts 0]   if {[dict exists $dcert \"certificate\"]} {     set cert [dict get $dcert \"certificate\"]     dict set dRes certificate $cert   }   if {[dict exists $dcert \"friendlyName\"]} {     set cert_friendlyName [dict get $dcert \"friendlyName\"]   }   if {[dict exists $dcert \"localKeyID\"]} {     set cert_localKeyID [dict get $dcert \"localKeyID\"]   }    #puts \"pfxKeyBagsParse\"    set lKeyBags [pfxKeyBagsParse $keyBags]   set dKeyBag [lindex $lKeyBags 0]   if {[dict exists $dKeyBag keyBag]} {     set keyBag [dict get $dKeyBag keyBag]   }   if {[dict exists $dKeyBag friendlyName]} {     set key_friendlyName [dict get $dKeyBag friendlyName]     dict set dRes friendlyName $key_friendlyName     if {[info exists cert_friendlyName] &amp;&amp; ($cert_friendlyName != $key_friendlyName)} {       puts \"pfxGetSingleKeyCert: Warning: certificate friendlyName: $cert_friendlyName is not equal to key friendlyName: $key_friendlyName\"     }   }   if {[dict exists $dKeyBag localKeyID]} {     set key_localKeyID [dict get $dKeyBag localKeyID]     dict set dRes localKeyID $key_localKeyID     if {[info exists cert_localKeyID] &amp;&amp; ($cert_localKeyID != $key_localKeyID)} {       puts \"pfxGetSingleKeyCert: Warning: certificate localKeyID is not equal to key localKeyID\"     }   }    #puts \"pfxKeyBagDecrypt\"   set decrKey [pfxKeyBagDecrypt $keyBag $password]    #puts \"pfxKeyDataParse\"   set dKey [pfxKeyDataParse $decrKey]   if {[dict exists $dKey version]} {     set version [dict get $dKey version]   }   if {[dict exists $dKey keyAlg]} {     set keyAlg [dict get $dKey keyAlg]     dict set dRes keyAlg $keyAlg   }   if {[dict exists $dKey gost3410Paramset]} {     set gost3410Paramset [dict get $dKey gost3410Paramset]     dict set dRes gost3410Paramset $gost3410Paramset   }   if {[dict exists $dKey gost3411Paramset]} {     set gost3411Paramset [dict get $dKey gost3411Paramset]     dict set dRes gost3411Paramset $gost3411Paramset   }   if {[dict exists $dKey keyValue]} {     set keyValue [dict get $dKey keyValue]     dict set dRes keyValue $keyValue   }      return $dRes }  proc ::GostPfx::pfxCreateSingleCertKey {password certificate keyValue keyAlg gost3410Paramset gost3411Paramset friendlyName localKeyID} {   variable oid_Gost3411_2012_512    variable oid_gost28147_89    variable oid_tc26_gost_28147_89_param_A    variable oid_tc26_hmac_gost_3411_2012_512   variable oid_pkcs5PBES2    variable oid_pBKDF2    variable oid_friendlyName    variable oid_localKeyID    variable oid_pkcs8ShroudedKeyBag    variable oid_pkcs7_data    variable oid_pkcs7_encrypted_data   variable oid_PKCS12CertificateBag    variable oid_PKCS9x509Certificate      set pfx \"\"   set ctx [lrnd_random_ctx_create \"\"]    # create identityData   set friendlyNameData [asn::asnSequence [asn::asnObjectIdentifier $oid_friendlyName] [asn::asnSet [asn::asnBMPString $friendlyName]]]   set localKeyIDData [asn::asnSequence [asn::asnObjectIdentifier $oid_localKeyID] [asn::asnSet [asn::asnOctetString $localKeyID]]]   set identityData [asn::asnSet $friendlyNameData $localKeyIDData]      # create private key data   set oid3410Paramset [asn::asnObjectIdentifier $gost3410Paramset]   set oid3411Paramset [asn::asnObjectIdentifier $gost3411Paramset]   set paramsetSequence [asn::asnSequence $oid3410Paramset $oid3411Paramset]   set oidKeyAlg [asn::asnObjectIdentifier $keyAlg]   set keyAlgSequence [asn::asnSequence $oidKeyAlg $paramsetSequence]   set keyOctets [asn::asnOctetString [asn::asnOctetString $keyValue]]   set version [asn::asnInteger 0]   set keyData [asn::asnSequence $version $keyAlgSequence $keyOctets]      # create private key cipherKey   set keySalt [lrnd_random_ctx_get_bytes $ctx 32]   set cipherKeyIter 2048   set hmacAlg $oid_tc26_hmac_gost_3411_2012_512   set keyCipherKey [pfxPbeKey $password $hmacAlg $keySalt $cipherKeyIter]   # create cipher algorithm and params   set cipherAlg $oid_gost28147_89   set cipherParamset $oid_tc26_gost_28147_89_param_A   set keyCipherIV [lrnd_random_ctx_get_bytes $ctx 8]   # encrypt private key data   set encrKey [pfxDataEncrypt $keyData $cipherAlg $cipherParamset $keyCipherKey $keyCipherIV]    # create private key PbeData   set keyCipherParams [asn::asnSequence [asn::asnOctetString $keyCipherIV] [asn::asnObjectIdentifier $cipherParamset]]   set keyCipherData [asn::asnSequence [asn::asnObjectIdentifier $cipherAlg] $keyCipherParams]   set hmacAlgData [asn::asnSequence [asn::asnObjectIdentifier $oid_tc26_hmac_gost_3411_2012_512] [asn::asnNull]]   set keyHmacData [asn::asnSequence [asn::asnOctetString $keySalt] [asn::asnInteger $cipherKeyIter] $hmacAlgData]   set keyPbkdf2Data [asn::asnSequence [asn::asnObjectIdentifier $oid_pBKDF2] $keyHmacData]   set keyPbeData [asn::asnSequence [asn::asnObjectIdentifier $oid_pkcs5PBES2] [asn::asnSequence $keyPbkdf2Data $keyCipherData]]      # create keyBag   set keyBagContext [asn::asnContextConstr 0 [asn::asnSequence $keyPbeData [asn::asnOctetString $encrKey]]]   set keyBag [asn::asnSequence [asn::asnObjectIdentifier $oid_pkcs8ShroudedKeyBag] $keyBagContext $identityData]   # create keyBags   set keyBags [asn::asnOctetString [asn::asnSequence $keyBag]]   set keysData [asn::asnSequence [asn::asnObjectIdentifier $oid_pkcs7_data] [asn::asnContextConstr 0 $keyBags]]      # create certificate cipherKey   set certSalt [lrnd_random_ctx_get_bytes $ctx 32]   set certCipherKey [pfxPbeKey $password $hmacAlg $certSalt $cipherKeyIter]   # create cipher algorithm and params   set certCipherIV [lrnd_random_ctx_get_bytes $ctx 8]   # create certPbeData   set certCipherParams [asn::asnSequence [asn::asnOctetString $certCipherIV] [asn::asnObjectIdentifier $cipherParamset]]   set certCipherData [asn::asnSequence [asn::asnObjectIdentifier $cipherAlg] $certCipherParams]   set certHmacData [asn::asnSequence [asn::asnOctetString $certSalt] [asn::asnInteger $cipherKeyIter] $hmacAlgData]   set certPbkdf2Data [asn::asnSequence [asn::asnObjectIdentifier $oid_pBKDF2] $certHmacData]   set certPbeData [asn::asnSequence [asn::asnObjectIdentifier $oid_pkcs5PBES2] [asn::asnSequence $certPbkdf2Data $certCipherData]]   # create certData   set certData [asn::asnSequence [asn::asnObjectIdentifier $oid_PKCS9x509Certificate] [asn::asnContextConstr 0 [asn::asnOctetString $certificate]]]   set certBag [asn::asnSequence [asn::asnObjectIdentifier $oid_PKCS12CertificateBag] [asn::asnContextConstr 0 $certData] $identityData]   # create certBags   set certBags [asn::asnSequence $certBag]   # encrypt certBags   set encrCertBags [pfxDataEncrypt $certBags $cipherAlg $cipherParamset $certCipherKey $certCipherIV]     # create certsInfo (non-constructed context here!)    set certsContent [asn::asnSequence [asn::asnObjectIdentifier $oid_pkcs7_data] $certPbeData [asn::asnContext 0 $encrCertBags]]   set certsEncrData [asn::asnSequence [asn::asnInteger 0] $certsContent]   set certsData [asn::asnSequence [asn::asnObjectIdentifier $oid_pkcs7_encrypted_data] [asn::asnContextConstr 0 $certsEncrData]]   # create tbs   set tbs [asn::asnSequence $certsData $keysData]   # create hmacKey   set hmacKeySalt [lrnd_random_ctx_get_bytes $ctx 32]   set hmacPbaKey [string range [lcc_gost3411_2012_pkcs5 $password $hmacKeySalt $cipherKeyIter 96] 64 95]     # create hmac   set hmacPba [lcc_gost3411_2012_hmac 64 $tbs $hmacPbaKey]   # create macData   set digestParams [asn::asnSequence [asn::asnObjectIdentifier $oid_Gost3411_2012_512] [asn::asnNull]]   set hmacData [asn::asnSequence $digestParams [asn::asnOctetString $hmacPba]]   set macData [asn::asnSequence $hmacData [asn::asnOctetString $hmacKeySalt] [asn::asnInteger $cipherKeyIter]]   # create pfx   set pfxData [asn::asnSequence [asn::asnObjectIdentifier $oid_pkcs7_data] [asn::asnContextConstr 0 [asn::asnOctetString $tbs]]]   set pfx [asn::asnSequence [asn::asnInteger 3] $pfxData $macData]    lrnd_random_ctx_delete $ctx   return $pfx } proc ::GostPfx::pfxCreateLocalKeyID {keyAlg gost3410Paramset privKeyValue} {   variable oid_GostR3410_2001   variable oid_GostR3411_94_with_GostR3410_2001   variable oid_tc26_gost3410_2012_256   variable oid_tc26_signwithdigest_gost3410_2012_256   variable oid_tc26_gost3410_2012_512   variable oid_tc26_signwithdigest_gost3410_2012_512      set localKeyID \"\"     if {($keyAlg == $oid_GostR3410_2001) || ($keyAlg == $oid_GostR3411_94_with_GostR3410_2001) || \\   ($keyAlg == $oid_tc26_gost3410_2012_256) || ($keyAlg == $oid_tc26_signwithdigest_gost3410_2012_256)} {     set par_id [string map {\" \" \".\"} $gost3410Paramset]     set group [lcc_gost3410_2012_256_getGroupByOid $par_id]     if {$group &gt; 0} {       set pubKey [lcc_gost3410_2012_256_createPublicKey $group $privKeyValue]     } else {       error \"pfxCreateLocalKeyID: Unsupported paramset $gost3410Paramset\"     }   } else {     if {($keyAlg == $oid_tc26_gost3410_2012_512) || ($keyAlg == $oid_tc26_signwithdigest_gost3410_2012_512)} {       set par_id [string map { } {.} $gost3410Paramset]       set group [lcc_gost3410_2012_512_getGroupByOid $par_id]       if {$group &gt; 0} {         set pubKey [lcc_gost3410_2012_512_createPublicKey $group $privKeyValue]       } else {         error \"pfxCreateLocalKeyID: Unsupported paramset $gost3410Paramset\"       }     } else {       error \"pfxCreateLocalKeyID: Unsupported algorithm: $keyAlg\"     }   }   set octets [asn::asnOctetString $pubKey]   set localKeyID [lcc_sha1 $octets]       return $localKeyID } package provide GostPfx 1.0.0<\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>   \u0418\u0442\u0430\u043a, \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 crytoarmpkcs, \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 PKCS#12 \u0441 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u043c \u0432\u0441\u0435\u0441\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0425\u0430\u0431\u0440\u0430, <a href=\"https:\/\/habr.com\/ru\/post\/453164\/\"><font color=\"blue\">\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u0440\u0430\u043d\u0435\u0435<\/font><\/a>, \u0438 \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ek\/nc\/dm\/ekncdmfvtc_cbsyg201gyirn6fm.png\"> <\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b \u043d\u0435 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044f \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0421\u041a\u0417\u0418, \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u0430 \u0441\u0432\u044f\u0437\u044c \u0441 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u043e\u043c, \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432, \u0448\u0442\u0430\u043c\u043f\u043e\u0432 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u043e\u0442\u043e\u0437\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432, \u043e\u0442\u0432\u0435\u0442\u043e\u0432 OCSP. <br \/>  \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 <a href=\"https:\/\/habr.com\/ru\/post\/457288\/\"><font color=\"blue\">\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0430\u043d\u0435\u0435<\/font><\/a>:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/pd\/k7\/v2\/pdk7v2rpikvo5mx6bg2n1009kak.png\"><\/p>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u044c \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043c\u0435\u043b\u043e <a href=\"https:\/\/www.gosuslugi.ru\/pgu\/eds\/\"><font color=\"blue\">\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c<\/font><\/a> \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 \u0413\u043e\u0441\u0443\u0441\u043b\u0443\u0433 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0435.<br \/>  \u041a\u0430\u043a \u0443\u0436\u0435 \u043e\u0442\u043c\u0435\u0447\u0430\u043b\u043e\u0441\u044c, \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0432 \u0444\u0430\u0439\u043b, \u0442\u0430\u043a \u0438 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d. \u041f\u0440\u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0435 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u0430 \u0435\u0433\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u044c:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/wr\/cb\/0f\/wrcb0f3_t5gfzdtsu6qtuhhx50a.png\"><\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u0440\u044b\u0442\u044b\u0439 \u043a\u043b\u044e\u0447 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/_w\/py\/iw\/_wpyiwsm0o8hyihj3a8a-alhbdo.png\"><\/p>\n<p>  \u041d\u0430\u0434\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u0432\u0438\u0434\u0443, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0438\u0445 \u0437\u0430\u043a\u0440\u044b\u0442\u044b\u0435 \u043a\u043b\u044e\u0447\u0438. \u0421 \u043d\u0430\u0448\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f, \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u043f\u0440\u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430 <a href=\"https:\/\/habr.com\/ru\/post\/403563\/\"> <font color=\"blue\"> \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u043c \u0442\u043e\u043a\u0435\u043d\u0435 PKCS#11<\/font><\/a>.<br \/>  \u0410 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438 PKCS#11, \u0431\u044b\u043b\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0432 <a href=\"https:\/\/habr.com\/ru\/post\/457288\/\"><font color=\"blue\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/font><\/a>.<br \/>  \u0418 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0430\u043c\u0430\u044f \u043c\u0430\u043b\u043e\u0441\u0442\u044c (\u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043a\u043d\u043e\u043f\u043a\u0430 \u00ab\u0420\u0435\u0437\u0435\u0440\u0432\u00bb), \u2014 \u044d\u0442\u043e \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f (\u043d\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u043a\u043b\u044e\u0447\u0435). \u041d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0430\u0437.<\/div>\n<p>               <script class=\"js-mediator-script\">!function(e){function t(t,n){if(!(n in e)){for(var r,a=e.document,i=a.scripts,o=i.length;o--;)if(-1!==i[o].src.indexOf(t)){r=i[o];break}if(!r){r=a.createElement(\"script\"),r.type=\"text\/javascript\",r.async=!0,r.defer=!0,r.src=t,r.charset=\"UTF-8\";var d=function(){var e=a.getElementsByTagName(\"script\")[0];e.parentNode.insertBefore(r,e)};\"[object Opera]\"==e.opera?a.addEventListener?a.addEventListener(\"DOMContentLoaded\",d,!1):e.attachEvent(\"onload\",d):d()}}}t(\"\/\/mediator.mail.ru\/script\/2820404\/\",\"_mediator\")}(window);<\/script>     <br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/460205\/\"> https:\/\/habr.com\/ru\/post\/460205\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html js-mediator-article\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/si\/bu\/q7\/sibuq775i85ksk84xdzzzqjpc_8.png\" align=\"left\" alt=\"image\"> \u041f\u0440\u043e\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u0430, \u043d\u0430\u0447\u0430\u0442\u0430\u044f \u043a\u0430\u043a <a href=\"https:\/\/habr.com\/ru\/post\/440754\/\"><font color=\"blue\">\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0449\u0438\u043a \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432<\/font><\/a>, \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u0440\u0438\u043f\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/457288\/\"><font color=\"blue\">\u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438 PKCS#11<\/font><\/a> \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 (PKCS#10) \u043d\u0430 \u043a\u0432\u0430\u043b\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442, \u043f\u043e\u043f\u043e\u043b\u043d\u0438\u043b\u0430\u0441\u044c, \u043a\u0430\u043a \u0438 \u0431\u044b\u043b\u043e \u0437\u0430\u044f\u0432\u043b\u0435\u043d\u043e, \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438 PKCS#12.   <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0418\u0442\u0430\u043a, \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438 PKCS#12 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u0430 cryptoarmpkcs :<\/b><\/p>\n<div class=\"spoiler_text\">\n<ul>\n<li> <a href=\"http:\/\/museum.lissi-crypto.ru\/docs\/guipkcs7_tclpkcs11\/cryptoarmpkcs_linux32.tar.bz2\">Linux32<\/a><\/li>\n<li> <a href=\"http:\/\/museum.lissi-crypto.ru\/docs\/guipkcs7_tclpkcs11\/cryptoarmpkcs_linux64.tar.bz2\">Linux64<\/a><\/li>\n<li> <a href=\"http:\/\/museum.lissi-crypto.ru\/docs\/guipkcs7_tclpkcs11\/cryptoarmpkcs_mac.tar.bz2\">OS X<\/a><\/li>\n<li> <a href=\"http:\/\/museum.lissi-crypto.ru\/docs\/guipkcs7_tclpkcs11\/cryptoarmpkcs_win32.exe\">WIN32<\/a><\/li>\n<li> <a href=\"http:\/\/museum.lissi-crypto.ru\/docs\/guipkcs7_tclpkcs11\/cryptoarmpkcs_win64.exe\">WIN64<\/a><\/li>\n<\/ul>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0443\u0442\u0438\u043b\u0438\u0442\u0443 cryptoarmpkcs \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u00abPKCS12\u00bb:<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-292106","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/292106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=292106"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/292106\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=292106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=292106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=292106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}