2010-06-30 94 views
4

我有一些停機時間,我覺得選擇一個新項目的樂趣。我是一名大學生,每年我們都會舉辦網上音樂比賽。我想爲這場距離比賽大約9個月的比賽創建一個項目。問題是該項目需要非常高的安全性,而且競爭非常激烈。安全HIPAA ePHI加密

事情,我需要能夠做到: 1.存儲HIPAA或ePHI的(.PDF | .gif注意| JPG格式| .DOC) 2.強大的訪問控制 3.支持大量的用戶和文件( 1億多) 4.全審計報告(哦EPHI你是這樣的痛) 5.加密

提出的解決方案
0)將Web應用程序防火牆上的

1後面的安全專用服務器)將文件存儲在文件中說「secure_files /」,然後使用mod_rewrite限制對此的訪問d irectory。上線

東西:

#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企業標準數據庫審計。我希望我可以使用MySQL,但我找不到任何審計支持。我可以使用MySQL並使用PITA。有沒有人使用MySQL的時間點架構(PITA)?你能分享你的經驗嗎?

5)所以很顯然,我可以散列密碼與單向鹽漬散列。但是我需要加密一切嗎?另外我也沒有看到AES_ENCRYPT(str,key_str)是如何提高安全性的。我想這可能會阻止管理員查看數據庫?我可以/應該加密「secure_files /」文件夾中的所有內容嗎?我可以使用BitLocker等全盤加密嗎?

基本上可以通過php和CI實現網上銀行級別的安全嗎?除了毫無價值的「你一個白癡去付專家,因爲你什麼都不知道」的建議之外,你能否提出其他建議?

感謝您花時間閱讀本文。


從終極版驗證

採用至於單向散列。說我的錯誤加密。我通常會做類似於:

salt_length ='9'; ($ 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); 返回$ password; } 私有函數salt() { return substr(md5(uniqid(rand(),true)),0,$ this-> salt_length); }} >
+0

在未來,您應該嘗試將這樣的大問題分解爲更小的部分。這將是更容易回答,你會得到更多的積分:) – rook 2010-06-30 04:41:17

回答

2

編輯: 在SQL數據庫加密敏感數據抵禦3個大威脅。

  1. 內部威脅:

    系統管理員和開發人員。

  2. SQL注入:

    如果你的數據庫配置正確的SQL注入應該只提供訪問應用程序的數據庫,而不是其他的攻擊者。在mysql中,請確保您撤回FILE特權,因爲這可能用於讀取硬編碼的密鑰或配置文件。

  3. 更加安全備份:

    安全的層。

所以,很顯然,我可以用單向散列鹹魚加密 密碼。

加密與哈希不同。加密意味着有解密數據的手段。使用密碼加密功能是由CWE-257識別的漏洞。密碼必須總是使用salted hash,而sha-256是一個很好的算法。鹽應該是一個Cryptographic nonce,因爲在一個非常隨機的值中,每個哈希只使用1個值。

MySQL的AES_ENCRYPT()很爛,其使用ECB mode這太可怕了。如果函數調用沒有IV可能的ECB模式,如果IV是空的,那麼它違反了CWE-329。

明文:

alt text

與ECB模式加密:

alt text

加密是困難的,你不用擔心初始化向量,經營模式,密鑰存儲和string2key函數。絕大多數程序員認爲密碼學很容易,但他們認真地管理mess things up。獲取實用密碼學的一個副本,其直接點,而不是數學重。如果你喜歡數學,然後去"The Handbook"

編輯: 我不喜歡你的nonce世代,因爲它的熵/尺寸比不好。當你可以有256鹼鹽時,鹼16鹽是浪費。請記住,大多數(可能全部)消息摘要實現是二進制安全的。另外uniqid()在計算中使用了大量時間,如果它只使用時間,那將違反CWE-337。另一方面,現在mt_rand() kicks ass。另外請記住,您應該將其存儲爲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); 
    } 
+0

我同意你同意我的笑聲。我將不得不閱讀你建議的書。你有沒有讀過你的自我?我是一名工程專業的學生,​​所以數學難以嚇倒我。它是否回答關於密鑰存儲,初始化向量等問題?大多數書籍都是這樣說的; 「嘿,這東西很難,你需要考慮這些事情。」但是不要提出任何有用的解決方案。感謝您的跟進 – John 2010-06-30 03:21:08

+0

@ user379592在本文中,您有許多CWE違規行爲。把它們拿出來記錄下來是我能做的最好的。如果你有更具體的問題,那麼你會得到更好的答案。如果數學不會嚇到你比用「The Handbook」(http://books.google.com/books?id=nSzoG72E93MC&dq=handbook+of+applied+cryptography&printsec=frontcover&source=bn&hl=en&ei=lr4qTISWEYKjnQeL0vR5&sa=X&oi=book_result&ct = result&resnum = 6&ved = 0CDwQ6AEwBQ#v = onepage&q&f = false) – rook 2010-06-30 03:49:15

+0

我完全同意你的隨機數。這是一個更好的改進。再次感謝您不要將我視爲無望的新人。我有很多東西需要學習,但是我再次擁有圖書館,沒有電視和偉大人物的偉大建議。謝謝。我會翻閱「手冊」(必須愛神祕的書名)和CWE。 – John 2010-06-30 04:16:04