ホームページ  >  記事  >  バックエンド開発  >  openssl_verifyの使い方! ?

openssl_verifyの使い方! ?

WBOY
WBOYオリジナル
2016-06-23 14:27:153849ブラウズ

openssl_verify

openssl_verify の使用法は何ですか?
3 つのパラメータにどのような値が渡されるのか知りたいです!

ディスカッションへの返信 (解決策)

$pub_key_id は間違いなく公開鍵です!他の 2 つのパラメーター $data と $signature は何を意味しますか?

$signature 公開鍵暗号化によって生成されたデータ、$data 元データ
$fp = fopen("pem public key", "r");
$cert = fread($fp, 8192); ;暗号化する方法は?

通常、これは無視して構いません。

もう解決しました!
オンラインでカテゴリを見つけました。それは機能します。
/**
* ある pem エンコードされた 証明書 は 別の 証明書 の署名者ですか?
*
* PHP の openssl 機能は、安定した
* API とドキュメント自体が暗号化されていないため、大幅に制限されています。
* 特に openssl_verify() に関するドキュメントでは、
* が検証する実際の署名を取得する場所についてはまったく説明されていません。  以下の isCertSigner() 関数
* は、引数として 2 つの PEM エンコードされた証明書を受け入れ、
* 1 つの証明書が他の証明書の署名に使用された場合は true を返します。  これは
* openssl_pkey_get_public() と openssl_public_decrypt() の openssl 関数にのみ依存しており、
* はかなり安定しているはずです。  ASN 解析コード スニペットのほとんどは、horde プロジェクトの smime.php から
* 借用したものです。
*
* @author Mike Green
* @copyright Copyright (c) 2010, Mike Green
* @license http://opensource.org/licenses/gpl-2.0.php GPLv2
 */

/**
* viewSource がリクエスト文字列にある場合は、ソースを表示します、ルーク。

if (isset($_REQUEST['viewSource'])) {
die(highlight_file(__FILE__));
}
*/
class OpensslVerifyAPI {
/**
* エンコードされた証明書から署名を抽出します。
* 2 つのセクションと 1 つのビットストリームを含むセクション コンテナで構成される x509 でエンコードされた証明書を期待します。  ビットストリームには、発行元の
* 署名者の公開鍵によって暗号化された
* 元の暗号化署名が含まれています。
* @param string $der
* @return string 成功の場合
* @return bool false 失敗の場合
 */
function extractSignature($der=false) {
if ( strlen($der) < 5) { return false; }
// コンテナシーケンスをスキップします
$der = substr($der,4)
// 2 つのシーケンスをバースルーして、最後のビットストリームを返します
while(str len {
を使用を使用する を使用する 使用する 使用する 使用する 使用する 使用する 使用する - ケース0x03:ord($ der [1]);                        $len = ($len << 8) | ord($der[$i + 2]);

}
return substr($der,3 + $bytes, $len);
休憩。
// シーケンス
case 0x30:
$len = ord($der[1]);
$bytes = 0;
if ($len & 0x80) {
$bytes = $len & 0x0f;
$len = 0;
for($i = 0; $i < $bytes; $i++) {
$len = ($len << 8) | ord($der[$i + 2]);
}
}
$contents = substr($der, 2 + $bytes, $len);
$der = substr($der,2 + $bytes + $len);
休憩。
デフォルト:
falseを返します。
休憩。
}
}
return false;
}

/**
* エンコードされた署名データから署名アルゴリズム oid を取得します。
* 証明書形式の復号化された署名データを期待します。
* この ASN1 データには、次の 構造が含まれている必要があります:
* SEQUENCE * SEQUENCE
* OID (署名アルゴリズム)
* NULL * OCTET STR ING(署名ハッシュ)
* @return bool false(失敗時)
* @return string oid
 */
function getSignatureAlgorithmOid($der=null) {
// これが必要なデルであることを検証します...
if (!is_string($der) or strlen($der) < 5) { falseを返します。 }
$bit_seq1 = 0;
$bit_seq2 = 2;
$bit_oid = 4;
if (ord($der[$bit_seq1]) !== 0x30) {
die('無効な DER が getSignatureAlgorithmOid() に渡されました');
        }
if (ord($der[$bit_seq2]) !== 0x30) {
die('無効な DER が getSignatureAlgorithmOid() に渡されました');
}
if (ord($der[$bit_oid]) !== 0x06) {
die('無効なDERがgetSignatureAlgorithmOidに渡されました');
}
// 不要なものを取り除き、oid を取得します
$der = substr($der,$bit_oid);
// oid を取得します
$len = ord($der[1]);
$バイト = 0;
if ($len & 0x80) {
$bytes = $len & 0x0f;
$len = 0;
for ($i = 0; $i < $bytes; $i++) {
$len = ($len << 8) | ord($der[$i + 2]);
}
}
$oid_data = substr($der, 2 + $bytes, $len);
// OID を解凍します
$oid = floor(ord($oid_data[0]) / 40);
$oid .= '.' 。 ord($oid_data[0]) % 40;
$value = 0;
$i = 1;
while ($i < strlen($oid_data)) {
$value = $value << 7;
$value = $value | (ord($oid_data[$i]) & 0x7f);
if (!(ord($oid_data[$i]) & 0x80)) {
$oid .= '.' 。 $値;
$value = 0;
}
$i++;
}
return $oid;
}

/**
* エンコードされた署名データから署名ハッシュを取得します。
* 証明書形式の復号化された署名データを期待します。
* この ASN1 データには、次の 構造が含まれている必要があります:
* SEQUENCE * SEQUENCE
* OID (署名アルゴリズム)
* NULL * OCTET STR ING(署名ハッシュ)
* @return bool false(失敗時)
* @return 文字列ハッシュ
 */
function getSignatureHash($der=null) {
// これが必要なデータであることを検証します...
if (!is_string($der) or strlen($der) < 5) { falseを返します。 }
if (ord($der[0]) !== 0x30) {
die('getSignatureHash() に無効な DER が渡されました');
}
// コンテナシーケンスを削除します
$der = substr($der,2);
if (ord($der[0]) !== 0x30) {
die('getSignatureHash() に無効な DER が渡されました');
}
    // 最初のシーケンスの長さを取得して、それを削除できるようにします。
$len = ord($der[1]);
$バイト = 0;
if ($len & 0x80) {
$bytes = $len & 0x0f;
$len = 0;
for ($i = 0; $i < $bytes; $i++) {
$len = ($len << 8) | ord($der[$i + 2]);
}
}
$der = substr($der, 2 + $bytes + $len);
// これで、オクテット文字列が必要になります
if (ord($der[0]) !== 0x04) {
die('無効な DER が getSignatureHash() に渡されました');
}
$len = ord($der[1]);
$バイト = 0;
if ($len & 0x80) {
$bytes = $len & 0x0f;
$len = 0;
for ($i = 0; $i < $bytes; $i++) {
$len = ($len << 8) | ord($der[$i + 2]);
}
}
return bin2hex(substr($der, 2 + $bytes, $len));
}

/**
* ある証明書が別の証明書の署名に使用されたかどうかを確認します
* 複数の CA 証明書、一部の証明書では肯定的な結果が得られることに注意してください
* 有効期限のみを変更した後、署名証明書を再発行します。
* @param 文字列 $cert - PEM エンコードされた 証明書
* @param 文字列 $caCert - $cert に署名された可能性がある PEM エンコードされた 証明書
* @return bool
 */
function isCertSigner($certPem=null,$caCertPem=null) {
if (!function_exists('openssl_pkey_get_public')) {
die('openssl_pkey_get_public() 関数が必要です。 ');
}
if (!function_exists('openssl_public_decrypt')) {
die('openssl_public_decrypt() 関数が必要です。');
}
if (!function_exists('hash')) {
die('php hash() 関数が必要です。');
}
if (empty($certPem) or empty($caCertPem)) { return false; }
// 抽出する署名にフィードするために証明書を der に変換します。
$certDer = $this->pemToDer($certPem);
if (!is_string($certDer)) { die('invalid certPem'); }
// エンコードされた証明書から暗号化された署名を取得します。
$encryptedSig = $this->extractSignature($certDer);
if (!is_string($encryptedSig)) {
die('certPem から暗号化された署名を抽出できませんでした。');
}
// ca 証明書から公開鍵を抽出します。これは、
// 証明書内の署名の暗号化に使用されたものです。
$pubKey = openssl_pkey_get_public($caCertPem);
if ($pubKey === false) {
die('CA証明書からの公開キーの抽出に失敗しました');
}
// CA の公開
// キーを使用して暗号化された署名の復号化を試み、復号化された署名を $decryptedSig で返します。  
// 復号化できない場合は、この CA は確かに署名に使用されていません...
$rc = openssl_public_decrypt($encryptedSig,$decryptedSig,$pubKey);
if ($rc === false) { return false; }
// これで、復号化された署名が得られました。これは、よりエンコードされたものです
// asn1 データ には 署名 アルゴリズム と 署名 ハッシュが含まれています。
// 次に、発行者によって元々ハッシュされたものが必要になります。これは、
// 発行者と
// 署名情報のない、元の DER エンコードされた証明書です。
$origCert = $this->stripSignerAsn($certDer);
if ($origCert === false) {
die('未署名の証明書の抽出に失敗しました。');
}
    // 署名ハッシュ アルゴリズムの oid を取得します。これは、元の証明書の独自のハッシュを生成するために必要です
//  このハッシュは
// 発行者のハッシュと比較されるものです。
$oid = $this->getSignatureAlgorithmOid($decryptedSig);
if ($oid === false) {
die('署名アルゴリズムの決定に失敗しました。');
}
switch($oid) {
case '1.2.840.113549.2.2': $algo = 'md2';    壊す;
case '1.2.840.113549.2.4': $algo = 'md4';    壊す;
case '1.2.840.113549.2.5': $algo = 'md5';    壊す;
case '1.3.14.3.2.18': $algo = 'sha';    壊す;
case '1.3.14.3.2.26': $algo = 'sha1';   壊す;
case '2.16.840.1.101.3.4.2.1': $algo = 'sha256'; 壊す;
case '2.16.840.1.101.3.4.2.2': $algo = 'sha384'; 壊す;
case '2.16.840.1.101.3.4.2.3': $algo = 'sha512'; 壊す;
デフォルト:
die('不明な署名ハッシュアルゴリズム oid: ' . $oid);
休憩;
}
// 復号された署名から発行者が生成したハッシュを取得します。
$decryptedHash = $this->getSignatureHash($decryptedSig);
// OK、元の署名されていない証明書を同じアルゴリズムでハッシュします
// そしてそれが $decryptedHash と一致すれば、勝者が決まります。
$certHash = ハッシュ($algo,$origCert);
return ($decryptedHash === $certHash);
}

/**
* pem エンコードされた証明書を DER エンコーディングに変換します
* @return string $derEncoded 成功した場合
* @return bool false 失敗した場合
 */
function pemToDer($pem=null) {
if (!is_string($pem)) { return false; }
$cert_split = preg_split('/(-----((BEGIN)|(END)) CERTIFICATE-----)/',$pem);
if (!isset($cert_split[1])) { return false; }
return base64_decode($cert_split[1]);
}

/**
* 発行者と署名のセクションを削除した証明書を取得します。
* @param string $der - der エンコードされた証明書
* @return string $der 成功の場合
* @return bool false 失敗の場合
 */
function stripSignerAsn($der=null) {
if (!is_string($der) or strlen($der) < 8) { return false; }
$bit = 4;
$len = ord($der[($bit + 1)]);
$バイト = 0;
if ($len & 0x80) {
$bytes = $len & 0x0f;
        $len = 0;
for($i = 0; $i < $bytes; $i++) {
$len = ($len << 8) | ord($der[$bit + $i + 2]);
}
}
return substr($der,4,$len + 4);
}
}
/**
* HTML フォームはここから始まります...
 */

$this->answer = 「発行者とサブジェクトの PEM エンコードされた証明書を入力してください」
 」をクリックし、[送信]をクリックします。  「
」を含む証明書全体を含めます。 「BEGIN CERTIFICATE 行と END CERTIFICATE 行。」;
/*
if (isset($_POST['subjectPem']) and isset($_POST['issuerPem'])) {
if (strlen($_POST['subjectPem']) >0 and strlen($_POST ['issuerPem']) > 0) {
$rc = isCertSigner($_POST['subjectPem'],$_POST['issuerPem']);
if ($rc === true) {
$answer = '発行者の証明書は対象の証明書に署名しました。';
} else {
$answer = '発行者の証明書は対象の証明書に署名しませんでした。';


}
*/

?>

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。