Security Encryption HIPAA ePHI

I have a downtime and I’m thinking about choosing a new project for fun. I am a college student and every year we have an online competition. I want to create a project for this pitch competition that is approximately 9 months old. The problem is that the project requires very high security, and competition is very competitive.

Things I need to do: 1. Store HIPAA or ePHI (.pdf | .gif | .jpg | .doc) 2. Strong access control 3. Support for a large number of users and files (1 million +) 4. Full reports on audit (oh ePhi, what a pain you are) 5. Encryption

Suggested Solutions
0) Put the web application on a secure dedicated server behind the firewall.

1) Store the files in a file, for example, "secure_files /", and then use mod_rewrite to restrict access to this directory.

Something in the lines:

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

Then use a php script to open the files if the user has privileges for this. So I can just use:

 ------ -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) Use the CI session class to add a "user" to the session.

The controller checks if the session is established:

 <?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) Rotate a round robin between several cobwebs. I have never done this, so I have no idea how to do this. I have no idea how to handle multiple database servers. Any ideas / suggestions?

4) Use Oracle Database Standard Database Auditing. I wish I could use MySQL, but I cannot find any audit support. I could use MySQL and use PITA. Has anyone used a point-in-time (PITA) architecture with MySQL? can you share your experience?

5) Thus, I can use hash codes with a one-way salt hash. But do I need to encrypt everything? Also, I do not see how AES_ENCRYPT (str, key_str) generally improves security. I think this may prevent the administrator from looking at the database? Can / should I encrypt everything in the secure_files / folder? Can I just use full disk encryption like BitLocker?

Basically, can I achieve security at the level of banking Internet using php and CI? Can you make any other suggestions, except that "your idiot must pay an expert because you know nothing"?

Thanks for taking the time to read this.


adopted from Redux Auth

As for the one-way hash. My mistake is what I'm talking about encryption. I usually do something similar to:

salt_length = '9'; } public 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); return $ password; } salt of private functions () {return substr (md5 (uniqid (rand (), true)), 0, $ this-> salt_length); }}? >
+4
source share
1 answer

Edit: Encrypting sensitive data in sql database protects against 3 main threats.

  • Internal threats:

    Administrator and Sys developers.

  • SQL Injection:

    If your database is configured correctly, SQL injection should provide an attacker access to the application database and nothing more. In mysql, make sure that you revoke the FILE privileged, as this could be used to read a hard-coded key or configuration file.

  • Even more secure backups:

    Security in layers.

Therefore, obviously, I can encrypt passwords with a one-way salt hash.

Encryption is not the same as hashing. Encryption implies that there is a way to decrypt data. Using the encryption feature for passwords is a vulnerability recognized by CWE-257 . Passwords should always use a salty hash, and sha-256 is a great algorithm. The salt should be Cryptographic nonce , as in a very random value that only uses 1 per hash.

MySQL AES_ENCRYPT() sucks using ECB mode , which is terrible. If the function call does not have an IV, this is probably ECB mode, if the IV is zero, then this is a violation of CWE-329.

Plain text:

alt text

encrypted using ECB mode:

alt text

Encryption is difficult, you need to worry about initialization vectors, operation modes, key storage and string2key functions. The vast majority of programmers believe that cryptography is simple, but they seriously run the mess up . Get a copy of Practical Cryptography, its straightforward, not mathematical. If you like math, go to The Handbook .

EDIT: I don't like your nonce generation very much because it has a poor entropy / size ratio. Base salt 16 is waste when you could have a base with salt. Keep in mind that most (possibly all) message digest implementations are binary. In addition, uniqid() uses a lot of time in its calculation, and if it only used time, it would be a violation of CWE-337. Now, on the other hand, mt_rand () kicks the ass . Also keep in mind that you should probably store this as base64 and then base64 decode it before using it in your hash function.

  public function nonce($size=32){//256 bit == 32byte. for($x=0;$x<$size;$x++){ $ret.=chr(mt_rand(0,255)); } return base64_encode($ret); } 
+2
source

Source: https://habr.com/ru/post/1314275/


All Articles