4

暇な時間があり、楽しみのために新しいプロジェクトを選ぶことを考えています。私は大学生で、毎年オンラインでピッチ コンテストを開催しています。今から約9か月後のこのピッチコンペのプロジェクトを作成したいと考えています。問題は、プロジェクトが非常に高度なセキュリティを必要とし、競争が非常に激しいことです。

私ができるようにする必要があること: 1. HIPAA または ePHI (.pdf|.gif|.jpg|.doc) を保存する 2. 強力なアクセス制御 3. 多数のユーザーとファイル (100 万以上) をサポートする 4. フル監査レポート (ePhi さん、大変ですね) 5. 暗号化

提案された解決策
0) ファイアウォールの背後にある安全な専用サーバーに Web アプリを配置する

1) ファイルを「secure_files/」というファイルに保存し、mod_rewrite を使用してこのディレクトリへのアクセスを制限します。

次の行に何か:

#Removes access to the secure_files folder by users.
RewriteCond %{REQUEST_URI} ^secure_files.*
RewriteRule ^(.*)$ /index.php?/$1 [L]

次に、ユーザーに権限がある場合は、php スクリプトを使用してファイルを開きます。だから私はちょうど使用できますか:

------
-SQL
------

------
- create files table
-----
CREATE TABLE `files` (
id INT NOT NULL AUTO_INCREMENT,
file_name VARCHAR(50) NOT NULL,
PRIMARY KEY('id')
);

------
- create files table
-----
CREATE TABLE `privileges` (
uesr_id INT NOT NULL,
file_id INT NOT NULL,
);

------
- create users table
-----
CREATE TABLE `users` (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
email VARCHAR(50) NOT NULL,
password CHAR(40) NOT NULL,
PRIMARY KEY('id')
);

<?php
public function get_user_files($filename)
{
   //this is set during login
   $user_id = $this->session->userdata('user_id');

   //check to see if the user has privileges to access the file and gets the file name
   $query = $this->db->join('privileges','privileges.id = files.id')
                     ->select('files.file_name')
                     ->where('privileges.user_id',$user_id)
                     ->where('files.file_name',$file_name)
                     ->limit(1)
                     ->get('files');

    $file = $query->row()->files.file_name;

   if($file)
   {
    //user has privileges to access the file so include it
    $handle = fopen($file, "rb");
    $data['file'] = fread($handle, filesize($file));
    fclose($handle);
   }
  $this->load->view('files',$data);
}
?>

2) CI セッション クラスを使用して、セッションに「ユーザー」を追加します。

コントローラーは、セッションが設定されているかどうかを確認します。

<?php
public function __construct()        
    {
        parent::__construct();

        if($this->secure(array('userType' => 'user')) == FALSE)
        {
            $this->session->set_flashdata('flashError', 'You must be logged into a valid user account to access this section.');
            $this->session->sess_destroy();
            redirect('login');
        }
    }    

function secure($options = array())
    {            
        $userType = $this->session->userdata('userType');

        if(is_array($options['userType']))
        {
            foreach($options['userType'] as $optionUserType)
            {
                if($optionUserType == $userType) return true;
            }
        }
        else
        {
            if($userType == $options['userType']) return true;
        }
        return false;
    }
?>

3) 複数の Web サーバー間でラウンド ロビンをローテーションします。私はこれをやったことがないので、これを行う方法がわかりません。複数のデータベース サーバーを処理する方法がわかりません。アイデア/提案はありますか?

4) Oracle Enterprise Standard Database 監査を使用します。MySQL を使用できればよいのですが、監査サポートが見つかりません。MySQL と PITA を使用できます。MySQL でポイントインタイム アーキテクチャ (PITA) を使用した人はいますか? あなたの経験を共有できますか?

5) したがって、明らかに、一方向のソルト付きハッシュでパスワードをハッシュできます。しかし、すべてを暗号化する必要がありますか? また、 AES_ENCRYPT(str,key_str) がセキュリティを向上させる方法がまったくわかりません。管理者がデータベースを見るのを妨げる可能性があると思いますか? 「secure_files/」フォルダー内のすべてを暗号化できますか? BitLocker のようなフル ディスク暗号化を使用できますか?

基本的に、php と CI でオンライン バンク レベルのセキュリティを実現できますか? 価値のない「あなたは何も知らないから専門家にお金を払ってください」という提案以外に、他に何か提案をすることはできますか?

ここまでお読みいただきありがとうございました。


Redux Auth から採用

一方向ハッシュに関して。暗号化と言う私の間違い。私は通常、次のようなことをします:

ソルトの長さ = '9'; } public function hash($password = false) { $salt_length = $this->salt_length; if ($password === false) { return false; $salt = $this->salt(); $password = $salt . substr(hash('sha256',$salt.$password), 0, -$salt_length); $パスワードを返します。} private function salt() { return substr(md5(uniqid(rand(), true)), 0, $this->salt_length); } } ?>
4

1 に答える 1

2

編集: SQL データベース内の機密データを暗号化すると、3 つの主要な脅威から防御されます。

  1. 内部脅威:

    システム管理者と開発者。

  2. SQL インジェクション:

    データベースが適切に構成されている場合、SQL インジェクションは攻撃者にアプリケーションのデータベースへのアクセスのみを提供し、それ以外には何も提供しません。mysql では、特権を取り消すようにしてください。FILEこれは、ハードコードされたキーまたは構成ファイルの読み取りに使用される可能性があるためです。

  3. さらに安全なバックアップ:

    レイヤーのセキュリティ。

したがって、明らかに、一方向のソルトハッシュでパスワードを暗号化できます。

暗号化はハッシュと同じではありません。暗号化とは、データを解読する手段があることを意味します。パスワードに暗号化機能を使用することは、CWE-257 で認識されている脆弱性です。パスワードは常にソルト ハッシュを使用する必要があり、sha-256 は優れたアルゴリズムです。ハッシュごとに 1 つだけ使用される非常にランダムな値のように、salt はCryptographic nonceである必要があります。

MySQLは最悪です。ひどいECB モードAES_ENCRYPT()を使用しています。関数呼び出しに IV がない場合は、おそらく ECB モードです。IV が null の場合は、CWE-329 に違反しています。

平文:

代替テキスト

ECB モードで暗号化:

代替テキスト

暗号化は難しく、初期化ベクトル、操作モード、キー ストレージ、および string2key 関数について心配する必要があります。大多数のプログラマーは、暗号化は簡単だと考えていますが、かなりの混乱に対処しています。Practical Cryptography のコピーを入手してください。要点が明確で、数学が重くありません。数学が好きなら、「The Handbook」をどうぞ。

編集: エントロピー/サイズ比が悪いため、ナンス生成はあまり好きではありません。塩基 256 の塩を使用できる場合、塩基 16 の塩は無駄です。ほとんどの(おそらくすべての) メッセージ ダイジェストの実装は、バイナリ セーフであることに注意してください。またuniqid()、計算に多くの時間を使用します。時間だけを使用すると、CWE-337 に違反します。一方、mt_rand() はお尻を蹴ります。また、ハッシュ関数で使用する前に、おそらくこれを base64 として保存し、base64 でデコードする必要があることに注意してください。

    public function nonce($size=32){//256 bit == 32byte. 
        for($x=0;$x<$size;$x++){
            $ret.=chr(mt_rand(0,255));
        }
        return base64_encode($ret);
    }
于 2010-06-30T01:29:46.593 に答える