LinuxでのGOSTアルゴリズムを使用した証明書承認を伴うPHP-SOAP相互作用

暗号化に以前に出くわし、CryptoProに一度に認証センターを展開する必要があったため、秘密鍵と公開鍵および証明書が何であるかについての一般的な考えはありましたが、これらすべてがLinuxでどのように機能するかについてはあまり分かりませんでした。

RosMinzdravのサービスとの相互作用、つまりSOAPプロトコルを使用する医療従事者の連邦レジストリとの相互作用を確保するために、タスクが発生しました。 クライアント側では、システムはCentOS上にあり、PHPでサービスを実行しています。サーバー側では、GOSTアルゴリズムを使用した証明書承認を伴うSOAPサービスがあります。 RosMinzdravの認証センターとこのキーの証明書によって形成された秘密キーを持つフラッシュドライブがありました。

Linuxの世界でのGOST暗号化アルゴリズムの使用に関する状況を分析した結果、近年では順調な動きが見られましたが、まだすべてが順調ではありませんでした。 そのため、php-soap拡張機能がGOSTアルゴリズムを透過的に理解し、RosMinzdravによって発行された証明書とキーを使用するには、次のことを行う必要があります。



1.配布パッケージのOpenSSLライブラリを1.0.1s以上のバージョンに更新し、GOSTのサポートを構成します。

2.発行されたキーと証明書をOpenSSLが理解できる形式に変換します。 OpenSSLの動作を確認します。

3. PHPのOpenSSL拡張機能を修正し、PHP自体を再コンパイルします。 PHPでSOAPをテストします。



それでは始めましょう。 phpおよびopensslライブラリによってインストールされた配布キットのデータ:



# lsb_release -a LSB Version: :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch Distributor ID: CentOS Description: CentOS release 6.4 (Final) Release: 6.4 Codename: Final # yum list installed | grep php php.x86_64 5.3.3-22.el6 @base php-cli.x86_64 5.3.3-22.el6 @base php-common.x86_64 5.3.3-22.el6 @base php-dba.x86_64 5.3.3-22.el6 @base php-devel.x86_64 5.3.3-22.el6 @base php-imap.x86_64 5.3.3-22.el6 @base php-ldap.x86_64 5.3.3-22.el6 @base php-lessphp.noarch 0.3.9-1.el6 @epel php-mbstring.x86_64 5.3.3-22.el6 @base php-mcrypt.x86_64 5.3.3-1.el6 @epel php-odbc.x86_64 5.3.3-22.el6 @base php-pdo.x86_64 5.3.3-22.el6 @base php-pear.noarch 1:1.9.4-4.el6 @base php-pgsql.x86_64 5.3.3-22.el6 @base php-process.x86_64 5.3.3-22.el6 @base php-shout.x86_64 0.9.2-6.el6 @epel php-soap.x86_64 5.3.3-22.el6 @base php-xml.x86_64 5.3.3-22.el6 @base php-xmlrpc.x86_64 5.3.3-22.el6 @base # yum list installed | grep openssl openssl.x86_64 1.0.0-27.el6_4.2 @updates openssl-devel.x86_64 1.0.0-27.el6_4.2 @updates
      
      





OpenSSLライブラリの更新


「ソースから」コンパイルしてシステムを詰まらせる方法は、私たちの方法ではありません。 したがって、最適なオプションは完成したパッケージを見つけることであり、axivoリポジトリで見つけました。

 # rpm -ivh --nosignature http://rpm.axivo.com/redhat/axivo-release-6-1.noarch.rpm # yum --enablerepo=axivo update openssl
      
      





OpenSSLのインストール済みバージョンの確認:

 # openssl version OpenSSL 1.0.1e 11 Feb 2013
      
      





次に、GOSTアルゴリズムを使用するようにライブラリを設定する必要があります。そのため、 /etc/pki/tls/openssl.cnf



にある設定ファイルを編集し、ファイルの最初に次の行を追加します。

 openssl_conf = openssl_def
      
      





そして、ファイルの最後に:

 [openssl_def] engines=engine_section [engine_section] gost=gost_section [gost_section] engine_id=gost #!!     dynamic_path=/usr/lib64/openssl/engines/libgost.so default_algorithms=ALL CRYPT_PARAMS=id-Gost28147-89-CryptoPro-A-ParamSet
      
      





変更が行われた後、OpenSSLがGOSTアルゴリズムを認識しているかどうかを確認します。

 #openssl ciphers | tr ":" "\n" | grep GOST GOST2001-GOST89-GOST89 GOST94-GOST89-GOST89
      
      





発行されたキーと証明書をOpenSSLが理解できる形式に変換します


これを行うには、CryptoPRO CSP 3.6がインストールされたWindowsマシンが必要です。 開発者のサイトからリークしました(3か月間デモモードが提供されます)。

最初に行うことは、CryptoProを使用してキーコンテナーをレジストリにエクスポートすることです。 これを行うには、WindowsのコントロールパネルからCryptoProを開きます。 キーメディアをコンピューターに挿入します。 通常のフラッシュドライブの場合、[ハードウェア]タブのリーダーには、[すべてのリムーバブルドライブ]と[レジストリ]が含まれていることを確認します。 通常のフラッシュドライブではなく、RuTokenやEtokenなどのメディアがある場合は、CryptoProで使用するためのドライバーとライブラリが必要です(同じタブの[リーダーの構成]セクションに表示されます)。



次に、「サービス」タブに移動して「コピー」をクリックし、「参照」をクリックして、リストからキーコンテナを選択します。 そこで突然彼が見つからない場合は、前の段落に戻ってすべてを確認します。 次に、新しいキーコンテナの意味のある名前を入力し、[完了]をクリックして、表示されるウィンドウでメディアとして[レジストリ]を選択します。 コンテナに新しいパスワードを設定しません。

次に、新しいコンテナに証明書をインストールする必要があります。 CryptoProの[サービス]タブで、[個人証明書のインストール]ボタンをクリックし、証明書を含むファイルを指定し、[次へ]をクリックし、作成したコンテナーを選択し、[コンテナーに証明書をインストール]チェックボックスを忘れないでください。

この証明書を秘密キーとともにPKSC#12形式でエクスポートするには、サードパーティのユーティリティが必要です。 ここで購入するか、インターネットでp12fromgostcspの名前で見つけることができます。 このユーティリティを起動し、証明書を選択し、パスワードを空のままにしてmycert.p12ファイルに保存します。

受信した証明書をLinuxマシンにコピーします。 証明書にプライベートキーとパブリックキーの両方があることを確認します。

 # openssl pkcs12 -in mycert.p12 -nodes
      
      





パスワードの入力を求められたら、Enterキーを押します。 そして、BEGIN CERTIFICATEおよびBEGIN PRIVATE KEY文字列の存在を探します。 行がある場合、すべてが正常です。 受信した証明書をPEM形式に変換します。

 # openssl pkcs12 -in mycert.p12 -out mycert.pem -nodes -clcerts
      
      





クライアント証明書による承認だけでなく、サーバー自体の有効性のチェックも必要な場合は、証明機関のルート証明書が必要になります。 秘密鍵が含まれていないため、Windowsを介して簡単に開き、X.509エンコード(証明書の表示時に[構成]タブから)でDER形式で保存できます。 次に、OpenSSLを介してPEM形式に変換します。

 # openssl x509 -inform DER -in cacert.cer -outform PEM -out cacert.pem
      
      





cacert.cerは、ルート証明書を含むソースファイルの名前です。 OpenSSLコマンドを使用して、証明書を使用してサーバーへの接続を確認できます。

 # openssl s_client -connect service.rosminzdrav.ru:443 -CAfile cacert.pem -cert mycert.pem
      
      





その結果、すべてが正しく行われた場合、最後にこの出力を取得する必要があります。

 New, TLSv1/SSLv3, Cipher is GOST2001-GOST89-GOST89 Server public key is 256 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : GOST2001-GOST89-GOST89 Session-ID: *** Session-ID-ctx: Master-Key: *** Key-Arg : None Krb5 Principal: None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1375875984 Timeout : 300 (sec) Verify return code: 0 (ok)
      
      





PHPの編集と再コンパイル


主な問題は、OpenSSLがデフォルトの構成ファイルを使用するため(GOSTアルゴリズムの設定がある場所)、使用する前にOPENSSL_config(NULL)関数を呼び出す必要があることです。 これはPHP OpenSSL拡張機能では行われていないため、SSL接続を使用する場合、PHP-SOAPモジュールはGOSTアルゴリズムを認識しません。 ところで、同じことが他のライブラリ、たとえばcurlにも当てはまります。 また、使用する場合はパッチを適用する必要があります。

それでは始めましょう。 OpenSSLを修正するには、CentOSではモジュールによってOpenSSL拡張が作成されていないため、すべてのPHPを再コンパイルする必要があります。

パッケージを構築するための環境を準備します。

 # yum install rpm-build redhat-rpm-config # mkdir /root/rpmbuild # cd /root/rpmbuild # mkdir BUILD RPMS SOURCES SPECS SRPMS # mkdir RPMS/{i386,i486,i586,i686,noarch,athlon}
      
      





PHPソースをダウンロードしてインストールします。

 # wget http://vault.centos.org/6.4/os/Source/SPackages/php-5.3.3-22.el6.src.rpm # rpm -ivh php-5.3.3-22.el6.src.rpm
      
      





SOURCESフォルダーに移動してphpを抽出し、ソースを含むフォルダーのコピーを作成します。

 # cd SOURCES # tar xvjf php-5.3.3.tar.bz2 # cp php-5.3.3 php-5.3.3p -R
      
      





php-5.3.3p/ext/openssl/openssl.c





文字列SSL_library_init();



を見つけSSL_library_init();



(私はこの行番号985を持っています)そしてその前に書きます

OPENSSL_config(NULL);





SOURCESフォルダーに移動して、パッチを作成します。

 # diff -uNr php-5.3.3/ php-5.3.3p/ > php-5.3.3-gostfix.patch
      
      





結果は、次の内容のファイルです。

 diff -uNr php-5.3.3/ext/openssl/openssl.c php-5.3.3p/ext/openssl/openssl.c --- php-5.3.3/ext/openssl/openssl.c 2010-06-26 20:03:39.000000000 +0400 +++ php-5.3.3p/ext/openssl/openssl.c 2013-08-07 11:32:41.944581280 +0400 @@ -981,7 +981,7 @@ le_key = zend_register_list_destructors_ex(php_pkey_free, NULL, "OpenSSL key", module_number); le_x509 = zend_register_list_destructors_ex(php_x509_free, NULL, "OpenSSL X.509", module_number); le_csr = zend_register_list_destructors_ex(php_csr_free, NULL, "OpenSSL X.509 CSR", module_number); - + OPENSSL_config(NULL); SSL_library_init(); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests();
      
      





ここで、コレクターにパッチを強制的に使用させる必要があります。 アセンブリ規則は、SPEC / php.specファイルに記述されています。 これを開き、パッチの説明行(Patch230で始まるこの行があります)の後に、新しいパッチの説明を含む行を挿入します。

 Patch231: php-5.3.3-gostfix.patch
      
      





また、アセンブリの前にこのパッチの呼び出しを処方します。このため、%patchで始まる行を探し、それらの最後で処方します

 %patch231 -p1
      
      





ファイルを保存します。 パッケージをアセンブルする前に、アセンブリのすべての依存関係を配置します。

 # yum install bzip2-devel db4-devel gmp-devel httpd-devel pam-devel sqlite-devel pcre-devel libedit-devel libtool-ltdl-devel libc-client-devel cyrus-sasl-devel openldap-devel mysql-devel postgresql-devel libxml2-devel net-snmp-devel libxslt-devel libxml2-devel libXpm-devel libpng-devel freetype-devel libtidy-devel aspell-devel recode-devel libicu-devel enchant-devel net-snmp
      
      





次に、アセンブリに進み、rpmbuldフォルダーから次のコマンドを実行します。

 rpmbuild -ba SPECS/php.spec
      
      





アセンブリには時間がかかり、すべてがうまくいった場合、RPMS / {Your_architecture}フォルダーに準備が整ったrpm_packagesが表示されます。

x86_64アーキテクチャの場合:

 # ls RPMS/x86_64/ php-5.3.3-22.el6.x86_64.rpm php-devel-5.3.3-22.el6.x86_64.rpm php-intl-5.3.3-22.el6.x86_64.rpm php-pgsql-5.3.3-22.el6.x86_64.rpm php-tidy-5.3.3-22.el6.x86_64.rpm php-bcmath-5.3.3-22.el6.x86_64.rpm php-embedded-5.3.3-22.el6.x86_64.rpm php-ldap-5.3.3-22.el6.x86_64.rpm php-process-5.3.3-22.el6.x86_64.rpm php-xml-5.3.3-22.el6.x86_64.rpm php-cli-5.3.3-22.el6.x86_64.rpm php-enchant-5.3.3-22.el6.x86_64.rpm php-mbstring-5.3.3-22.el6.x86_64.rpm php-pspell-5.3.3-22.el6.x86_64.rpm p hp-xmlrpc-5.3.3-22.el6.x86_64.rpm php-common-5.3.3-22.el6.x86_64.rpm php-fpm-5.3.3-22.el6.x86_64.rpm php-mysql-5.3.3-22.el6.x86_64.rpm php-recode-5.3.3-22.el6.x86_64.rpm php-zts-5.3.3-22.el6.x86_64.rpm php-dba-5.3.3-22.el6.x86_64.rpm php-gd-5.3.3-22.el6.x86_64.rpm php-odbc-5.3.3-22.el6.x86_64.rpm php-snmp-5.3.3-22.el6.x86_64.rpm php-debuginfo-5.3.3-22.el6.x86_64.rpm php-imap-5.3.3-22.el6.x86_64.rpm php-pdo-5.3.3-22.el6.x86_64.rpm php-soap-5.3.3-22.el6.x86_64.rpm
      
      





これで、すでにインストールされているphpの上に、この「良い」ものすべてを置き換えてインストールできます。

 rpm -Uvh --replacepkgs --replacefiles RPMS/x86_64/*
      
      





次に、php-soapの動作を確認します。 たとえば、次のコードを使用できます(サービス「医療提供者の連邦登録」の例):

 <?php class GetEmployees { public $ogrn; } $cert="/mycert.pem"; // $wsdl="https://service.rosminzdrav.ru/MedStaffIntegration/MedStaff.svc?wsdl"; // wdsl  $loc = "https://service.rosminzdrav.ru/MedStaffIntegration/medstaff.svc/basic"; //   $sp = new SoapClient($wsdl,array( 'local_cert' => $cert, 'trace' => 1, 'exceptions' => 1, 'soap_version' => SOAP_1_1, 'location' =>$loc, )); $emp = new GetEmployees; $emp->ogrn = '1022303554570'; try{ $data = $sp->GetEmployees($emp); print_r($data); } catch (SoapFault $e) { echo "<h2>Exception Error!</h2>"; echo $sp->__getLastRequest(); echo get_class($e); echo $e->getMessage(); }
      
      





すべてがうまくいけば、エラーは発生せず、PHP-SOAPは問題なく動作します。

さらに、必要に応じて、curlライブラリを調整したり、サーバー証明書を確認したり、一般的に、GOSTアルゴリズムを使用した証明書に応じた許可でWebサーバーを起動するまでのSSL接続に有効なすべての操作を実行できます。



All Articles