【PHP8.x】sodium_crypto_sign_verify_detached関数の使い方

作成日: 更新日:

sodium_crypto_sign_verify_detached関数は、デジタル署名の検証を実行する関数です。この関数は、Libsodiumという強力な暗号ライブラリの機能を提供し、PHPアプリケーションにおいてデータの完全性と認証を確保するために利用されます。

デジタル署名とは、あるデータ(メッセージ)が特定の送信者によって作成され、かつ途中で改ざんされていないことを証明する技術です。sodium_crypto_sign_verify_detached関数は、このデジタル署名が「正しい」ものであるかどうかを確認する役割を担います。具体的には、署名された元のメッセージ、そのメッセージに付随する署名データ、そして署名者の公開鍵という三つの情報を受け取ります。

これらの情報を用いて、署名が正当な公開鍵によって作成されたものであり、かつメッセージが署名後に一切改ざんされていないことを暗号学的に検証します。検証が成功した場合はtrueを、失敗した場合はfalseを返します。この機能は、ソフトウェアのアップデートファイルの検証、安全な通信におけるメッセージの認証、データの整合性チェックなど、セキュリティが求められる様々な場面で極めて重要です。システムエンジニアを目指す方にとって、データの信頼性を保証する上で不可欠な技術要素の一つと言えます。

基本的な使い方

構文(syntax)

1<?php
2
3// 検証する署名データ (string型, SODIUM_CRYPTO_SIGN_BYTESの長さ)
4// 例: sodium_crypto_sign_detached() によって生成されたバイナリ署名
5$signature_data = random_bytes(SODIUM_CRYPTO_SIGN_BYTES);
6
7// 署名が作成された際の元のメッセージデータ (string型)
8$original_message = 'This is the message that was signed.';
9
10// 署名者の公開鍵データ (string型, SODIUM_CRYPTO_SIGN_PUBLICKEYBYTESの長さ)
11// 例: sodium_crypto_sign_publickey() から取得されたバイナリ公開鍵
12$signer_public_key = random_bytes(SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES);
13
14// sodium_crypto_sign_verify_detached 関数の呼び出し
15// 署名が有効な場合は bool(true) を、無効な場合は bool(false) を返します。
16$is_signature_valid = sodium_crypto_sign_verify_detached(
17    $signature_data,
18    $original_message,
19    $signer_public_key
20);
21
22?>

引数(parameters)

string $signature, string $message, string $public_key

  • string $signature: 検証する署名。
  • string $message: 署名された元のメッセージ。
  • string $public_key: 署名の検証に使用する公開鍵。

戻り値(return)

bool

署名が有効であれば true を、無効であれば false を返します。

サンプルコード

PHPsodium crypto_sign_verify_detachedで署名を検証する

1<?php
2
3declare(strict_types=1);
4
5/**
6 * Libsodium拡張機能を使用して、メッセージの署名を検証するサンプルコード。
7 *
8 * この関数は、あらかじめ生成された署名、元のメッセージ、および公開鍵を使用して、
9 * 署名が有効であるかを検証します。
10 *
11 * システムエンジニアを目指す初心者の方へ:
12 * セキュリティを向上させるため、データの送信元が本物であること(認証)や、
13 * データが改ざんされていないこと(完全性)を確認する際に、デジタル署名が役立ちます。
14 * sodium_crypto_sign_verify_detached は、メッセージと署名が別々に提供される「分離型署名」の検証に使われます。
15 */
16function verifyDetachedSignatureExample(): void
17{
18    // 1. Libsodium拡張機能が利用可能か確認
19    if (!extension_loaded('sodium')) {
20        echo "エラー: Libsodium拡張機能がインストールされていません。\n";
21        return;
22    }
23
24    echo "--- sodium_crypto_sign_verify_detached 使用例 ---\n\n";
25
26    // 2. 署名用の鍵ペアを生成
27    // 実際のアプリケーションでは、鍵ペアは安全な方法で事前に生成・保存されます。
28    $keypair = sodium_crypto_sign_keypair_gen();
29    $secretKey = sodium_crypto_sign_secretkey($keypair);
30    $publicKey = sodium_crypto_sign_publickey($keypair);
31
32    echo "鍵ペアが生成されました。\n";
33    echo "公開鍵: " . bin2hex($publicKey) . "\n";
34    echo "秘密鍵: " . bin2hex($secretKey) . "\n\n";
35
36    // 3. 署名するメッセージを定義
37    $message = "これは署名されるべき重要なメッセージです。";
38    echo "元のメッセージ: " . $message . "\n";
39
40    // 4. メッセージを秘密鍵で署名し、分離型署名(detached signature)を生成
41    // この署名が、検証の対象となります。
42    $signature = sodium_crypto_sign_detached($message, $secretKey);
43    echo "生成された署名: " . bin2hex($signature) . "\n\n";
44
45    // 5. 署名を検証(正しいメッセージと鍵で検証)
46    echo "--- 署名の検証を開始 --- \n";
47    $isValid = sodium_crypto_sign_verify_detached($signature, $message, $publicKey);
48
49    if ($isValid) {
50        echo "[成功] 署名は有効です。メッセージは改ざんされておらず、信頼できる送信元からのものです。\n";
51    } else {
52        echo "[失敗] 署名は無効です。メッセージが改ざんされたか、署名が不正です。\n";
53    }
54
55    echo "\n--- 不正なシナリオの検証 --- \n";
56
57    // 6. メッセージが改ざんされた場合の検証
58    $modifiedMessage = "これは改ざんされたメッセージです。";
59    echo "改ざんされたメッセージ: " . $modifiedMessage . "\n";
60
61    $isValidModified = sodium_crypto_sign_verify_detached($signature, $modifiedMessage, $publicKey);
62    if ($isValidModified) {
63        echo "[失敗?] 署名は有効です (これは発生すべきではありません)。\n";
64    } else {
65        echo "[成功] 署名は無効です。メッセージが改ざんされたため、正しく検出されました。\n";
66    }
67
68    // 7. 別の(間違った)公開鍵で検証した場合
69    echo "\n--- 別の公開鍵での検証 --- \n";
70    // 新しい鍵ペアを生成し、その公開鍵を使ってみる
71    $otherKeypair = sodium_crypto_sign_keypair_gen();
72    $otherPublicKey = sodium_crypto_sign_publickey($otherKeypair);
73    echo "別の公開鍵: " . bin2hex($otherPublicKey) . "\n";
74
75    $isValidOtherKey = sodium_crypto_sign_verify_detached($signature, $message, $otherPublicKey);
76    if ($isValidOtherKey) {
77        echo "[失敗?] 署名は有効です (これは発生すべきではありません)。\n";
78    } else {
79        echo "[成功] 署名は無効です。別の公開鍵では、正しく検出されました。\n";
80    }
81
82    echo "\n--- sodium_crypto_sign_verify_detached 使用例終了 ---\n";
83}
84
85// サンプル関数の実行
86verifyDetachedSignatureExample();
87

PHP 8のsodium_crypto_sign_verify_detached関数は、デジタル署名が有効であるかを検証するために使われます。これは、データの改ざん防止(完全性)や、送信元の確認(認証)といったセキュリティの確保に役立ちます。特に、メッセージと署名が別々に提供される「分離型署名」の検証に特化した関数です。

引数には、検証対象の$signature(デジタル署名)、$message(署名された元のメッセージ)、$public_key(署名作成者の公開鍵)の3つを指定します。これらの情報から、署名が正規のものであるかを確認します。

戻り値はブール値(bool)です。署名が有効であればtrue、無効であればfalseを返し、メッセージの信頼性を判断できます。

サンプルコードでは、まず鍵ペアを生成し、メッセージを秘密鍵で署名して分離型署名を作成しています。その後、本関数を使って正しい公開鍵とメッセージで署名を検証し、trueが返されることを示します。さらに、メッセージを改ざんした場合や、異なる公開鍵で検証を試みた際には、関数がfalseを返し、不正が正しく検出される様子も確認できます。これにより、デジタル署名がデータの信頼性をどのように保証するかが理解できます。

sodium_crypto_sign_verify_detachedを使用する際は、まずPHP環境にLibsodium拡張機能がインストールされているか確認が必要です。鍵ペア、特に秘密鍵は厳重に管理し、本番環境では安全な方法で事前に生成・保存されたものを使用してください。この関数の引数は、署名、元のメッセージ、公開鍵の順序で指定します。誤った順序で渡すと検証は失敗しますので注意してください。戻り値は真偽値(true/false)のため、検証結果を適切にハンドリングすることが重要です。デジタル署名は、メッセージの完全性(改ざんされていないこと)と認証(送信元が本物であること)を保証するセキュリティ機能として活用されます。

【PHP8.x】sodium_crypto_sign_verify_detached関数の使い方 | いっしー@Webエンジニア