- Что нужно из оборудования
- Библитека signature
- Как монтировать ролик
- Как снимать видео с экрана компьютера или мобильного устройства
- Как снимать реальные кадры или записывать закадровый голос
- Кто нужен для производства видеоинструкции
- Монтируем созданный том
- Обязательно ли писать сценарий
- Опыт применения технологии рутокен для регистрации и авторизации пользователей в системе (часть 2)
- Создаем зашифрованный том
Что нужно из оборудования
- Компьютер. На нем производится запись необходимого материала с экрана, хранятся все файлы для видео и монтируется ролик.
- Штатив. На него можно закрепить мобильный телефон для съемки живых кадров.
- Мобильный телефон. На него, как вы уже догадались, можно снимать живые кадры. Когда есть возможность позвать в этот проект видеооператора, штатив и мобильный телефон не нужны, так как процесс съемки обеспечивает видеооператор.
- Диктофон. На него записывается звук. Никакой конкретный рекламировать не будем, используйте любой, можно даже тот, что есть в мобильном телефоне.
- Монтажная программа. В ней мы монтируем и собираем видео. У нас их две: для простого линейного монтажа мы используем программу Movavi, а для более сложного — Adobe Premiere Pro. Первая очень простая и быстрая в освоении. Конечно необходимо, чтобы все используемое ПО было лицензированным.
- Много памяти на компьютере и мощный процессор. Чтобы сохранять все файлы для ролика и быстро его собирать. Файлы для ролика занимают в разы больше места, чем обычная документация.
- Программа для обработки звука. В ней мы обрабатываем звук. Можно установить специальную, а можно использовать возможности программы Adobe Premiere Pro.
- Текстовый редактор. В нем мы пишем сценарий. Использовать можно любой, но лучше всего тот, в котором организована возможность совместной работы с документом. Например, можно использовать Microsoft Word 2022 или Google Docs.
- Программа для записи видео с экрана. С ее помощью мы снимаем видео с экрана, если это необходимо. Мы используем ту же программу, в которой мы делаем скриншоты для обычной документации, это программа Snagit.
- Программа для создания текстовых слайдов для роликов. Можно использовать любую, мы используем графический онлайн-редактор Readymag.
.
Библитека signature
.
.
int init( const char* install_path
);.
char* create_key_request( const char* pin, /* PIN-код токена */ const char* slot_key_id, /* СЛОТ:ID ключа */ const char* paramset, /* параметры ключа */ const char* request_file, /* файл, в который будет сохранена заявка */ const char* common_name, /* понятное имя субъекта */ const char* org, /* организация */ const char* org_unit, /* подразделение организации */ const char* city, /* город */ const char* region, /* регион */ const char* country, /* страна */ const char* email, /* email */ const char* keyUsages, /* способы использования ключа, через , */ const char* extendedKeyUsages /* расширенные способы использования ключа, через , */
);.
int save_pem_cert( const char* cert, /* сертификат в PEM */ const char* cert_file, /*файл с сертификатом в PEM */ const char* slot_cert_id, /* SLOT : ID сертификата */ const char* label /* label */
);.
char* sign_file( const char* pin, /* PIN-код токена */ const char* slot_key_id, /* СЛОТ:ID ключа */ const char* slot_cert_id, /* СЛОТ:ID сертификата */ const char* file_path, /* путь к файлу, который будет подписан */ int detached /* тип подписи: 1-отсоединенная, 0-присоединенная */
);.
.
.
#include <windows.h>
#include "signature.h"
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL
Java_Rutoken_OpenSSL_Init
( JNIEnv* env, jclass cl, jstring install_path
)
{ if(!install_path) return 0; return (jint)init((*env).GetStringUTFChars(install_path, false));
}
JNIEXPORT jint JNICALL
Java_Rutoken_OpenSSL_SaveCertToToken
( JNIEnv* env, jclass cl, jstring cert, // сертификат в PEM jstring cert_file, // файл с сертификатом в PEM jstring slot_cert_id, // SLOT : ID сертификата jstring label
)
{ char* pCert = NULL; char* pCertFile = NULL; char* pId = NULL; char* pLabel = NULL; if( (!cert && !cert_file) || !slot_cert_id) return 0; if(cert) pCert=(char*)(*env).GetStringUTFChars(cert, false); if(cert_file) pCertFile=(char*)(*env).GetStringUTFChars(cert_file, false); pId=(char*)(*env).GetStringUTFChars(slot_cert_id, false); if(label) pLabel=(char*)(*env).GetStringUTFChars(label, false); return (jint)save_pem_cert( pCert, pCertFile, pId, pLabel);
}
JNIEXPORT jstring JNICALL
Java_Rutoken_OpenSSL_CreateKeyRequest
( JNIEnv* env, jclass cl, jstring pin, // PIN-код токена jstring slot_key_id, // СЛОТ:ID ключа jstring paramset, // параметры ключа jstring request_file, // файл, в который будет сохранена заявка jstring common_name, // понятное имя субъекта jstring org, // организация jstring org_unit, // подразделение организации jstring city, // город jstring region, // регион jstring country, // страна jstring email, // почтовый адрес jstring keyUsages, // способы использования ключа, через , jstring extendedKeyUsages // расширенные способы использования ключа, через ,
)
{ char* pPin = NULL; char* pSlotKeyId = NULL; char* pParamset = NULL; char* pCommonName = NULL; char* pOrg = NULL; char* pOrgUnit = NULL; char* pCity = NULL; char* pRegion = NULL; char* pCountry = NULL; char* pEmail = NULL; char* pKeyUsages = NULL; char* pExtendedKeyUsages = NULL; char* request = NULL; if(!pin || !slot_key_id || !paramset || !common_name || !email || !keyUsages || !extendedKeyUsages) return NULL; pPin=(char*)(*env).GetStringUTFChars(pin, false); pSlotKeyId=(char*)(*env).GetStringUTFChars(slot_key_id, false); pParamset=(char*)(*env).GetStringUTFChars(paramset, false); pCommonName=(char*)(*env).GetStringUTFChars(common_name, false); pOrg=(char*)(*env).GetStringUTFChars(org, false); pEmail=(char*)(*env).GetStringUTFChars(email, false); pKeyUsages=(char*)(*env).GetStringUTFChars(keyUsages, false); pExtendedKeyUsages=(char*)(*env).GetStringUTFChars(extendedKeyUsages, false); if(org) pOrg=(char*)(*env).GetStringUTFChars(org, false); if(org_unit) pOrgUnit=(char*)(*env).GetStringUTFChars(org_unit, false); if(city) pCity=(char*)(*env).GetStringUTFChars(city, false); if(region) pRegion=(char*)(*env).GetStringUTFChars(region, false); if(country) pCountry=(char*)(*env).GetStringUTFChars(country, false); request=(char*)create_key_request( pPin, pSlotKeyId, pParamset, NULL, pCommonName, pOrg, pOrgUnit, pCity, pRegion, pCountry, pEmail, pKeyUsages, pExtendedKeyUsages); if(request) return (*env).NewStringUTF((const char*)request); else return NULL;
}
JNIEXPORT jstring JNICALL
Java_Rutoken_OpenSSL_SignFile
( JNIEnv* env, jclass cl, jstring pin, // PIN-код токена jstring slot_key_id, // СЛОТ:ID ключа jstring slot_cert_id, // СЛОТ:ID сертификата jstring file_path, // путь к файлу, который будет подписан jint detached
)
{ char* pPin = NULL; char* pKeyID = NULL; char* pCertID = NULL; char* pFilePath = NULL; char* signature = NULL; if(!pin || !slot_key_id || !slot_cert_id || !file_path) return NULL; pPin=(char*)(*env).GetStringUTFChars(pin, false); pKeyID=(char*)(*env).GetStringUTFChars(slot_key_id, false); pCertID=(char*)(*env).GetStringUTFChars(slot_cert_id, false); pFilePath=(char*)(*env).GetStringUTFChars(file_path, false); signature=sign_file( pPin, pKeyID, pCertID, pFilePath, (int)detached); if(signature) return (*env).NewStringUTF((const char*)signature); else return NULL;
}
#ifdef __cplusplus
}
#endif.
#include <windows.h>
#include <openssl/lhash.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/crypto.h> /* for CRYPTO_* and SSLeay_version */
#include <openssl/rand.h>
#include <openssl/md4.h>
#include <openssl/des.h>
#include <openssl/engine.h>
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/cms.h>
#define CMD_LOAD_CERT_CTRL (ENGINE_CMD_BASE 5)
#define CMD_SAVE_CERT_CTRL (ENGINE_CMD_BASE 6)
#define CMD_LOGOUT (ENGINE_CMD_BASE 8)
#define ENGINE_PKCS11_PIN_MESSAGE "PKCS#11 token PIN"
char modules_path[MAX_PATH];
/* структура для взаимодействия с engine_pkcs11 */
typedef struct _CERT_PKCS11_INFO { const char* s_slot_cert_id; X509* cert; const char* label;
} CERT_PKCS11_INFO;
/* callback передачи PIN-кода */
int pin_cb(UI *ui, UI_STRING *uis)
{ char* pPin=NULL; char* pString=NULL; pString=(char*)UI_get0_output_string(uis); if(!pString) return 0; if(!strncmp(pString, ENGINE_PKCS11_PIN_MESSAGE, strlen(ENGINE_PKCS11_PIN_MESSAGE))) { pPin=(char*)UI_get_app_data(ui); if(!pPin) return 0; UI_set_result(ui, uis, pPin); return 1; } else return 0;
}
/* создает объект расширения сертификата */
X509_EXTENSION*
create_X509_extension
( char* name, char *value
)
{ X509_EXTENSION *ex; ex = X509V3_EXT_conf(NULL, NULL, name, value); if (!ex) return NULL; return ex; }
ENGINE* engine_gost=NULL;
ENGINE* LoadEngine(const char* pin)
{ ENGINE* engine_pkcs11=NULL; char enginePkcs11[MAX_PATH]; char engineGost[MAX_PATH]; char rtPkcs11ECP[MAX_PATH]; /* динамическая загрузка engine GOST */ strcpy(engineGost, modules_path); strcat(engineGost, "gost.dll"); engine_gost=ENGINE_by_id("dynamic"); if(!engine_gost) return NULL; if(!ENGINE_ctrl_cmd_string(engine_gost, "SO_PATH", engineGost, 0) || !ENGINE_ctrl_cmd_string(engine_gost, "ID", "gost", 0) || !ENGINE_ctrl_cmd_string(engine_gost, "LOAD", NULL, 0)) return NULL; if(!ENGINE_init(engine_gost)) { ENGINE_free(engine_gost); return NULL; } /* динамическая загрузка engine PKCS11 */ strcpy(enginePkcs11, modules_path); strcat(enginePkcs11, "pkcs11_gost.dll"); strcpy(rtPkcs11ECP, modules_path); strcat(rtPkcs11ECP, "rtPKCS11ECP.dll"); /* WARNING: крайне нужный вызов */ ENGINE_add(engine_gost); engine_pkcs11=ENGINE_by_id("dynamic"); if(!engine_pkcs11) return NULL; if(!ENGINE_ctrl_cmd_string(engine_pkcs11, "SO_PATH", enginePkcs11, 0) || !ENGINE_ctrl_cmd_string(engine_pkcs11, "ID", "pkcs11_gost", 0) || !ENGINE_ctrl_cmd_string(engine_pkcs11, "LOAD", NULL, 0) || !ENGINE_ctrl_cmd_string(engine_pkcs11, "MODULE_PATH", rtPkcs11ECP, 0)) return NULL; if(pin) { if(!ENGINE_ctrl_cmd_string(engine_pkcs11, "PIN", pin, 0)) return NULL; } if(!ENGINE_init(engine_pkcs11)) { ENGINE_free(engine_pkcs11); return NULL; } if(!ENGINE_set_default(engine_pkcs11, ENGINE_METHOD_ALL)) { ENGINE_free(engine_pkcs11); return NULL; } return engine_pkcs11;
}
X509_REQ*
create_request
( EVP_PKEY* pKey, const char* common_name, /* понятное имя субъекта */ const char* org, /* организация */ const char* org_unit, /* подразделение организации */ const char* city, /* город */ const char* region, /* регион */ const char* country, /* страна */ const char* email, /* почтовый адрес */ const char* keyUsages, /* способы использования ключа, через , */ const char* extendedKeyUsages /* расширенные способы использования ключа, через ; */
)
{ X509_REQ* req; X509_NAME* subject; BOOL bGoodEmail=TRUE; subject = X509_NAME_new(); if(common_name && strlen(common_name)>0) { if(!X509_NAME_add_entry_by_NID( subject, NID_commonName, MBSTRING_UTF8, (unsigned char*)common_name, -1, -1, 0)) { X509_NAME_free(subject); return NULL; } } if(org && strlen(org)>0) if(!X509_NAME_add_entry_by_NID( subject, NID_organizationName, MBSTRING_UTF8, (unsigned char*)org, -1, -1, 0)) { X509_NAME_free(subject); return NULL; } if(org_unit && strlen(org_unit)>0) if(!X509_NAME_add_entry_by_NID( subject, NID_organizationalUnitName, MBSTRING_UTF8, (unsigned char*)org_unit, -1, -1, 0)) { X509_NAME_free(subject); return NULL; } if(city && strlen(city)>0) if(!X509_NAME_add_entry_by_NID( subject, NID_localityName, MBSTRING_UTF8, (unsigned char*)city, -1, -1, 0)) { X509_NAME_free(subject); return NULL; } if(region && strlen(region)>0) if(!X509_NAME_add_entry_by_NID( subject, NID_stateOrProvinceName, MBSTRING_UTF8, (unsigned char*)region, -1, -1, 0)) { X509_NAME_free(subject); return NULL; } if(country && strlen(country)>0) if(!X509_NAME_add_entry_by_NID( subject, NID_countryName, MBSTRING_UTF8, (unsigned char*)country, -1, -1, 0)) { X509_NAME_free(subject); return NULL; } if(email && strlen(email)>0) { for (int i=0; i<strlen(email); i ) if (email[i]&0x80) { bGoodEmail=FALSE; break; } if(bGoodEmail) { if(!X509_NAME_add_entry_by_NID( subject, NID_pkcs9_emailAddress, MBSTRING_UTF8, (unsigned char*)email, -1, -1, 0)) { X509_NAME_free(subject); return NULL; } } } req=X509_REQ_new(); if(!req) { X509_NAME_free(subject); return NULL; } /* установка версии */ if(!X509_REQ_set_version(req, 0)) { X509_REQ_free(req); X509_NAME_free(subject); return NULL; } /* установка subject */ if(!X509_REQ_set_subject_name(req, subject)) { X509_REQ_free(req); X509_NAME_free(subject); return NULL; } /* установка открытого ключа */ if(!X509_REQ_set_pubkey(req, pKey)) { X509_REQ_free(req); X509_NAME_free(subject); return NULL; } /* "digitalSignature,keyEncipherment" */ X509_EXTENSION* keyUsageExt = create_X509_extension("keyUsage", (char*)keyUsages); if(!keyUsageExt) { X509_REQ_free(req); X509_NAME_free(subject); return NULL; } /* "clientAuth,emailProtection" */ X509_EXTENSION* extendedKeyUsageExt = create_X509_extension("extendedKeyUsage", (char*)extendedKeyUsages); if(!extendedKeyUsageExt) { X509_EXTENSION_free(keyUsageExt); X509_REQ_free(req); X509_NAME_free(subject); return NULL; } STACK_OF(X509_EXTENSION)* extension_stack = sk_X509_EXTENSION_new_null(); if(!extension_stack) { X509_EXTENSION_free(extendedKeyUsageExt); X509_EXTENSION_free(keyUsageExt); X509_REQ_free(req); X509_NAME_free(subject); return NULL; } sk_X509_EXTENSION_push(extension_stack, keyUsageExt); sk_X509_EXTENSION_push(extension_stack, extendedKeyUsageExt); if(!X509_REQ_add_extensions(req, extension_stack)) { X509_EXTENSION_free(extendedKeyUsageExt); X509_EXTENSION_free(keyUsageExt); X509_REQ_free(req); X509_NAME_free(subject); return NULL; } if(!X509_REQ_sign(req, pKey, EVP_get_digestbyname("md_gost94"))) { X509_EXTENSION_free(extendedKeyUsageExt); X509_EXTENSION_free(keyUsageExt); X509_REQ_free(req); X509_NAME_free(subject); return NULL; } sk_X509_EXTENSION_pop_free (extension_stack,X509_EXTENSION_free); X509_NAME_free(subject); return req;
}
ENGINE* engine_pkcs11 = NULL;
extern "C" __declspec( dllexport )
int init(const char* install_path)
{ HMODULE hLibp11 = NULL; HMODULE hLibTdl = NULL; char libp11[MAX_PATH]; char libtdl[MAX_PATH]; strcpy(modules_path, install_path); strcpy(libtdl, install_path); strcat(libtdl, "libltdl3.dll"); hLibTdl=LoadLibraryA(libtdl); if(!hLibTdl) return 0; strcpy(libp11, install_path); strcat(libp11, "libp11.dll"); hLibp11=LoadLibraryA(libp11); if(!hLibp11) return 0; /* инициализируем OpenSSL */ ENGINE_load_builtin_engines(); OPENSSL_add_all_algorithms_noconf(); engine_pkcs11=LoadEngine(NULL); if(!engine_pkcs11) return 0; return 1;
}
/* записать сертификат на токен */
extern "C" __declspec( dllexport )
int save_pem_cert
( const char* cert, /* сертификат в PEM */ const char* cert_file, /* файл с сертификатом в PEM */ const char* slot_cert_id, /* SLOT : ID сертификата */ const char* label /* label */
)
{ int len = 0; X509* x509 = NULL; BIO* bio_cert = NULL; BIO* bio_der = NULL; CERT_PKCS11_INFO cert_info; /* загружаем сертификат */ if(cert) { bio_cert=BIO_new(BIO_s_mem()); if(!bio_cert) return 0; if(!BIO_puts(bio_cert, cert)) return 0; x509=PEM_read_bio_X509(bio_cert, NULL, NULL, NULL); if(!x509) { BIO_free(bio_cert); return 0; } } else if(cert_file) { bio_cert=BIO_new_file(cert_file, "rb"); if(!bio_cert) return 0; x509=PEM_read_bio_X509(bio_cert, NULL, NULL, NULL); if(!x509) { BIO_free(bio_cert); return 0; } } cert_info.s_slot_cert_id=slot_cert_id; cert_info.cert=x509; cert_info.label=label; if(!ENGINE_ctrl(engine_pkcs11, CMD_SAVE_CERT_CTRL, 0, (void*)&cert_info, NULL)) { return 0; } return 1;
}
/* генерирует ключ подписи ГОСТ Р 34-10.2001 на Рутокен ЭЦП и создает заявку в формате PKCS#10 */
extern "C" __declspec( dllexport )
char* create_key_request( const char* pin, /* PIN-код токена */ const char* slot_key_id, /* СЛОТ:ID ключа */ const char* paramset, /* параметры ключа */ const char* request_file, /* файл, в который будет сохранена заявка */ const char* common_name, /* понятное имя субъекта */ const char* org, /* организация */ const char* org_unit, /* подразделение организации */ const char* city, /* город */ const char* region, /* регион */ const char* country, /* страна */ const char* email, /* почтовый адрес */ const char* keyUsages, /* способы использования ключа, через , */ const char* extendedKeyUsages /* расширенные способы использования ключа, через , */
)
{ BIO* bio_req=NULL; BIO* bio_key=NULL; X509_REQ* pRequest=NULL; BUF_MEM* pbmReq; char* cRequest=NULL; UI_METHOD* uim=NULL; int reason=0; EVP_PKEY* key1=NULL; EVP_PKEY* newkey=NULL; EVP_PKEY_CTX* ctx=NULL; key1=EVP_PKEY_new(); if(!key1) { return NULL; } if(!EVP_PKEY_set_type(key1, 811)) { EVP_PKEY_free(key1); return NULL; } ctx=EVP_PKEY_CTX_new(key1, NULL); if(!ctx) { EVP_PKEY_free(key1); return NULL; } if(!EVP_PKEY_keygen_init(ctx)) { EVP_PKEY_CTX_free(ctx); return NULL; } if(!EVP_PKEY_CTX_ctrl_str(ctx, "paramset", paramset)) { EVP_PKEY_CTX_free(ctx); return NULL; } if(!EVP_PKEY_CTX_ctrl_str(ctx, "slot_key_id", slot_key_id)) { EVP_PKEY_CTX_free(ctx); return NULL; } if(!EVP_PKEY_CTX_ctrl_str(ctx, "pin", pin)) { EVP_PKEY_CTX_free(ctx); return NULL; } if(!EVP_PKEY_keygen(ctx,&newkey)) { EVP_PKEY_CTX_free(ctx); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } pRequest=create_request( newkey, common_name, org, org_unit, city, region, country, email, keyUsages, extendedKeyUsages); if(!pRequest) { EVP_PKEY_free(newkey); EVP_PKEY_CTX_free(ctx); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } bio_req=BIO_new(BIO_s_mem()); if(!bio_req) { X509_REQ_free(pRequest); EVP_PKEY_free(newkey); EVP_PKEY_CTX_free(ctx); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } if(!PEM_write_bio_X509_REQ(bio_req, pRequest)) { BIO_free(bio_req); X509_REQ_free(pRequest); EVP_PKEY_free(newkey); EVP_PKEY_CTX_free(ctx); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } BIO_get_mem_ptr(bio_req, &pbmReq); if(!pbmReq) { BIO_free(bio_req); X509_REQ_free(pRequest); EVP_PKEY_free(newkey); EVP_PKEY_CTX_free(ctx); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } cRequest=(char*)OPENSSL_malloc(pbmReq->length 1); if(!cRequest) { BIO_free(bio_req); X509_REQ_free(pRequest); EVP_PKEY_free(newkey); EVP_PKEY_CTX_free(ctx); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } memset(cRequest, 0, pbmReq->length 1); memcpy(cRequest, pbmReq->data, pbmReq->length); BIO_free(bio_req); bio_req=NULL; if(request_file) { bio_req=BIO_new_file(request_file, "wb"); if(!bio_req) { X509_REQ_free(pRequest); EVP_PKEY_free(newkey); EVP_PKEY_CTX_free(ctx); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } if(!PEM_write_bio_X509_REQ(bio_req, pRequest)) { BIO_free(bio_req); EVP_PKEY_free(newkey); EVP_PKEY_CTX_free(ctx); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } BIO_free(bio_req); } X509_REQ_free(pRequest); EVP_PKEY_free(newkey); EVP_PKEY_CTX_free(ctx); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return cRequest;
}
/* возвращает подпись PKCS#7 по ГОСТ Р 34-10.2001 в формате PEM */
extern "C" __declspec( dllexport )
char* sign_file( const char* pin, /* PIN-код токена */ const char* slot_key_id, /* СЛОТ:ID ключа */ const char* slot_cert_id, /* СЛОТ:ID сертификата */ const char* file_path, /* путь к файлу, который будет подписан */ int detached /* тип подписи: 1-отсоединенная, 0-присоединенная */
)
{ BIO* bio_cert = NULL; BIO* in = NULL; BIO* out = NULL; BUF_MEM* pbmOut = NULL; EVP_PKEY* pKey = NULL; UI_METHOD* uim = NULL; PKCS7* p7 = NULL; char* pSignature = NULL; int flags = 0; int reason = 0; CERT_PKCS11_INFO cert_info; uim=UI_create_method("RutokenECP"); if(!uim) return NULL; UI_method_set_reader(uim, pin_cb); /* считываем закрытый ключ */ pKey=ENGINE_load_private_key(engine_pkcs11, slot_key_id, uim, (void*)pin); if(!pKey) { /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } memset(&cert_info, 0, sizeof(cert_info)); cert_info.s_slot_cert_id=slot_cert_id; /* считывем сертификат с токена */ if(!ENGINE_ctrl(engine_pkcs11, CMD_LOAD_CERT_CTRL, 0, &cert_info, NULL)) { EVP_PKEY_free(pKey); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } BIO_free(bio_cert); in=BIO_new_file(file_path, "rb"); if(!in) { EVP_PKEY_free(pKey); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } out=BIO_new(BIO_s_mem()); if(!out) { BIO_free(in); EVP_PKEY_free(pKey); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } if(detached) flags=PKCS7_DETACHED|PKCS7_BINARY; else flags=PKCS7_BINARY; /* подпись pkcs#7 */ p7=PKCS7_sign(cert_info.cert, pKey, NULL, in, flags); if(!p7) { BIO_free(out); BIO_free(in); EVP_PKEY_free(pKey); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } if(!PEM_write_bio_PKCS7(out, p7)) { PKCS7_free(p7); BIO_free(out); BIO_free(in); EVP_PKEY_free(pKey); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } BIO_get_mem_ptr(out, &pbmOut); if(!pbmOut) { PKCS7_free(p7); BIO_free(out); BIO_free(in); EVP_PKEY_free(pKey); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } pSignature=(char*)OPENSSL_malloc(pbmOut->length 1); if(!pSignature) { PKCS7_free(p7); BIO_free(out); BIO_free(in); EVP_PKEY_free(pKey); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return NULL; } memset(pSignature, 0, pbmOut->length 1); memcpy(pSignature, pbmOut->data, pbmOut->length); CRYPTO_cleanup_all_ex_data(); PKCS7_free(p7); BIO_free(out); BIO_free(in); EVP_PKEY_free(pKey); /* logout */ ENGINE_ctrl(engine_pkcs11, CMD_LOGOUT, 0, (void*)slot_key_id, NULL); return pSignature;
}.
Как монтировать ролик
.
.
.
.
.
.
.
.
.
Как снимать видео с экрана компьютера или мобильного устройства
.
.
.
.
.
.
Как снимать реальные кадры или записывать закадровый голос
.
.
.
.
.
.
.
.
.
.
.
.
Кто нужен для производства видеоинструкции
.
.
- Технический писатель. Тот, который писал инструкцию для нашей смарт-карты. Он уже многое знает и напишет сценарий быстрее, чем любой другой, кому придется разбираться в этой теме. Зачем он нам: написать сценарий и снять видео с экрана своего компьютера. Также, если в видео есть реальные кадры, то нарисовать раскадровку для видеооператора. Это идеальная картина, бывает так, что технический писатель и режиссер, и оператор, и монтажер.
- Видеооператор. Ему совсем не обязательно быть в теме, для него создана раскадровка, и он по ней работает. У нас это не всегда отдельный человек, если нет на это ресурсов, то тот, кто пишет сценарий и снимает живые кадры. В этот раз он у нас был. Зачем он нам: качественно снять живые кадры и при необходимости помочь с монтажом.
- Монтажер. У нас это тот, кто писал сценарий, он собирает весь ролик. Видеооператор может помочь ему выполнить какие-то сложные моменты. В этот раз они были: нам надо было показать одновременную работу смарт-карты в двух мобильных операционных системах.
- Человек, записывающий закадровый голос. У нас это реальный сотрудник технической поддержки, его голос знаком нашим пользователям. Он записывает закадровый голос для ролика.
.
Монтируем созданный том
.
Файл
.
.
Если у Вас не подключен рутокен, то вы получите ошибку «
.
.

.
.
.
Обязательно ли писать сценарий
.
.
.
.
.
.
Опыт применения технологии рутокен для регистрации и авторизации пользователей в системе (часть 2)
.
.
).
.
.
.
- Скачиваем установочный дистрибутив openssl-1.1.1g.
У openSSL имеются различные версии. В документации к Рутокену было сказано, что необходима версия openSSL версии 1.1.0 или новее. Я использовал версию openssl-1.1.1g. Можно скачать openSSL с официального сайта, но для более простой установки необходимо найти установочный файл для windows в сети. Я это сделал за вас: slproweb.com/products/Win32OpenSSL.html
Необходимо пролистать вниз страницы и скачать Win64 OpenSSL v1.1.1g EXE 63MB Installer. - Устанавливаем openssl-1.1.1g на компьютер.
Установку необходимо провести по стандартному пути, который указывается автоматически в папку C:Program Files. Программа установится в папку OpenSSL-Win64. - Для того, чтобы настроить openSSL так как вам нужно, существует файл openssl.cfg. Этот файл расположен в пути C:Program FilesOpenSSL-Win64bin если вы установили openSSL так, как было сказано в предыдущем пункте. Переходим в папку, где хранится openssl.cfg и открываем этот файл с использованием, например, Notepad .
- Вы наверно догадались, что настройка удостоверяющего центра будет производиться как-то изменением содержимого файла openssl.cfg, и вы абсолютно правы. Для этого требуется настроить команду [ ca ]. В файле openssl.cfg начало текста, куда мы будем вносить изменения, можно найти как: [ ca ].
- Теперь я приведу пример настройки с его описанием:
[ ca ] default_ca = CA_default [ CA_default ] dir = /Users/username/bin/openSSLca/demoCA certs = $dir/certs crl_dir = $dir/crl database = $dir/index.txt new_certs_dir = $dir/newcerts certificate = $dir/ca.crt serial = $dir/private/serial crlnumber = $dir/crlnumber crl = $dir/crl.pem private_key = $dir/private/ca.key x509_extensions = usr_cert.
.
.
.
.
- Подключаем алгоритмы шифрования предоставляемые Рутокеном.
Это подключение происходит в файле openssl.cfg.- Прежде всего требуется скачать необходимые алгоритмы Рутокена. Это файлы rtengine.dll, rtpkcs11ecp.dll.
Для этого скачиваем Рутокен SDK: www.rutoken.ru/developers/sdk..
sdk/openssl/rtengine/bin/windows-x86_64/lib/rtengine.dll
sdk/pkcs11/lib/windows-x86_64/rtpkcs11ecp.dll.
- Библиотеки rtengine.dll и rtpkcs11ecp.dll можно держать в любом месте учетной записи пользователя.
- Прописываем пути к этим библиотекам в openssl.cfg. Для этого открываем файл openssl.cfg, в начало этого файла необходимо поместить строчку:
openssl_conf = openssl_def.
[ openssl_def ] engines = engine_section [ engine_section ] rtengine = gost_section [ gost_section ] dynamic_path = /Users/username/bin/sdk-rutoken/openssl/rtengine/bin/windows-x86_64/lib/rtengine.dll MODULE_PATH = /Users/username/bin/sdk-rutoken/pkcs11/lib/windows-x86_64/rtpkcs11ecp.dll RAND_TOKEN = pkcs11:manufacturer=Aktiv Co.;model=Rutoken ECP default_algorithms = CIPHERS, DIGEST, PKEY, RANDdynamic_path – необходимо прописать свой путь к библиотеке rtengine.dll.
MODULE_PATH — необходимо прописать свой путь к библиотеке rtpkcs11ecp.dll.
- Прежде всего требуется скачать необходимые алгоритмы Рутокена. Это файлы rtengine.dll, rtpkcs11ecp.dll.
- Добавляем переменные среды.
.
.
- Теперь можно вернуться к пункту 5 и создать недостающие файлы для каталога demoCA.
- Первый важный файл без которого ничего не будет работать — serial. Это файл без расширения, значение которого должно быть 01. Можно создать этот файл самостоятельно и прописать внутрь 01. Также можно скачать его из Рутокен SDK по пути sdk/openssl/rtengine/samples/tool/demoCA/.
В каталоге demoCA лежит файл serial, который нам как раз и нужен. - Создаем корневой приватный ключ.
Для этого воспользуемся командой библиотеки openSSL, которую необходимо запустить прямо в командной строке:openssl genpkey -algorithm gost2022_256 -pkeyopt paramset:A -out ca.key - Создаем корневой сертификат.
Для этого воспользуемся следующей командой библиотеки openSSL:openssl req -utf8 -x509 -key ca.key -out ca.crtОбратите внимание, что для создания корневого сертификата требуется корневой приватный ключ, который создавался на предыдущем шаге. Поэтому командная строка должна быть запущена в одной и той же директории.
Все теперь имеются все недостающие файлы для полной конфигурации каталога demoCA. Поместите созданные файлы в те каталоги, которые указаны в пункте 5.
- Первый важный файл без которого ничего не будет работать — serial. Это файл без расширения, значение которого должно быть 01. Можно создать этот файл самостоятельно и прописать внутрь 01. Также можно скачать его из Рутокен SDK по пути sdk/openssl/rtengine/samples/tool/demoCA/.
.
.
Создаем зашифрованный том
ВНИМАНИЕ! Все дальнейшие необдуманные действия с Вашей стороны со своим жестким диском на Ваш страх и риск! Я описываю самый безопасный способ создания скрытого раздела. Если не хотите потерять данные, придерживайтесь инструкции.Для создания нового тома используем мастер создания томов TrueCrypt – ТомаСоздать новый раздел.
Запускается «Мастер создания томов TrueCrypt». Выбираем «Создать зашифрованный файловый контейнер», т.е. виртуальный зашифрованный диск будет храниться в одной файле.
Обычный том».


Токен-файлы», вводим пароль рутокена и выбираем токен.













