- Что нужно из оборудования
- Библитека 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, RAND
dynamic_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». Выбираем «Создать зашифрованный файловый контейнер», т.е. виртуальный зашифрованный диск будет храниться в одной файле.
Обычный том».
Токен-файлы», вводим пароль рутокена и выбираем токен.