Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】OPENSSL_ALGO_SHA384定数の使い方

OPENSSL_ALGO_SHA384定数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

OPENSSL_ALGO_SHA384定数は、PHPのOpenSSL拡張機能において、セキュアハッシュアルゴリズムの一つであるSHA-384を指定するために使用される定数です。

この定数が表すSHA-384(Secure Hash Algorithm 384)は、米国国家安全保障局(NSA)によって設計されたSHA-2ファミリーに属する暗号学的ハッシュ関数です。このアルゴリズムは、あらゆる長さの入力データから、常に固定された長さ(384ビット、すなわち48バイト)のハッシュ値、またはメッセージダイジェストを生成します。SHA-384の大きな特徴は、このハッシュ値が元のデータの一方向の要約である点にあり、生成されたハッシュ値から元のデータを復元することは極めて困難です。

また、元のデータが少しでも変更されると、生成されるハッシュ値は全く異なるものになるという特性を持っています。この特性により、データの改ざん検出、ファイルやメッセージの完全性チェック、パスワードなどの認証情報の安全な保管、電子署名の生成と検証など、幅広いセキュリティ関連の用途で利用されます。

OPENSSL_ALGO_SHA384定数は、PHPのopenssl_digest()関数など、OpenSSL拡張機能が提供するハッシュ関連の関数と組み合わせて使用されます。これにより、開発者は明示的に処理にSHA-384アルゴリズムを適用するよう指示することができます。この定数を利用することで、コードの可読性が向上し、アルゴリズム名を直接文字列で指定するよりも誤入力のリスクを減らし、システムのセキュリティと信頼性を高める上で重要な役割を果たします。

構文(syntax)

1<?php
2echo OPENSSL_ALGO_SHA384;

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

この定数は、SHA3-384アルゴリズムを表す整数値を返します。この値は、OpenSSL拡張機能でハッシュ関数を指定する際に使用されます。

サンプルコード

PHP OpenSSLでIV長取得とハッシュ生成

1<?php
2
3/**
4 * テキストを暗号化し、そのデータのハッシュを生成する関数。
5 *
6 * この関数は、指定された暗号化アルゴリズムの初期化ベクトル(IV)長を取得し、
7 * ランダムなIVと秘密鍵を使用してデータを暗号化します。
8 * さらに、暗号化されたデータの改ざん検出のために、
9 * OPENSSL_ALGO_SHA384 アルゴリズムでハッシュ(ダイジェスト)を生成します。
10 *
11 * @param string $plaintext 暗号化する元の平文。
12 * @param string $key 暗号化に使用する秘密鍵。この鍵はセキュアに生成・管理される必要があります。
13 * @return array|false 暗号化されたデータ、IV、ハッシュ、および使用された暗号化アルゴリズムの配列を返します。
14 *                     処理が失敗した場合は false を返します。
15 */
16function encryptAndHashData(string $plaintext, string $key): array|false
17{
18    // 使用する暗号化アルゴリズムを定義します。
19    // 'aes-256-cbc' は広く使われている強力なブロック暗号モードの一つです。
20    $cipherAlgo = 'aes-256-cbc';
21
22    // openssl_cipher_iv_length() 関数を使用して、指定されたアルゴリズムに必要な
23    // 初期化ベクトル (IV) の長さをバイト単位で取得します。
24    // IVは、同じ平文と鍵を使用しても異なる暗号文が生成されるようにするために重要です。
25    $ivLength = openssl_cipher_iv_length($cipherAlgo);
26    if ($ivLength === false) {
27        error_log("Error: Failed to get IV length for {$cipherAlgo}.");
28        return false;
29    }
30
31    // openssl_random_pseudo_bytes() を使用して、セキュリティ的に強力なランダムなIVを生成します。
32    // IVは暗号化のたびにユニークであるべきです。
33    $iv = openssl_random_pseudo_bytes($ivLength);
34    if ($iv === false) {
35        error_log('Error: Failed to generate random IV.');
36        return false;
37    }
38
39    // openssl_encrypt() 関数で平文を暗号化します。
40    // OPENSSL_RAW_DATA フラグは、暗号化されたデータを生のバイナリ形式で返します。
41    // この場合、IVは暗号文とは別に管理する必要があります。
42    $encryptedData = openssl_encrypt(
43        $plaintext,
44        $cipherAlgo,
45        $key,
46        OPENSSL_RAW_DATA, // 生のバイナリデータとして出力
47        $iv
48    );
49    if ($encryptedData === false) {
50        error_log('Error: Encryption failed. ' . openssl_error_string());
51        return false;
52    }
53
54    // openssl_digest() 関数と OPENSSL_ALGO_SHA384 定数を使用して、
55    // 暗号化されたデータのハッシュ(ダイジェスト)を生成します。
56    // SHA384は、データの完全性(改ざんされていないこと)を検証するために使用されるハッシュアルゴリズムです。
57    $hash = openssl_digest(
58        $encryptedData,
59        OPENSSL_ALGO_SHA384 // SHA384 アルゴリズムを指定
60    );
61    if ($hash === false) {
62        error_log('Error: Hash generation failed. ' . openssl_error_string());
63        return false;
64    }
65
66    // 暗号化されたデータ、IV、ハッシュ、および使用したアルゴリズムを返します。
67    return [
68        'encryptedData' => $encryptedData,
69        'iv'            => $iv,
70        'hash'          => $hash,
71        'cipherAlgo'    => $cipherAlgo,
72    ];
73}
74
75/**
76 * 暗号化されたデータを復号化し、そのデータのハッシュを検証する関数。
77 *
78 * @param string $encryptedData 暗号化されたバイナリデータ。
79 * @param string $iv 暗号化時に使用された初期化ベクトル (IV)。
80 * @param string $expectedHash 暗号化時に生成された期待されるハッシュ値。
81 * @param string $key 復号化に使用する秘密鍵。
82 * @param string $cipherAlgo 暗号化時に使用されたアルゴリズム。
83 * @return string|false 復号化された平文を返します。ハッシュ検証に失敗した場合や、
84 *                      復号化が失敗した場合は false を返します。
85 */
86function decryptAndVerifyData(
87    string $encryptedData,
88    string $iv,
89    string $expectedHash,
90    string $key,
91    string $cipherAlgo
92): string|false {
93    // 復号化の前に、暗号化されたデータが改ざんされていないかハッシュを再計算して検証します。
94    $recalculatedHash = openssl_digest($encryptedData, OPENSSL_ALGO_SHA384);
95    if ($recalculatedHash === false || $recalculatedHash !== $expectedHash) {
96        error_log('Error: Hash verification failed. Data might be tampered or hash generation failed.');
97        return false;
98    }
99
100    // openssl_decrypt() 関数で暗号化されたデータを復号化します。
101    // ここでも OPENSSL_RAW_DATA フラグを使用して、生のバイナリデータを扱います。
102    $decryptedData = openssl_decrypt(
103        $encryptedData,
104        $cipherAlgo,
105        $key,
106        OPENSSL_RAW_DATA, // 生のバイナリデータとして入力
107        $iv
108    );
109    if ($decryptedData === false) {
110        error_log('Error: Decryption failed. ' . openssl_error_string());
111        return false;
112    }
113
114    return $decryptedData;
115}
116
117// --- 使用例 ---
118$originalText = 'システムエンジニアを目指す初心者向けのPHP OpenSSLサンプルです。';
119
120// AES-256-CBC には256ビット (32バイト) の鍵が必要です。
121// openssl_random_pseudo_bytes() で安全なランダムバイト列を鍵として生成します。
122// 実際のシステムでは、鍵はセキュアな方法で生成、保存、管理されるべきです。
123$encryptionKey = openssl_random_pseudo_bytes(32); 
124
125echo "元のテキスト: " . $originalText . "\n";
126echo "--------------------------------------------------\n";
127
128// データを暗号化し、ハッシュを生成します。
129$processedData = encryptAndHashData($originalText, $encryptionKey);
130
131if ($processedData) {
132    echo "データの暗号化とハッシュ生成に成功しました!\n";
133    echo "  IV (Hex): " . bin2hex($processedData['iv']) . "\n"; // IVはバイナリなので16進数で表示
134    echo "  ハッシュ (SHA384): " . $processedData['hash'] . "\n";
135    // 暗号文もバイナリなので、表示のためにBase64エンコードします。
136    echo "  暗号文 (Base64): " . base64_encode($processedData['encryptedData']) . "\n";
137
138    echo "--------------------------------------------------\n";
139
140    // 暗号化されたデータを復号化し、ハッシュを検証します。
141    $decryptedText = decryptAndVerifyData(
142        $processedData['encryptedData'],
143        $processedData['iv'],
144        $processedData['hash'],
145        $encryptionKey,
146        $processedData['cipherAlgo']
147    );
148
149    if ($decryptedText !== false) {
150        echo "データの復号化とハッシュ検証に成功しました!\n";
151        echo "  復号化されたテキスト: " . $decryptedText . "\n";
152
153        if ($originalText === $decryptedText) {
154            echo "  元のテキストと復号化されたテキストは一致します。データは正しく処理されました。\n";
155        } else {
156            echo "  エラー: 元のテキストと復号化されたテキストが一致しません。\n";
157        }
158    } else {
159        echo "データの復号化またはハッシュ検証に失敗しました。\n";
160    }
161} else {
162    echo "データの暗号化処理に失敗しました。\n";
163}
164
165?>

このPHPサンプルコードは、OpenSSL拡張機能を用いてテキストデータを安全に暗号化し、そのデータの完全性を検証する一連の流れを示しています。OPENSSL_ALGO_SHA384は、データのハッシュ(ダイジェスト)を生成する際に、強力なSHA384アルゴリズムを指定するための整数型の定数です。

encryptAndHashData関数は、引数として受け取った平文と秘密鍵をもとに、データを暗号化してハッシュを生成します。まず、openssl_cipher_iv_length関数で指定された暗号化アルゴリズム(例: 'aes-256-cbc')に必要な初期化ベクトル(IV)の長さを取得します。このIVは、同じ鍵と平文でも異なる暗号文が生成されるようにするために重要です。次に、セキュリティの高いランダムなIVを生成し、openssl_encrypt関数でデータを暗号化します。最後に、暗号化されたデータに対してOPENSSL_ALGO_SHA384定数を用いてopenssl_digest関数でハッシュを生成し、改ざん検知のために利用します。この関数は、暗号化されたデータ、IV、ハッシュなどを配列で返し、失敗した場合はfalseを返します。

decryptAndVerifyData関数は、引数として暗号化されたデータ、IV、期待されるハッシュ、秘密鍵、そして使用されたアルゴリズムを受け取り、データを復号化します。最初に、受け取った暗号化データから再度OPENSSL_ALGO_SHA384を使用してハッシュを計算し、元のハッシュと比較することでデータが改ざんされていないか確認します。検証が成功した場合のみ、openssl_decrypt関数を用いてデータを復号化し、平文を返します。この関数も、ハッシュ検証や復号化が失敗した場合はfalseを返します。

このサンプルコードは、PHPでデータの暗号化と改ざん検知を行う基本的な手順を示します。システムエンジニアを目指す初心者の方は、まず鍵($encryptionKey)の厳重な管理が最も重要であると理解してください。サンプルでは鍵をランダム生成していますが、実際のシステムではセキュアな方法で生成・保存・共有する必要があります。また、初期化ベクトル(IV)は毎回異なる値を生成し、暗号文と一緒に安全に管理・転送する必要がありますが、IV自体を秘密にする必要はありません。ハッシュはデータの改ざんを検出するためのものであり、データ自体を秘密にする暗号化とは目的が異なります。openssl_系の関数は失敗時にfalseを返すため、常にエラーチェックを行い、適切に処理を中断することが安全なコードのために不可欠です。OPENSSL_RAW_DATAを使用する場合、暗号化されたデータやIVはバイナリ形式のため、表示や保存にはBase64エンコードなどが必要となります。

PHP OpenSSL SHA384で署名・検証する

1<?php
2
3/**
4 * OPENSSL_ALGO_SHA384 定数を使用して、データへのデジタル署名の生成と検証を行います。
5 * システムエンジニアを目指す初心者向けに、OpenSSL拡張機能の基本的な利用例を示します。
6 * デジタル署名は、データの完全性と送信者の認証を保証する暗号技術です。
7 *
8 * @param string $dataToSign 署名する対象のデータ
9 * @return bool 署名の生成と検証が成功した場合は true、それ以外は false
10 */
11function generateAndVerifySha384Signature(string $dataToSign): bool
12{
13    // 1. RSA鍵ペアを生成します(秘密鍵と公開鍵)
14    // openssl_pkey_new() は、新しい秘密鍵リソースを生成します。
15    // ここでは、2048ビットのRSA鍵を生成する設定を指定しています。
16    $privateKeyResource = openssl_pkey_new([
17        'private_key_bits' => 2048,           // 鍵のビット数(セキュリティ強度)
18        'private_key_type' => OPENSSL_KEYTYPE_RSA, // RSA鍵タイプ
19    ]);
20
21    if ($privateKeyResource === false) {
22        echo "エラー: 秘密鍵の生成に失敗しました。\n";
23        return false;
24    }
25
26    // 生成された秘密鍵をPEM形式の文字列として取得します。
27    // 秘密鍵は厳重に管理する必要があります。
28    openssl_pkey_export($privateKeyResource, $privateKeyPem);
29
30    // 秘密鍵リソースから公開鍵の詳細を取得し、公開鍵をPEM形式の文字列として取得します。
31    // 公開鍵は署名の検証に使用され、広く配布可能です。
32    $publicKeyDetails = openssl_pkey_get_details($privateKeyResource);
33    $publicKeyPem = $publicKeyDetails['key'];
34
35    echo "--- 鍵ペアが生成されました ---\n";
36    // 秘密鍵は機密情報のため、通常は表示しません。
37    echo "公開鍵:\n" . $publicKeyPem . "\n";
38    echo "署名対象データ: \"" . $dataToSign . "\"\n\n";
39
40    // 2. データを秘密鍵で署名します
41    // openssl_sign() 関数を使用して、指定されたデータと秘密鍵でデジタル署名を生成します。
42    // 第4引数に OPENSSL_ALGO_SHA384 定数を渡すことで、SHA384アルゴリズムでハッシュ化し署名します。
43    $signature = ''; // 署名結果を格納する変数
44    $signed = openssl_sign($dataToSign, $signature, $privateKeyPem, OPENSSL_ALGO_SHA384);
45
46    if ($signed === false) {
47        echo "エラー: 署名の生成に失敗しました。\n";
48        return false;
49    }
50
51    echo "--- 署名処理 ---\n";
52    // 生成された署名はバイナリデータなので、表示のためにBase64エンコードします。
53    echo "署名が生成されました (Base64エンコード): " . base64_encode($signature) . "\n\n";
54
55    // 3. 署名を公開鍵で検証します
56    // openssl_verify() 関数を使用して、署名がオリジナルのデータと公開鍵によって正しく生成されたか確認します。
57    // ここでも OPENSSL_ALGO_SHA384 定数を使用して、署名時と同じアルゴリズムを指定します。
58    $verified = openssl_verify($dataToSign, $signature, $publicKeyPem, OPENSSL_ALGO_SHA384);
59
60    echo "--- 署名検証処理 ---\n";
61    if ($verified === 1) {
62        echo "検証結果: 成功しました。データと署名は有効です。\n";
63        return true;
64    } elseif ($verified === 0) {
65        echo "検証結果: 失敗しました。データまたは署名が改ざんされている可能性があります。\n";
66        return false;
67    } else { // $verified === -1
68        echo "検証結果: エラーが発生しました。\n";
69        // openssl_error_string() を使用して、OpenSSLのエラーキューから詳細なエラーメッセージを取得できます。
70        return false;
71    }
72}
73
74// サンプルコードの実行
75$message = "これはPHPのOpenSSL拡張機能でSHA384アルゴリズムを使って署名・検証するメッセージです。";
76generateAndVerifySha384Signature($message);
77
78?>

このPHPサンプルコードは、OPENSSL_ALGO_SHA384定数を用いて、データのデジタル署名を生成し、その署名を検証する基本的なプロセスをシステムエンジニアを目指す初心者向けに解説しています。デジタル署名とは、データが途中で改ざんされていないこと(データの完全性)と、特定の送信者によって作成されたこと(送信者の認証)を保証する暗号技術です。

コードではまず、openssl_pkey_new関数を使用して、デジタル署名に不可欠なRSA形式の秘密鍵と公開鍵のペアを生成します。次に、openssl_sign関数を用いて、引数として渡された署名対象のデータ $dataToSign を、生成した秘密鍵とOPENSSL_ALGO_SHA384定数で指定されたSHA384ハッシュアルゴリズムを用いて署名します。この定数は、署名プロセスにおいてデータをSHA384でハッシュ化することを指示するものです。

最後に、openssl_verify関数を使用し、生成された署名が、オリジナルのデータ、公開鍵、および署名時と同じOPENSSL_ALGO_SHA384アルゴリズムによって正しく検証されるかを確認します。この検証処理が成功すれば、データは改ざんされておらず、秘密鍵の所有者によって署名されたことが証明されます。関数は、署名の生成と検証が両方成功した場合はtrueを、それ以外の場合はfalseを戻り値として返します。

このサンプルコードはデジタル署名の基本を学ぶ上で参考になりますが、実際のシステム開発ではいくつかの注意が必要です。最も重要なのは秘密鍵の扱いです。秘密鍵は厳重に管理し、本番環境ではファイルや鍵管理サービス(KMS)を通じて安全に利用してください。決してコード内に直接記述したり、安易にログに出力したりしないでください。また、署名時と検証時にOPENSSL_ALGO_SHA384のように同じハッシュアルゴリズムを指定することが必須です。鍵のビット数もセキュリティ強度に関わるため、用途に応じた適切な値を選びましょう。関数が失敗した際には、openssl_error_string()で詳細なエラーメッセージを確認し、堅牢なエラーハンドリングを実装することが大切です。

関連コンテンツ

関連IT用語

関連プログラミング言語