Re: Поддержка Рутокен ЭЦП в OpenSSL
Для решения проблемы необходимо поставить свежую библиотеку PKCS#11 https://www.rutoken.ru/support/download/pkcs/
Вы не авторизованы. Пожалуйста, войдите или зарегистрируйтесь.
Форум Рутокен → Рутокен и Open Source → Поддержка Рутокен ЭЦП в OpenSSL
Страницы Назад 1 … 8 9 10 11 12 … 17 Далее
Чтобы отправить ответ, нужно авторизоваться или зарегистрироваться
Для решения проблемы необходимо поставить свежую библиотеку PKCS#11 https://www.rutoken.ru/support/download/pkcs/
Добрый день.
Есть веб-приложение. Клиент - js (rutoken plugin), сервер - php. Произвожу шифрование данных (строки) на сервере. С помощью голого openssl ( exec('openssl cms -engine gost -gost89 -encrypt -in data.txt -outform PEM -out data_enc.txt cert.crt') ) все работает отлично. Но хотелось бы сделать с помощью обертки php openssl, но та не видит гостовских алгоритмов. Может кто подскажет, как с этим бороться?
php: 5.5.x
rutoken ecp
Добрый день.
Есть веб-приложение. Клиент - js (rutoken plugin), сервер - php. Произвожу шифрование данных (строки) на сервере. С помощью голого openssl ( exec('openssl cms -engine gost -gost89 -encrypt -in data.txt -outform PEM -out data_enc.txt cert.crt') ) все работает отлично. Но хотелось бы сделать с помощью обертки php openssl, но та не видит гостовских алгоритмов. Может кто подскажет, как с этим бороться?
php: 5.5.x
rutoken ecp
Здравствуйте!
На Хабре была статья, где описан способ решения подобной проблемы. Может быть поможет.
Будет много кода.
Смотрим функцию из враппера PHP над OpenSSL (https://github.com/php/php-src/blob/mas … /openssl.c), которая является аналогом нужной вам команды:
/* {{{ proto bool openssl_pkcs7_encrypt(string infile, string outfile, mixed recipcerts, array headers [, long flags [, long cipher]])
Encrypts the message in the file named infile with the certificates in recipcerts and output the result to the file named outfile */
PHP_FUNCTION(openssl_pkcs7_encrypt)
{
zval ** zrecipcerts, * zheaders = NULL;
STACK_OF(X509) * recipcerts = NULL;
BIO * infile = NULL, * outfile = NULL;
long flags = 0;
PKCS7 * p7 = NULL;
HashPosition hpos;
zval ** zcertval;
X509 * cert;
const EVP_CIPHER *cipher = NULL;
long cipherid = PHP_OPENSSL_CIPHER_DEFAULT;
uint strindexlen;
ulong intindex;
char * strindex;
char * infilename = NULL; int infilename_len;
char * outfilename = NULL; int outfilename_len;
RETVAL_FALSE;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZa!|ll", &infilename, &infilename_len,
&outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE)
return;
if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
return;
}
infile = BIO_new_file(infilename, "r");
if (infile == NULL) {
goto clean_exit;
}
outfile = BIO_new_file(outfilename, "w");
if (outfile == NULL) {
goto clean_exit;
}
recipcerts = sk_X509_new_null();
/* get certs */
if (Z_TYPE_PP(zrecipcerts) == IS_ARRAY) {
zend_hash_internal_pointer_reset_ex(HASH_OF(*zrecipcerts), &hpos);
while(zend_hash_get_current_data_ex(HASH_OF(*zrecipcerts), (void**)&zcertval, &hpos) == SUCCESS) {
long certresource;
cert = php_openssl_x509_from_zval(zcertval, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
goto clean_exit;
}
if (certresource != -1) {
/* we shouldn't free this particular cert, as it is a resource.
make a copy and push that on the stack instead */
cert = X509_dup(cert);
if (cert == NULL) {
goto clean_exit;
}
}
sk_X509_push(recipcerts, cert);
zend_hash_move_forward_ex(HASH_OF(*zrecipcerts), &hpos);
}
} else {
/* a single certificate */
long certresource;
cert = php_openssl_x509_from_zval(zrecipcerts, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
goto clean_exit;
}
if (certresource != -1) {
/* we shouldn't free this particular cert, as it is a resource.
make a copy and push that on the stack instead */
cert = X509_dup(cert);
if (cert == NULL) {
goto clean_exit;
}
}
sk_X509_push(recipcerts, cert);
}
/* sanity check the cipher */
cipher = php_openssl_get_evp_cipher_from_algo(cipherid);
if (cipher == NULL) {
/* shouldn't happen */
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to get cipher");
goto clean_exit;
}
p7 = PKCS7_encrypt(recipcerts, infile, (EVP_CIPHER*)cipher, flags);
if (p7 == NULL) {
goto clean_exit;
}
/* tack on extra headers */
if (zheaders) {
zend_hash_internal_pointer_reset_ex(HASH_OF(zheaders), &hpos);
while(zend_hash_get_current_data_ex(HASH_OF(zheaders), (void**)&zcertval, &hpos) == SUCCESS) {
strindex = NULL;
zend_hash_get_current_key_ex(HASH_OF(zheaders), &strindex, &strindexlen, &intindex, 0, &hpos);
convert_to_string_ex(zcertval);
if (strindex) {
BIO_printf(outfile, "%s: %s\n", strindex, Z_STRVAL_PP(zcertval));
} else {
BIO_printf(outfile, "%s\n", Z_STRVAL_PP(zcertval));
}
zend_hash_move_forward_ex(HASH_OF(zheaders), &hpos);
}
}
(void)BIO_reset(infile);
/* write the encrypted data */
SMIME_write_PKCS7(outfile, p7, infile, flags);
RETVAL_TRUE;
clean_exit:
PKCS7_free(p7);
BIO_free(infile);
BIO_free(outfile);
if (recipcerts) {
sk_X509_pop_free(recipcerts, X509_free);
}
}
Там есть такой фрагмент
/* sanity check the cipher */
cipher = php_openssl_get_evp_cipher_from_algo(cipherid);
if (cipher == NULL) {
/* shouldn't happen */
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to get cipher");
goto clean_exit;
}
p7 = PKCS7_encrypt(recipcerts, infile, (EVP_CIPHER*)cipher, flags);
if (p7 == NULL) {
goto clean_exit;
}
Давайте посмотрим на реализацию php_openssl_get_evp_cipher_from_algo:
static const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(long algo) { /* {{{ */
switch (algo) {
#ifndef OPENSSL_NO_RC2
case PHP_OPENSSL_CIPHER_RC2_40:
return EVP_rc2_40_cbc();
break;
case PHP_OPENSSL_CIPHER_RC2_64:
return EVP_rc2_64_cbc();
break;
case PHP_OPENSSL_CIPHER_RC2_128:
return EVP_rc2_cbc();
break;
#endif
#ifndef OPENSSL_NO_DES
case PHP_OPENSSL_CIPHER_DES:
return EVP_des_cbc();
break;
case PHP_OPENSSL_CIPHER_3DES:
return EVP_des_ede3_cbc();
break;
#endif
#ifndef OPENSSL_NO_AES
case PHP_OPENSSL_CIPHER_AES_128_CBC:
return EVP_aes_128_cbc();
break;
case PHP_OPENSSL_CIPHER_AES_192_CBC:
return EVP_aes_192_cbc();
break;
case PHP_OPENSSL_CIPHER_AES_256_CBC:
return EVP_aes_256_cbc();
break;
#endif
default:
return NULL;
break;
}
}
/* }}} */
ГОСТа нет.
Вывод: если вам нужно шифрование в формате CMS с ГОСТами, то требуется дополнительно патчить PHP. Вы можете сделать это и осчастливить своим патчем рунет.
Добрый день!
попытался разобраться с интеграцией rutoken c openssl по этой инструкции:
http://developer.rutoken.ru/pages/viewp … Id=2228251
Собрана версия openssl с поддержкой эллиптической криптографии
openssl-version выдает:
OpenSSL 1.0.1 14 Mar 2012
openssl genpkey -engine pkcs11_gost -algorithm GOST2001 -pkeyopt slot_key_id:50 -pkeyopt paramset:A -pkeyopt pin:12345678
Выдает следующее:
Error configuring OpenSSL
3073689800:error:25066067:DSO support routines:DLFCN_LOAD:could not load the shared library:dso_dlfcn.c:185:filename(/usr/lib/pkcs11-gost/libpkcs11_gost.so): /usr/lib/pkcs11-gost/libpkcs11_gost.so: undefined symbol: EC_ex_dup_data_fun
3073689800:error:25070067:DSO support routines:DSO_load:could not load the shared library:dso_lib.c:244:
3073689800:error:260B6084:engine routines:DYNAMIC_LOAD:dso not found:eng_dyn.c:450:
3073689800:error:260BC066:engine routines:INT_ENGINE_CONFIGURE:engine configuration error:eng_cnf.c:204:section=pkcs11_section, name=dynamic_path, value=/usr/lib/pkcs11-gost/libpkcs11_gost.so
3073689800:error:0E07606D:configuration file routines:MODULE_RUN:module initialization error:conf_mod.c:235:module=engines, value=engine_section, retcode=-1
А у вас программная engine gost работает?
Очень похоже на то, что что-то таки не дособралось с эллиптическими кривыми
как это проверить?
вообще возникло ощущение что не подхватываются символы из libp11.so.2, хотя она лежит в /usr/lib
С этим разобрался, прописал пути к библиотеке libp11.so.2, в LD_LIBRARY_PATH
Теперь выдает вот такое сообщение:
./openssl genpkey -engine pkcs11_gost -algorithm GOST2001 -pkeyopt slot_key_id:0 -pkeyopt paramset:A -pkeyopt pin:12345678
engine "pkcs11_gost" set.
Error writing key
3073783432:error:0D0A30A7:asn1 encoding routines:i2d_PrivateKey:unsupported public key type:i2d_pr.c:77:
3073783432:error:0906900D:PEM routines:PEM_ASN1_write_bio:ASN1 lib:pem_lib.c:357:
Причем ключ на токене по всей видимости создаётся, т к при повторной генерации получаю:
./openssl genpkey -engine pkcs11_gost -algorithm GOST2001 -pkeyopt slot_key_id:0 -pkeyopt paramset:A -pkeyopt pin:12345678
engine "pkcs11_gost" set.
key with such ID allready exists on token
Error generating key
3074176648:error:8107808D:lib(129):PKEY_GOST01CP_KEYGEN:key allready exists on token:gost_sign_pkcs11.c:152:
Это нормальное поведение. Особенности тулзы openssl. Ключ на токене создался.
openssl req -engine pkcs11_gost -new -key 0 -keyform engine -out req.csr
unable to load module (null)
can't use that engine
3073870024:error:80001401:Vendor defined:PKCS11_CTX_load:Unable to load PKCS#11 module:p11_load.c:69:
3073870024:error:8108D097:lib(129):PKCS11_INIT:fail load libp11:engine_pkcs11.c:180:
3073870024:error:260B806D:engine routines:ENGINE_TABLE_REGISTER:init failed:eng_table.c:174:
no engine specified
unable to load Private Key
*** glibc detected *** openssl: double free or corruption (!prev): 0x0889cef8 ***
Ошибка сегментирования (core dumped)
engine не смогла загрузить библиотеку librtpkcs11ecp.so
Нужно смотреть как путь к ней у вас прописан в конфиге и есть ли она по этому пути
Получилось!
но при подписании выдает
*** glibc detected *** openssl: double free or corruption (!prev): 0x0824dc80 ***
Ошибка сегментирования (core dumped)
Хотя всё подписывает, и подпись получается верная
И еще вопрос: как избавиться от запроса ПИНа при подписании? Планируется что подпись должна происходить без участия человека
с ПИН-ом тоже разобрался:
https://github.com/OpenSC/OpenSC/wiki/E … quickstart
PIN can be passed only in the [pkcs11_section] of the openssl.conf (see above).
А как у вас выглядит конфиг openssl?
Это на тему double free
И если не секрет, то что за проект (можно в личку)
Страницы Назад 1 … 8 9 10 11 12 … 17 Далее
Чтобы отправить ответ, нужно авторизоваться или зарегистрироваться
Форум Рутокен → Рутокен и Open Source → Поддержка Рутокен ЭЦП в OpenSSL