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

作成日: 更新日:

sodium_crypto_sign_detached関数は、与えられたメッセージに対してデジタル署名を生成する関数です。この関数は、Libsodiumライブラリの機能を提供しており、メッセージの完全性と送信者の認証を保証するために使用されます。

具体的には、指定されたメッセージと秘密鍵を用いて、メッセージの署名を計算します。生成される署名は「detached(分離された)」形式であり、元のメッセージと署名が別々に存在します。この特性により、メッセージ本体を変更することなく、署名のみを別途保管したり、メッセージと一緒に送信したりすることが可能です。

デジタル署名は、メッセージが送信後に改ざんされていないこと(完全性)と、そのメッセージが特定の秘密鍵を持つ正当な送信者によって作成されたこと(認証)を証明するための重要な暗号技術です。この関数で生成された署名は、対応する公開鍵と元のメッセージをsodium_crypto_sign_verify_detached関数で検証することで、その正当性を確認できます。

システムエンジニアを目指す上で、データの信頼性を確保する暗号技術の理解は非常に重要です。この関数は、セキュアな通信やデータ保管システムを構築する際に、メッセージの信頼性を高める基盤として活用されます。

基本的な使い方

構文(syntax)

1<?php
2// PHP 8 & Sodium extension required.
3
4// 署名鍵ペアを生成します (デモンストレーション用)
5$keypair = sodium_crypto_sign_keypair();
6$secret_key = sodium_crypto_sign_secretkey($keypair);
7$public_key = sodium_crypto_sign_publickey($keypair);
8
9// 署名対象のメッセージ
10$message = 'This is the message to be signed.';
11
12// メッセージのデタッチ署名を生成します
13// 署名されたメッセージから署名が分離されています
14$signature = sodium_crypto_sign_detached($message, $secret_key);
15
16// $signature は、メッセージが $secret_key の所有者によって署名されたことを
17// 証明するために使用できるバイナリ文字列を含みます。
18// この署名は、$public_key を使用して検証できます。
19?>

引数(parameters)

string $message, string $secret_key

  • string $message: 署名対象となるメッセージのバイト列
  • string $secret_key: 署名を生成するために使用する秘密鍵のバイト列

戻り値(return)

string

署名に成功した場合は、署名されたバイナリ文字列を返します。署名に失敗した場合は、falseを返します。

サンプルコード

PHP Sodium でデタッチド署名を作成・検証する

1<?php
2
3// PHP の Sodium 拡張がロードされているか確認します。
4// これがないと、このスクリプトは動作しません。
5if (!extension_loaded('sodium')) {
6    die('Sodium 拡張がロードされていません。PHP の設定で有効にしてください。');
7}
8
9/**
10 * sodium_crypto_sign_detached を使用してメッセージに署名し、
11 * sodium_crypto_sign_verify_detached を使用してその署名を検証する方法を示します。
12 *
13 * 「detached」署名とは、署名がメッセージ本体とは別に生成されることを意味します。
14 * これにより、署名とメッセージを個別に送信し、後で検証することができます。
15 */
16function demonstrateSodiumDetachedSignature(): void
17{
18    echo "--- Sodium デタッチド署名 例 ---\n\n";
19
20    // 1. 暗号化用のキーペア(公開鍵と秘密鍵)を生成します。
21    // 秘密鍵は署名生成に、公開鍵は署名検証に使用されます。
22    $keyPair = sodium_crypto_sign_keypair();
23    $secretKey = sodium_crypto_sign_secretkey($keyPair); // 署名を作成するための秘密鍵
24    $publicKey = sodium_crypto_sign_publickey($keyPair); // 署名を検証するための公開鍵
25
26    echo "キーペアを生成しました。\n";
27    // 実際のアプリケーションでは、キーは安全に保管・管理されます。
28    // このデモでは、その場で生成しています。
29
30    // 2. 署名対象のメッセージを定義します。
31    $message = "これは、その出所と完全性を証明するために署名する必要がある秘密のメッセージです。";
32    echo "オリジナルメッセージ: \"" . $message . "\"\n";
33
34    // 3. 秘密鍵を使用してメッセージに署名します。
35    // sodium_crypto_sign_detached は、メッセージ本体ではなく、署名のみを返します。
36    $signature = sodium_crypto_sign_detached($message, $secretKey);
37    echo "生成されたデタッチド署名 (Hex): " . bin2hex($signature) . "\n\n";
38
39    // 4. 公開鍵、オリジナルメッセージ、署名を使用して署名を検証します。
40    // この関数は、署名が与えられたメッセージと公開鍵に対して有効であれば true を、
41    // そうでなければ false を返します。
42    $isValid = sodium_crypto_sign_verify_detached($signature, $message, $publicKey);
43
44    // 5. 検証結果を出力します。
45    if ($isValid) {
46        echo "検証結果: 成功!署名は有効です。メッセージの完全性と送信者の認証が確認されました。\n";
47    } else {
48        echo "検証結果: 失敗!署名は無効です。メッセージが改ざんされたか、送信者が認証されていません。\n";
49    }
50
51    echo "\n--- メッセージの改ざんを試みます ---\n";
52    $tamperedMessage = "これは、その出所と完全性を証明するために署名する必要がある秘密のメッセージです。改ざんされました!";
53    echo "改ざんされたメッセージ: \"" . $tamperedMessage . "\"\n";
54
55    // 改ざんされたメッセージをオリジナルの署名で検証を試みます
56    $isValidTampered = sodium_crypto_sign_verify_detached($signature, $tamperedMessage, $publicKey);
57
58    if ($isValidTampered) {
59        echo "検証結果 (改ざんされたメッセージ): 成功 (これは、署名が安全であれば起こりえないはずです)。\n";
60    } else {
61        echo "検証結果 (改ざんされたメッセージ): 失敗!改ざんされたメッセージを正しく検出しました。\n";
62    }
63
64    echo "\n--- 異なる公開鍵での検証を試みます ---\n";
65    $anotherKeyPair = sodium_crypto_sign_keypair();
66    $anotherPublicKey = sodium_crypto_sign_publickey($anotherKeyPair);
67
68    echo "別の公開鍵を生成しました。\n";
69
70    // オリジナルメッセージを別の公開鍵で検証を試みます
71    $isValidDifferentKey = sodium_crypto_sign_verify_detached($signature, $message, $anotherPublicKey);
72
73    if ($isValidDifferentKey) {
74        echo "検証結果 (異なる鍵): 成功 (これは、署名が安全であれば起こりえないはずです)。\n";
75    } else {
76        echo "検証結果 (異なる鍵): 失敗!異なる鍵であることを正しく検出しました。\n";
77    }
78}
79
80// デモンストレーション関数を実行します
81demonstrateSodiumDetachedSignature();

sodium_crypto_sign_detached関数は、PHPでメッセージのデジタル署名を生成するために使用されます。この関数が生成するのは「デタッチド(detached)」署名と呼ばれる形式で、これは署名が元のメッセージ本体とは独立して生成されることを意味します。これにより、署名されたメッセージと署名データを別々に保管したり、それぞれ異なる経路で送信したりすることが可能になります。

第一引数$messageには署名したいオリジナルの文字列(メッセージ本文)を、第二引数$secret_keyには署名生成用の秘密鍵を指定します。秘密鍵は事前に生成されたキーペアの一部であり、メッセージに署名する権限を持つ者だけが保持すべき情報です。関数は、指定されたメッセージと秘密鍵に基づいて、固有の署名データを文字列として戻り値で返します。

この生成された署名は、対応する公開鍵とオリジナルのメッセージをsodium_crypto_sign_verify_detached関数に渡すことで検証できます。検証に成功すれば、メッセージが途中で改ざんされていないこと、そして指定された秘密鍵の持ち主が署名したことが保証されます。メッセージが少しでも変更されたり、異なる秘密鍵で署名されたりした場合は、検証に失敗し、不正な操作を検出できます。この機能は、データの完全性保証と送信者認証に不可欠であり、利用するにはPHPのSodium拡張が有効になっている必要があります。

sodium_crypto_sign_detached関数は、メッセージの改ざん検知と送信者認証のためのデジタル署名を生成します。利用にはPHPのSodium拡張を有効にする必要があります。detachedは、署名がメッセージ本体とは別に生成されることを意味し、メッセージと署名を独立して扱えます。秘密鍵は署名生成に不可欠であり、絶対に外部に漏洩させず厳重に管理してください。生成された署名は、sodium_crypto_sign_verify_detached関数でオリジナルのメッセージと公開鍵を使って検証するまでがワンセットです。署名データはバイナリ形式のため、表示や保存時にはbin2hexのような適切な変換を検討してください。

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