Win32 users having trouble getting php_openssl to work should make sure that they replace ALL the versions of libeay32.dll and ssleay32.dll, with the ones included with PHP. This is especially true while using Apache2 and OpenSSL together, as some OpenSSL win32 packages include older versions of these two files.
OpenSSL 関数
導入
このモジュールは、署名の生成および認証、そして、データのシール (暗号化)およびオープン(復号化)を行うために、 » OpenSSL の関数を使用します。 OpenSSL は多くの機能を提供しますが、これらはまだこのモジュールでは サポートされていません。これらのいくつかは将来的に追加される可能性が あります。
要件
OpenSSL 関数を使用するためには、» OpenSSL パッケージがインストール されていることを要します。 PHP のバージョン 4.0.5 から 4.3.1 までは、OpenSSL >= 0.9.5 で動作します。他のバージョン(PHP <=4.0.4 および >= 4.3.2) では OpenSSL >= 0.9.6 を必要とします。
最新のバージョンの OpenSSL を使用するようにしてください。 さもないと、Web サーバへの攻撃に対しての脆弱性をかかえてしまいます。
インストール手順
PHP の OpenSSL サポートを使用するには、--with-openssl[=DIR] を指定して PHP を コンパイルする必要があります。
注意: Win32 ユーザへの注意 この拡張モジュールを動作させるには、 Windows システムの PATH が通った場所に DLL ファイルが存在する必要があります。 FAQ の "Windows で PHP のディレクトリを PATH に追加するにはどうすればいいのですか?" で、その方法を説明しています。 DLL ファイルを PHP のフォルダから Windows のシステムディレクトリにコピーしても動作します (システムディレクトリは、デフォルトで PATH に含まれるからです) が、これは推奨しません。 この拡張モジュールを使用するには、以下のファイルが PATH の通った場所にある必要があります。 libeay32.dll
加えてキー生成およびサイン認証関数を使用する計画がある場合、 システムに 有効な openssl.cnf をインストールする 必要があります。PHP 4.3.0 以降、Win32 バイナリ配布版の openssl フォルダに サンプル設定ファイルが含まれています。 PHP 4.2.0 以降を使用しておりこのファイルがない場合、 » OpenSSLのホームページから入手するか PHP 4.3.0 のリリース版をダウンロードし、それらに含まれる 設定ファイルを使用することができます。 PHP は、 以下のロジックにより openssl.cnf を探します。
- 環境変数 OPENSSL_CONF が設定された場合、 設定ファイルの(ファイル名を含む)パスとして使用されます。
- 環境変数 SSLEAY_CONF が設定された場合、 設定ファイルの(ファイル名を含む)パスとして使用されます。
- ファイル openssl.cnf はデフォルトの認証エリアに あることが仮定され、openssl DLL がコンパイルされた時間で設定されます。 通常、デフォルトのファイル名が c:\usr\local\ssl\openssl.cnf であることを 意味します。
インストール時に、設定ファイルを c:\usr\local\ssl\openssl.cnf または 他の場所にインストールし、(例えば仮想ホスト毎に)環境変数に設定ファ イルの場所を指定するかを選ぶ必要があります。 設定ファイルを必要とする関数の configargs に より、デフォルトのパスを上書きすることが可能であることに注意してください。
実行時設定
設定ディレクティブは定義されていません。
リソース型
キー/証明書パラメータ
OpenSSL 関数のうち、キーまたは証明書パラメータを必要とするものは ごく一部です。PHP 4.0.5 より以前では、openssl_get_xxx 関数により り返されたキーまたは証明書リソースを使用する必要がありました。 これより後のバージョンでは、次の方法のどれかを使用することが 可能となる予定です。
-
証明書
- openssl_x509_read() から返された X.509 リソース。
- file://path/to/cert.pem 形式の文字列。 このファイルは、PEM エンコードされた証明書である必要があります。
- PEMエンコードされた証明書の内容を含む文字列。
-
公開鍵/秘密鍵
- openssl_get_publickey() あるいは openssl_get_privatekey() から返された キーリソース。
- 公開鍵のみ: X.509リソース。
- file://path/to/file.pem 形式の文字列。- このファイルは、PEM エンコードされた証明書/秘密鍵である 必要があります(両方を含むことも可能です)。
- PEM エンコードされた証明書/キーの内容を含む文字列
- 秘密鍵については array($key, $passphrase) という構文を使用することも可能です。 ただし、$key は file:// または上記のテキスト表現形式を使用 して指定したキー、$passphrase はその秘密鍵に関するパスワードを 有する文字列を表します。
証明書の認証
サイン/証明書を認証する関数をコールする際、 cainfo パラメータは、ファイルと認証済みの CA ファイルの場所を指定するファイルディレクトリ名を含む配列です。 ディレクトリが指定された場合、openssl コマンドが 使用できるような正しい形式にハッシュされたディレクトリである必要が あります。
定義済み定数
以下の定数が定義されています。 この関数の拡張モジュールが PHP 組み込みでコンパイルされているか、 実行時に動的にロードされている場合のみ使用可能です。
目的を調べるフラグ
パディングフラグ
PKCS7 フラグ/定数
S/MIME 関数はビットフィールドを使用して指定したフラグを使用します。 このビットフィールドには、以下の値を一つ以上含むことが可能です。
| 定数 | 説明 |
|---|---|
| PKCS7_TEXT | text/plain content type ヘッダを暗号化/署名されたメッセージに 追加します。復号化または認証を行う際には、このヘッダは出力から 取り除かれます。復号化または認証されたメッセージがMIME 型 text/plain でない場合、エラーとなります。 |
| PKCS7_BINARY | 通常は、入力されたメッセージは CR および LF を行端として使用した 「正規化」された形式に変換されます。こらは、S/MIME の規格に 基づくものです。このオプションが指定された場合、変換は行われません。 この機能は、MIME 形式でないバイナリデータを処理する際に 便利です。 |
| PKCS7_NOINTERN | メッセージを認証する際に、通常、メッセージに含まれる証明書が 証明書にサインする際に検索されます。 このオプションでは、 openssl_pkcs7_verify() の extracerts パラメータで指定した証明書 のみが使用されます。しかし、指定された証明書を信頼されていな い CA として使用することも可能です。 |
| PKCS7_NOVERIFY | サインつきメッセージをサインした証明書の署名について 検証しません。 |
| PKCS7_NOCHAIN | サインを行った側の証明書の認証の連鎖を行いません。 この場合、サイン付きのメッセージにある証明書を未認証の CA として使用しません。 |
| PKCS7_NOCERTS | メッセージにサインする際、通常はサインをする人の証明書が挿入 されますが、このオプションを指定した場合はそうなりません。これに よりサイン付きのメッセージのサイズは小さくなりますが、認証 側が(例えば、openssl_pkcs7_verify() の extracerts を用いて渡すことにより) サインをした人の証明書のコピーをローカルに用意する必要があります。 |
| PKCS7_NOATTR | 通常、メッセージがサインされる時、サインした時間やサポートされる 対象アルゴリズムを含む一連の属性が付加されます。このオプションを 指定した場合、それらの属性は付加されません。 |
| PKCS7_DETACHED | メッセージにサインをする際、MIME型 multipart/signed を指定して クリアテキストでサインを行います。これは、 openssl_pkcs7_sign() において フラグを指定しなかった場合の flags パラメータのデフォルトです。このオプションをオフにした場合、 メッセージは不透明なサインによりサインされます。これは、 メールリレイによる変換に対してより耐性がありますが、S/MIME を サポートしないメールエージェントでは読むことはできません。 |
| PKCS7_NOSIGS | メッセージにサインや認証を試みません。 |
注意: これらの定数は、4.0.6 で追加されました。
署名アルゴリズム
- OPENSSL_ALGO_SHA1 (integer)
- openssl_sign() および openssl_verify() のデフォルトアルゴリズムとして用いられます。
- OPENSSL_ALGO_MD5 (integer)
- OPENSSL_ALGO_MD4 (integer)
- OPENSSL_ALGO_MD2 (integer)
注意: これらの定数は、5.0.0 で追加されました。
目次
- openssl_csr_export_to_file — CSR をファイルにエクスポートする
- openssl_csr_export — CSR を文字列としてエクスポートする
- openssl_csr_get_public_key — CERT の公開鍵を返す
- openssl_csr_get_subject — CERT の subject を返す
- openssl_csr_new — CSR を作成する
- openssl_csr_sign — 他の CERT(あるいは自分自身)で証明書をサインする
- openssl_error_string — OpenSSL エラーメッセージを返す
- openssl_free_key — キーリソースを開放する
- openssl_get_privatekey — openssl_pkey_get_private のエイリアス
- openssl_get_publickey — openssl_pkey_get_public のエイリアス
- openssl_open — シール(暗号化)されたデータをオープン(復号)する
- openssl_pkcs12_export_to_file — PKCS#12 互換の証明書保存ファイルをエクスポートする
- openssl_pkcs12_export — PKCS#12 互換の証明書保存ファイルを変数にエクスポートする
- openssl_pkcs12_read — PKCS#12 認証ストアをパースして配列形式にする
- openssl_pkcs7_decrypt — S/MIME 暗号化されたメッセージを復号する
- openssl_pkcs7_encrypt — S/MIME メッセージを暗号化する
- openssl_pkcs7_sign — S/MIME メッセージにサインする
- openssl_pkcs7_verify — S/MIME でサインされたメッセージの署名を検証する
- openssl_pkey_export_to_file — エクスポート可能な形式で、キーをファイルに取得する
- openssl_pkey_export — エクスポート可能な形式で、キーを文字列に取得する
- openssl_pkey_free — 秘密鍵を開放する
- openssl_pkey_get_details — キーの詳細の配列を返す
- openssl_pkey_get_private — 秘密鍵を取得する
- openssl_pkey_get_public — 証明書から公開鍵を抽出し、使用できるようにする
- openssl_pkey_new — 新規に秘密鍵を生成する
- openssl_private_decrypt — 秘密鍵でデータを復号する
- openssl_private_encrypt — 秘密鍵でデータを暗号化する
- openssl_public_decrypt — 公開鍵でデータを復号する
- openssl_public_encrypt — 公開鍵でデータを暗号化する
- openssl_seal — データをシール(暗号化)する
- openssl_sign — 署名を生成する
- openssl_verify — 署名を検証する
- openssl_x509_check_private_key — 秘密鍵が証明書に対応するかを確認する
- openssl_x509_checkpurpose — 証明書が特定の目的に使用可能かどうか確認する
- openssl_x509_export_to_file — 証明書をファイルにエクスポートする
- openssl_x509_export — 証明書を文字列としてエクスポートする
- openssl_x509_free — 証明書リソースを開放する
- openssl_x509_parse — X509 証明書をパースし、配列として情報を返す
- openssl_x509_read — X.509 証明書をパースし、リソース ID を返す
OpenSSL
28-Nov-2007 07:07
20-Nov-2007 11:04
There doesn't seem to be a function here to test if a cert is valid (i.e. not corrupt)... This bash snippet should help. Sorry it's not PHP. slap it in a system(); call or make it a bash script and call it that way or something...
if [ "`openssl x509 -in /etc/certs/my.crt -noout -modulus`" = "`openssl rsa -in /etc/keys/my.key -noout -modulus`" ]; then echo "Match"; else echo "Different"; fi
30-Oct-2007 01:01
For working of openssl in windows platform IIS webserver, we need to enable in php.ini, tne copy libeay32.dll and ssleay32.dll to the php folder (or windows's system32 folder) and add both dll's path to the window's PATH variable. It seems to be working for me after I did these changes.
30-Aug-2007 06:16
Use this for simple public/private key encryption.
<?php
/**
* Point to your config file
*
*/
define("OPEN_SSL_CONF_PATH", "/usr/share/ssl/openssl.cnf");
/**
* Length of time certificate is valid (in days)
*
*/
define("OPEN_SSL_CERT_DAYS_VALID", 365);
/**
* Passphrase required with private key
*
*/
define("OPEN_SSL_PASSPHRASE", "lkdfjbjeyrasdfvkajwdeblsolkdkdjfbvzslalsmdbfvksb");
/**
* Enter description here...
*
*/
define("OPEN_SSL_PUBKEY_PATH", "/docs/domains/mywebsite.com/docs/key.pem"); // Public key path
/**
* A wrapper class for a simple subset of the PHP OpenSSL functions. Use for public key encryption jobs.
*
* <code>
*
* // To configure
* // 1. Set OPEN_SSL_CONF_PATH to the path of your openssl.cnf file.
* // 2. Set OPEN_SSL_PASSPHRASE to any passphrase.
* // 3. Use the OpenSSL::do_csr method to generate your private and public keys (see next section).
* // 4. Save the private key somewhere offline and save your public key somewhere on this machine.
* // 5. Set OPEN_SSL_PUBKEY_PATH to the public key's path.
*
* // To generate keys
* $ossl = new OpenSSL;
* $ossl->do_csr();
* $privatekey = $ossl->privatekey;
* $publickey = $ossl->publickey;
* unset($ossl);
*
* // Encrypt
* $text = "Secret text";
* $ossl = new OpenSSL;
* $ossl->encrypt($text);
* $encrypted_text = $ossl->crypttext;
* $ekey = $ossl->ekey;
* unset($ossl);
*
* // Decrypt
* $ossl = new OpenSSL;
* $decrypted_text = $ossl->decrypt($encrypted_text, $privatekey, $ekey);
* unset($ossl);
*
* @author Matt Alexander (mattalexx@gmail.com) [based on code by Alex Poole (php@wwwcrm.com)]
* @copyright 2007
*
*/
class OpenSSL {
public $privatekey;
public $publickey;
public $csr;
public $crypttext;
public $ekey;
public function encrypt($plain) {
// Turn public key into resource
$publickey = openssl_get_publickey(is_file(OPEN_SSL_PUBKEY_PATH)? file_get_contents(OPEN_SSL_PUBKEY_PATH) : OPEN_SSL_PUBKEY_PATH);
// Encrypt
openssl_seal($plain, $crypttext, $ekey, array($publickey));
openssl_free_key($publickey);
// Set values
$this->crypttext = $crypttext;
$this->ekey = $ekey[0];
}
public function decrypt($crypt, $privatekey, $ekey="") {
// Turn private key into resource
$privatekey = openssl_get_privatekey((is_file($privatekey)? file_get_contents($privatekey) : $privatekey), OPEN_SSL_PASSPHRASE);
// Decrypt
openssl_open($crypt, $plaintext, $ekey, $privatekey);
openssl_free_key($privatekey);
// Return value
return $plaintext;
}
public function do_csr(
$countryName = "UK",
$stateOrProvinceName = "London",
$localityName = "Blah",
$organizationName = "Blah1",
$organizationalUnitName = "Blah2",
$commonName = "Joe Bloggs",
$emailAddress = "openssl@domain.com"
) {
$dn = array(
"countryName" => $countryName,
"stateOrProvinceName" => $stateOrProvinceName,
"localityName" => $localityName,
"organizationName" => $organizationName,
"organizationalUnitName" => $organizationalUnitName,
"commonName" => $commonName,
"emailAddress" => $emailAddress
);
$config = array(
"config" => OPEN_SSL_CONF_PATH
);
$privkey = openssl_pkey_new();
$csr = openssl_csr_new($dn, $privkey, $config);
$sscert = openssl_csr_sign($csr, null, $privkey, OPEN_SSL_CERT_DAYS_VALID, $config);
openssl_x509_export($sscert, $this->publickey);
openssl_pkey_export($privkey, $this->privatekey, OPEN_SSL_PASSPHRASE, $config);
openssl_csr_export($csr, $this->csr);
}
}
?>
17-Aug-2007 03:17
There is a note below regarding the need to copy BOTH ssleay32.dll AND libeay32.dll to a folder in the system PATH on Win32 systems.
That is absolutely true. It should be noted also that Windows will search the Windows system directories before it will search the PATH. If you have existing .dlls in these directories - rename (rather than deleting in case you need to undo your changes) them and copy over the latest version of these files.
Key locations may include the /i386, /windows/system32, and ~/apache/.../modules directories.
I also updated my ~/subversion/bin directory.
-CF
27-Apr-2007 09:31
I generate certificates in such a way.
$config = array("config" => "d:/sslcert/openssl.cnf");
$dn = array(
"countryName" => "RU",
"stateOrProvinceName" => "Russia",
"localityName" => "Saint-Petersburg",
"organizationName" => "temp",
"organizationalUnitName" => "temp",
"commonName" => "temp",
"emailAddress" => "temp@temp.com"
);
$privkey_enc = openssl_pkey_new($config);
$csr = openssl_csr_new($dn, $privkey_enc, $config);
$sscert = openssl_csr_sign($csr, null, $privkey_enc, 365);
openssl_x509_export_to_file($sscert, "d:/cert_enc.crt");
openssl_pkey_export_to_file($privkey_enc, "d:/privkey_enc.pem");
As a result all the received certificates have identical serial number (00). But it should not be! How to avoid it?
29-Mar-2007 03:58
Currently, all OpenSSL Functions defined in PHP only utilize the PEM format. Use the following code to convert from DER to PEM and PEM to DER.
<?php
$pem_data = file_get_contents($cert_path.$pem_file);
$pem2der = pem2der($pem_data);
$der_data = file_get_contents($cert_path.$der_file);
$der2pem = der2pem($der_data);
function pem2der($pem_data) {
$begin = "CERTIFICATE-----";
$end = "-----END";
$pem_data = substr($pem_data, strpos($pem_data, $begin)+strlen($begin));
$pem_data = substr($pem_data, 0, strpos($pem_data, $end));
$der = base64_decode($pem_data);
return $der;
}
function der2pem($der_data) {
$pem = chunk_split(base64_encode($der_data), 64, "\n");
$pem = "-----BEGIN CERTIFICATE-----\n".$pem."-----END CERTIFICATE-----\n";
return $pem;
}
?>
04-Dec-2006 07:23
Windows users be warned that you need the following file in system32:
msvcr71.dll
It has to go in system32, is not picked up from php/dlls
27-Jul-2006 03:23
The php4 distribution for Windows/IIS has a README-SSL.txt which strongly implies that just the path needs to be added to the OPENSLL_CONF variable in the server's environment variables. Be sure to add the file name and extension too.
E.g.: c:\php-4.3.11\openssl\openssl.cnf
16-May-2006 05:34
For w32 users to enable OpenSSL support. As well as copying "libeay32.dll" to the windows system32 folder you also need to copy "ssleay32.dll". The documentation above should probably be updated to note this.
This requirement was documented at the libcurl pages:
http://curl.haxx.se/libcurl/php/install.html#windows
17-Nov-2005 01:47
If you want to use PHP for public / private key encryption jobs without needing to know the ins and outs of the Open SSL extension, the following may be of interest:
http://www.karenandalex.com/php_stuff/_class_OpenSSL.phps
This class was unavailable for a long while (server problems) but is now back up. Apologies to those who clicked through and got a 404
I hope it is useful to you...
Alex
09-Nov-2005 05:07
FreeBSD Ports tree php5-openssl uses openssl-0.9.8a. This is a problem, as if you install these two ports and attempt to open an HTTPS URL within PHP, it will fail with this error from openssl_error_string(): error:140A90A1:SSL routines:func(169):reason(161) which is SSL_R_LIBRARY_HAS_NO_CIPHERS or "library has no ciphers"
This is because the openssl library now requires you to load your ciphers manually -- all ciphers are not automatically loaded for you.
I don't believe the php5-openssl module has been updated to do this before opening an SSL connection (as of 5.0.5).
Using openssl-0.9.7i seems to work; symlinking libcrypto.so.3 to libcrypto.so.4 prevents the php5-openssl port from trying to install openssl-0.9.8a. So install openssl-stable (0.9.7i) from ports first, symlink 2nd, then install php5-openssl 3rd, and you should be OK.
09-Nov-2005 03:42
The openssl functions were disabled in Debian release 3.0 (woody), but as of release 3.1 (sarge) they're available again.
31-Aug-2005 08:21
Sorry, the code in my previous note doesn't work... the last line should read:
$csr = openssl_csr_new(array('commonName'=>'MyCSR'),$pkey,$config);
31-Aug-2005 01:54
"You need to have a valid openssl.cnf installed for this function to operate correctly" includes most openssl functions. You can force php to find your openssl.cnf file as follows:
$config = array('config'=>'/path/to/openssl.cnf');
$pkey = openssl_pkey_new($config);
$csr = openssl_csr_new('MyCSR',$pkey,$config);
20-Oct-2004 09:38
In case you're wondering what's a "correctly hashed" directory for the use with cainfo: it's simply a directory which contains CA public certificates in PEM/X.509 format. You can get such certificates either from the CA's website (they advertise it in visible places) or from your browser. In Explorer for instance you can click on the little yellow padlock, go to the CA entry and export it.
The only trick with the directory is that file names must be in the form "hash.#". The "hash" part is the 8-digit hex hash of the certificate, while the # part is a number which serves to differentiate certificates which give the same hash (yes, it can happen with certificates coming from the same CA). Usually # is 0, but you also can use 1, 2 and so on when having more certs with the same hash.
In order to obtain the hash of a certificate you can use the openssl command line utility like this:
openssl x509 -hash -in certfile.cer | head -1
17-Sep-2004 03:18
For newbies (as me):
If you want to try at home on win32, you can learn how to install apache+ssl on this url: http://tud.at/programm/apache-ssl-win32-howto.php3
Versions on English, Spanish and French.
Just I have read and install and run perfectly.
03-Feb-2004 03:43
Debian maintainers have disabled the openssl support because it seems to help break apache on startup. (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=193343 and http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=165699)
- Norman