前からゼロ知識証明使いたいと思っておりまして、ちょうど良い資料を見たのでこれを元にゼロ知識証明を使った認証を行いたいと思います。
ゼロ知識証明とは平たく言うとパスワードそのものを送らないでパスワード認証するものです。いくつか資料を見てみましたが、パスワードを暗号化したMD5等を送って比較する等もゼロ知識証明になるようです。
主な認証の流れとしては以下の様になります。
サーバ、クライアントにキーとなる数値T,剰余をとる数値Mを用意します。このT,Mがパスワードの代わりとなります。
次にクライアント側で任意の乱数Rを作成しサーバに送出します。
サーバからは結果として0または1の値Bを取得します。
クライアント側は取得した0/1の値Bを元にYの値を計算しサーバに送出します。
サーバはX,Y,Bの値を計算し両方の値が等しい事を確認します。
数式は面倒なのでソース見てください。
$t=18;
$m=77;
$r = rand(1,10);
/////////////////////
function server1(){
$b = rand(0,1);
echo "server:b=";
echo $b;
echo "\n";
return $b;
}
function client2($t,$m,$b,$r){
$x=($r*$r) % $m;
echo "client:x=";
echo $x;
echo "\n";
$y=(pow($t,$b)*$r) % $m;
echo "client:y=";
echo $y;
echo "\n";
return array($x,$y);
}
function server2($t,$m,$b,$x,$y){
$z = ($t*$t) % $m;
$ans1 = (pow($z,$b)*$x) % $m;
$ans2 = (pow($y,2)) % $m;
echo "server:res=";
echo "{$ans1},{$ans2}\n";
}
$b = server1();
list($x,$y) = client2($t,$m,$b,$r);
server2($t,$m,$b,$x,$y);
XとYの計算は一度にしていますが、まあ同じことです。
これをユーザエージェントに設定してサーバ側で複合します。
デモ
まずこのリンク(https://neon.cx/test/server.php)にアクセスしてください。Not Authentificatedが帰ってくるかと思います。
次に一段PHPをかましたリンク(https://neon.cx/test3/client.php?URL=https://neon.cx/test3/server.php)にアクセスしてください。OK!が帰るはずです。毎回乱数で異なる値が送出されていますので、回線をモニタリングしてもなりすましできません。
割と簡単に書けるので使いみちがあると思います。
元ネタはこれです。詳しく説明してあるのでここで説明するほどでもないでしょう
Copyright(c) 2015-2023 Birdland Ltd. All Rights Reserved.