ユーザ認証とセッション

Copyright(C) 25Feb2014 coskx TNCT



sha256を用いたユーザ認証とセッション生成の例1


「sha256.js」(http://sourceforge.net/projects/jssha/files/)を同じディレクトリに置いておくこと

sha256,セッションの利用 PHPサンプル
<?php
function makeA1($userID,$pass,$realm) //sha256でダイジェストする
{
    return hash('sha256', $userID . ":" . $realm . ":" . $pass);
}

function getPASSWD_A1($userID)
{
    global $mydatabase;
    if ($userID==$mydatabase['userID']) return $mydatabase['A1'];
    else return FALSE;
}

//////////   ここからphpメイン   ///////////////////////

$userID="TokyoTaro";
$password="himitsudesu";
$realm = 'Restricted area';
$A1=makeA1($userID,$password,$realm);
$mydatabase['userID']=$userID;
$mydatabase['A1']=$A1;
//本当は$A1はあらかじめ求められて,ファイルなどに保存されている。

$pagetoshow=0; //0:loginページを表示,1:メニューメージ(セッション開始),999:logout作業 2以降は必要に応じて定義
$message="";

if (isset($_POST['login']) && isset($_POST['userID']) && isset($_POST['userPASS']) && isset($_POST['realm']) && isset($_POST['nonce'])) { //ログインボタンが押された
    //$_POST['userPASS']はA1ダイジェストされた文字列が来る
    $message="login受け付けました。 ";
    $strcheck=TRUE;
    if (!preg_match('/\A([0-9A-Fa-f])+\Z/',$_POST['userPASS'])) $strcheck=FALSE;
    if (!preg_match('/\A([0-9A-Za-z_ ])+\Z/',$_POST['realm'])) $strcheck=FALSE;
    if (!preg_match('/\A([0-9A-Fa-f])+\Z/',$_POST['nonce'])) $strcheck=FALSE;
    $userID = htmlspecialchars($_POST['userID'], ENT_QUOTES);
    if (!preg_match('/\A([0-9A-Za-z_ ])+\Z/',$userID)) $strcheck=FALSE;
    if ($strcheck===TRUE) {
        $A1=getPASSWD_A1($userID);
        if ($A1!==FALSE) {
            $A2= hash('sha256', $_POST['nonce'] . ":" . $A1);
            if ($_POST['userPASS']===$A2) { //認証された
               
                $message .= $userID . "さん 認証に成功しました。";
                $pagetoshow = 1;
                session_start();
                //セッションを作成する
                $_SESSION["userID"] = $userID;      //サーバに値を保存
                $date = date('c');
                $message .= 'セッションをオープンしました。';
            } else {
                $message .= $userID . "さん 認証に失敗しました。もう一度やり直してください";
            }
        } else {
            $message .= $userID . "さんは未登録のユーザです";
        }
    } else {
        $message .= "認証できません";
    }
} else if (isset($_POST['menupage']) && isset($_COOKIE[session_name()]) ) { //選択ボタンが押された
    session_start();
    $userID = $_SESSION["userID"];
    $pagetoshow=1;
} else if (isset($_POST['work1']) && isset($_COOKIE[session_name()]) ) { //作業1ボタンが押された
    session_start();
    $userID = $_SESSION["userID"];
    $pagetoshow=101;
} else if (isset($_POST['work2']) && isset($_COOKIE[session_name()]) ) { //作業2ボタンが押された
    session_start();
    $userID = $_SESSION["userID"];
    $pagetoshow=102;
} else if (isset($_POST['work3']) && isset($_COOKIE[session_name()]) ) { //作業3ボタンが押された
    session_start();
    $userID = $_SESSION["userID"];
    $pagetoshow=103;
} else if (isset($_POST['logout'])) { //ログアウトボタンが押された
    session_start();
    //既存のセッションを使用可能にする
    $pagetoshow=999;
    if (isset($_COOKIE[session_name()])) {
        setcookie(session_name(), '', time() - 1800, '/');
    }                                       // cookieの削除
    session_destroy();                      //セッションの終了
    $message .= 'ログアウトしました。';
} else {
    //初回は必ずここを通過する
    $pagetoshow=0;
    $message="ユーザの認証をします";
}

?>

<html>
<head>
    <script src="./sha256.js"></script>
    <script type="text/javascript">
    <!--
        function SubmitIdPass() {
            var tmp1=document.frm_login.userID.value
                     +":"+document.frm_login.realm.value
                     +":"+document.frm_login.userPASS.value;
            var shaObj1=new jsSHA(tmp1, "ASCII");
            var sha256digest1 = shaObj1.getHash("SHA-256", "HEX");
            var tmp2=document.frm_login.nonce.value+":"+sha256digest1;
            var shaObj2=new jsSHA(tmp2, "ASCII");
            var sha256digest2 = shaObj2.getHash("SHA-256", "HEX");
            document.frm_login.userPASS.value=sha256digest2;
            document.frm_login.submit();
        }
    // -->
    </script>
</head>
<body>
<h1>sha256 sessionテスト</h1>

<?php if ($pagetoshow==0) { ?>
    <?php print $message; ?>
    <p>
    あなたのユーザIDとパスワードを入力して,ログインボタンを押してください。<br><br>
    </p>
    <form name="frm_login" method="post">
    ユーザID  <input type="text" name="userID"><br>
    パスワード <input type="password" name="userPASS"><br>
    <input type="hidden" name="realm" value="<?php echo $realm; ?>">
    <input type="hidden" name="nonce" value="<?php echo uniqid(); ?>">
    <input type="hidden" name="login" value="">
                <input type="button" onclick="SubmitIdPass();" name="" value="ログイン" >
    </form>
<?php } else if ($pagetoshow==1) { ?>
    <?php
    print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
    print $message;
    ?>
    <p>
    作業を選択してください。<br>
    <form method="post">
    <input type="submit" name="work1" value="作業1"> 作業1を行います。<br>
    </form>
    <form method="post">
    <input type="submit" name="work2" value="作業2"> 作業2を行います。<br>
    </form>
    <form method="post">
    <input type="submit" name="work3" value="作業3"> 作業3を行います。<br>
    </form>
    <form method="post">
    <input type="submit" name="logout" value="ログアウト"><br>
    </form>
<?php } else if ($pagetoshow==101) { ?>
    <?php
    print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
    print $message;
    ?>
    <p>作業1<br> :<br> :<br></p>
    <form method="post">
    <input type="submit" name="menupage" value="作業選択">
    </form>
    <form method="post">
    <input type="submit" name="logout" value="ログアウト"><br>
    </form>
<?php } else if ($pagetoshow==102) { ?>
    <?php
    print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
    print $message;
    ?>
    <p>作業2<br> :<br> :<br></p>
    <form method="post">
    <input type="submit" name="menupage" value="作業選択">
    </form>
    <form method="post">
    <input type="submit" name="logout" value="ログアウト"><br>
    </form>
<?php } else if ($pagetoshow==103) { ?>
    <?php
    print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
    print $message;
    ?>
    <p>作業3<br> :<br> :<br></p>
    <form method="post">
    <input type="submit" name="menupage" value="作業選択">
    </form>
    <form method="post">
    <input type="submit" name="logout" value="ログアウト"><br>
    </form>
<?php } else if ($pagetoshow==999) { ?>
    <p>
     ログアウトしました。<br>
     </p>
<?php } ?>

</body>
</html>



sha256を用いたユーザ認証とセッション生成の例2


こちらの例ではユーザ認証のためのセッションを生成している。

sha256を用いたユーザ認証とセッション生成の例
<?php
function makeA1($userID,$pass,$realm) //sha256でダイジェストする
{
    return hash('sha256', $userID . ":" . $realm . ":" . $pass);
}

function getPASSWD_A1($userID)
{
    global $mydatabase;
    if ($userID==$mydatabase['userID']) return $mydatabase['A1'];
    else return FALSE;
}

//////////   ここからphpメイン   ///////////////////////

$userID="TokyoTaro";
$password="himitsudesu";
$realm = 'Restricted area';
$A1=makeA1($userID,$password,$realm);
$mydatabase['userID']=$userID;
$mydatabase['A1']=$A1;
//本当は$A1はあらかじめ求められて,ファイルなどに保存されている。

$pagetoshow=0; //0:loginページを表示,1:メニューメージ(セッション開始),999:logout作業 2以降は必要に応じて定義
$message="";

session_save_path("./");/*セッション保存用のファイルのパスの設定 本当はもっと安全なところに設定する*/
if (isset($_POST['login']) && isset($_POST['userID']) && isset($_POST['userPASS']) && isset($_POST['realm']) && isset($_POST['nonce'])) { //ログインボタンが押された
    //$_POST['userPASS']はA1ダイジェストされた文字列が来る
    $message .= "login要求受け付けました。 ";
    $strcheck=TRUE;
    session_start();
    if (isset($_SESSION["mynonce"])) {
        $mynonce=$_SESSION["mynonce"];
        session_destroy();                      //ログイン用セッションの終了
    } else {
        $strcheck=FALSE;
        $message .= "認証できません。(セッションが継続していません)";
        $pagetoshow = -1;
    }
    if (!preg_match('/\A([0-9A-Fa-f])+\Z/',$_POST['userPASS'])) $strcheck=FALSE;
    if (!preg_match('/\A([0-9A-Za-z_ ])+\Z/',$_POST['realm'])) $strcheck=FALSE;
    if (!preg_match('/\A([0-9A-Fa-f])+\Z/',$_POST['nonce'])) $strcheck=FALSE;
    $userID = htmlspecialchars($_POST['userID'], ENT_QUOTES);
    if (!preg_match('/\A([0-9A-Za-z_ ])+\Z/',$userID)) $strcheck=FALSE;
    if ($strcheck===TRUE) {
        $A1=getPASSWD_A1($userID);
        if ($A1!==FALSE) {
            $A2= hash('sha256', $mynonce . ":" . $A1); //$message .= $A2 . " ";
            //$A2= hash('sha256', $_POST['nonce'] . ":" . $A1); $message .= $A2 . " ";
            if ($_POST['userPASS']===$A2) { //認証された
               
                $message .= $userID . "さん 認証に成功しました。";
                $pagetoshow = 1;
                $_SESSION = array();
                session_id(hash('sha256',uniqid(rand(), 1)));    // セッションID更新
                session_start();
                //セッションを作成する
                $_SESSION["userID"] = $userID;      //サーバに値を保存
                $date = date('c');
                $message .= 'セッションをオープンしました。';
            } else {
                $message .= $userID . "さん 認証に失敗しました。";
                $pagetoshow = -1;
            }
        } else {
            $message .= $userID . "さんは未登録のユーザです";
            $pagetoshow = -1;
        }
    } else {
        $message .= "認証できません。(リクエスト異常)";
        $pagetoshow = -1;
    }
} else if (isset($_POST['menupage']) && isset($_COOKIE[session_name()]) ) { //選択ボタンが押された
    session_start();
    if (isset($_SESSION["userID"])) {
        $userID = $_SESSION["userID"];
        $pagetoshow=1;
    } else {
        $pagetoshow=-1;
        $message .= "継続できません。(セッション異常)";
    }
} else if (isset($_POST['work1']) && isset($_COOKIE[session_name()]) ) { //作業1ボタンが押された
    session_start();
    if (isset($_SESSION["userID"])) {
        $userID = $_SESSION["userID"];
        $pagetoshow=101;
    } else {
        $pagetoshow=-1;
        $message .= "継続できません。(セッション異常)";
    }
} else if (isset($_POST['work2']) && isset($_COOKIE[session_name()]) ) { //作業2ボタンが押された
    session_start();
    if (isset($_SESSION["userID"])) {
        $userID = $_SESSION["userID"];
        $pagetoshow=201;
    } else {
        $pagetoshow=-1;
        $message .= "継続できません。(セッション異常)";
    }
} else if (isset($_POST['work3']) && isset($_COOKIE[session_name()]) ) { //作業3ボタンが押された
    session_start();
    if (isset($_SESSION["userID"])) {
        $userID = $_SESSION["userID"];
        $pagetoshow=301;
    } else {
        $pagetoshow=-1;
        $message .= "継続できません。(セッション異常)";
    }
} else if (isset($_POST['logout'])) { //ログアウトボタンが押された
    session_start();
    //既存のセッションを使用可能にする
    $pagetoshow=999;
    if (isset($_COOKIE[session_name()])) {
        setcookie(session_name(), '', time() - 1800, '/');
    }                                       // cookieの削除
    session_destroy();                      //セッションの終了
    $message .= 'ログアウトしました。';
} else {
    //初回は必ずここを通過する
    $pagetoshow=0;
    $message="ユーザの認証をします。";
    session_start();
    //認証用セッションを作成する
    $nonce=MD5(uniqid(rand(), 1));
    $_SESSION["mynonce"] = $nonce;      //サーバに値を保存
    //$message .= $nonce;
}

?>

<html>
<head>
    <script src="./sha256.js"></script>
    <script type="text/javascript">
    <!--
        function SubmitIdPass() {
            var tmp1=document.frm_login.userID.value
                    +":"+document.frm_login.realm.value
                    +":"+document.frm_login.userPASS.value;
            var shaObj1=new jsSHA(tmp1, "ASCII");
            var sha256digest1 = shaObj1.getHash("SHA-256", "HEX");
            var tmp2=document.frm_login.nonce.value+":"+sha256digest1;
            var shaObj2=new jsSHA(tmp2, "ASCII");
            var sha256digest2 = shaObj2.getHash("SHA-256", "HEX");
            document.frm_login.userPASS.value=sha256digest2;
            document.frm_login.submit();
        }
    // -->
    </script>
</head>
<body>
<h1>sha256 sessionテスト</h1>

<?php if ($pagetoshow==-1) { ?>
    <?php print $message ."<br><br>"; ?>
    <form method="post">
    <input type="submit" name="again" value="やり直し"><br>
    </form>
<?php } else if ($pagetoshow==0) { ?>
    <?php print $message; ?>
    <p>
    あなたのユーザIDとパスワードを入力して,ログインボタンを押してください。<br><br>
    </p>
    <form name="frm_login" method="post">
    ユーザID  <input type="text" name="userID"><br>
    パスワード <input type="password" name="userPASS"><br>
    <input type="hidden" name="realm" value="<?php echo $realm; ?>">
    <input type="hidden" name="nonce" value="<?php echo $nonce; ?>">
    <input type="hidden" name="login" value="">
                <input type="button" onclick="SubmitIdPass();" name="" value="ログイン" >
    </form>
<?php } else if ($pagetoshow==1) { ?>
    <?php
    print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
    print $message;
    ?>
    <p>
    作業を選択してください。<br>
    <form method="post">
    <input type="submit" name="work1" value="作業1"> 作業1を行います。<br>
    </form>
    <form method="post">
    <input type="submit" name="work2" value="作業2"> 作業2を行います。<br>
    </form>
    <form method="post">
    <input type="submit" name="work3" value="作業3"> 作業3を行います。<br>
    </form>
    <form method="post">
    <input type="submit" name="logout" value="ログアウト"><br>
    </form>
<?php } else if ($pagetoshow==101) { ?>
    <?php
    print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
    print $message;
    ?>
    <p>作業1<br> :<br> :<br></p>
    <form method="post">
    <input type="submit" name="menupage" value="作業選択">
    </form>
    <form method="post">
    <input type="submit" name="logout" value="ログアウト"><br>
    </form>
<?php } else if ($pagetoshow==201) { ?>
    <?php
    print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
    print $message;
    ?>
    <p>作業2<br> :<br> :<br></p>
    <form method="post">
    <input type="submit" name="menupage" value="作業選択">
    </form>
    <form method="post">
    <input type="submit" name="logout" value="ログアウト"><br>
    </form>
<?php } else if ($pagetoshow==301) { ?>
    <?php
    print "こんにちは,<b>" . $userID . "</b>さん。<br>\n";
    print $message;
    ?>
    <p>作業3<br> :<br> :<br></p>
    <form method="post">
    <input type="submit" name="menupage" value="作業選択">
    </form>
    <form method="post">
    <input type="submit" name="logout" value="ログアウト"><br>
    </form>
<?php } else if ($pagetoshow==999) { ?>
    <p>
     ログアウトしました。<br>
     </p>
<?php } ?>

</body>
</html>