{"id":11064,"date":"2018-02-10T11:12:45","date_gmt":"2018-02-10T10:12:45","guid":{"rendered":"http:\/\/flaven.fr\/?p=11064"},"modified":"2021-03-23T08:07:06","modified_gmt":"2021-03-23T07:07:06","slug":"mysql-encrypt-decrypt-encryption-decryption-data-in-php-mysql-and-some-elements-on-the-gdpr-compliance","status":"publish","type":"post","link":"https:\/\/flaven.fr\/2018\/02\/mysql-encrypt-decrypt-encryption-decryption-data-in-php-mysql-and-some-elements-on-the-gdpr-compliance\/","title":{"rendered":"MySQL, Encrypt, Decrypt &#8211; Encryption, decryption data in PHP, MySQL and some elements on the GDPR Compliance"},"content":{"rendered":"<p>Due to the coming GDPR (General Data Protection Regulation), that should come into force on 25th May 2018. Many organisations have to rethink their privacy policy. Indeed, GDPR establishes in terms of storage and exploitation of data a lot of new restrictions and duties.<\/p>\n<p>There is a lot of literature and business around this new directive. After meeting some so-called experts, you still remain &#8220;dazed and confused&#8221; on what steps to make to be compliant with the GDPR.<i>*<\/i><\/p>\n<p><b>The GDPR has at list one first benefit, it brings personal data and privacy to the fore in many companies.<\/b><\/p>\n<p><i>*In my case, I have met incompetent and arrogant consultants unable to make any recommendations that have added more mess to a situation already complex.<\/i><\/p>\n<p><b>What has to be remembered from the GDPR? I have found this bullet points list below. Some of the points are not meaningful in my case as it has a lot to deal with hosting and IT. Matters that are not directly in the scope of my function. The point that I wanted get to grips with is the &#8220;pseudonymisation and encryption&#8221;. This one clearly belongs to my tasks.<\/b><\/p>\n<ol>\n<li>Record keeping: each controller and processor must maintain a record of all categories of processing activities carried out.<\/li>\n<li><b>Pseudonymisation and encryption: all personal data must be pseudonomised and\/or encrypted.<\/b><\/li>\n<li>Security and resilience: ensure the ongoing confidentiality, integrity, availability and resilience of processing systems and services.<\/li>\n<li>Disaster recovery: the ability to restore the availability and access to personal data in a timely manner in the event of a physical or technical incident.<\/li>\n<li>Testing and monitoring: a process for regularly testing, assessing and evaluating the effectiveness of technical and organisational measures for ensuring the security of the processing.<\/li>\n<li>Breach notification: a personal data breach must be notified without undue delay and, where feasible, not later than 72 hours.<\/li>\n<\/ol>\n<p>Source: <a href=\"https:\/\/www.itproportal.com\/features\/how-enterprise-file-services-can-help-ensure-gdpr-compliance\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.itproportal.com\/features\/how-enterprise-file-services-can-help-ensure-gdpr-compliance\/<\/a><\/p>\n<h2>Encrypted data<\/h2>\n<p>Let&#8217;s say we create 2 tables in a database named <code>encrypt_db<\/code>, just to point out the differences.<\/p>\n<p><b>The table with with fields in clear<\/b><\/p>\n<pre lang=\"sql\">\r\n-- NON-ENCRYPTED TABLE\r\nCREATE  TABLE user_non_encrypted_ex (\r\nid BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,\r\nusername VARCHAR(250) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',\r\npassword VARCHAR(100) NOT NULL DEFAULT '',\r\naddress VARCHAR(200) NOT NULL DEFAULT '',\r\nsalt VARCHAR(20) NOT NULL DEFAULT '',\r\nPRIMARY KEY (id)\r\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;\r\n<\/pre>\n<p><b>The same table with &#8220;crypted&#8221; fields<\/b><\/p>\n<pre lang=\"sql\">\r\n-- ENCRYPTED TABLE\r\nCREATE  TABLE user_encrypted_ex (\r\nid BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,\r\nusername VARBINARY(100) NOT NULL DEFAULT '',\r\npassword VARBINARY(100) NOT NULL DEFAULT '',\r\naddress VARBINARY(200) NOT NULL DEFAULT '',\r\nsalt VARBINARY(20) DEFAULT NULL,\r\nPRIMARY KEY (id)\r\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;\r\n<\/pre>\n<p>Now, I add to insert some dummy data. Here they are. As usual, I like using US presidents as dummy data.<\/p>\n<pre lang=\"text\">\r\n-- user 1\r\nusername : Donald Trump\r\npassword : Russian_Roulette\r\naddress : White-House\r\nsalt : Melania\r\nkey : Mar-a-Lago\r\n\r\n-- user 2\r\nusername : Barack Obama\r\npassword : Michelle_Mabelle\r\naddress : Illinois\r\nsalt : Hillary\r\nkey : Kenya\r\n\r\n-- user 3\r\nusername : George W. Bush\r\npassword : Howdy_My_Password\r\naddress : Texas\r\nsalt : Bretzel\r\nkey : Saddam\t\r\n<\/pre>\n<p>Give honour where honour is due, I start with &#8220;Joli Toupet&#8221;. Here is the main queries for Donald Trump.<\/p>\n<pre lang=\"sql\">\r\n-- insert user non encrypted\r\nINSERT INTO user_non_encrypted_ex (id, username, password, address, salt) VALUES (NULL, 'Donald Trump', 'Russian_Roulette', 'White-House', 'Melania');\r\n\r\n-- insert same user encrypted\r\nINSERT INTO user_encrypted_ex (id, username, password, address, salt) VALUES (NULL, AES_ENCRYPT('Donald Trump', 'Mar-a-Lago'), AES_ENCRYPT(CONCAT('Russian_Roulette','Melania'),'Mar-a-Lago'), AES_ENCRYPT('White-House', 'Mar-a-Lago'), AES_ENCRYPT('Melania', 'Mar-a-Lago'));\r\n\r\n-- DETAIL FOR EACH FIELD\r\n-- username => AES_ENCRYPT('Donald Trump', 'Mar-a-Lago')\r\n-- password => AES_ENCRYPT(CONCAT('Russian_Roulette','Melania'),'Mar-a-Lago')\r\n-- username => AES_ENCRYPT('White-House', 'Mar-a-Lago')\r\n-- username => AES_ENCRYPT('Melania', 'Mar-a-Lago')\r\n\r\n-- query_1 : select encrypt data \r\nSELECT AES_DECRYPT(username, 'Mar-a-Lago'), AES_DECRYPT(address, 'Mar-a-Lago') FROM user_encrypted_ex;\r\n-- Output : Donald Trump, White-House\r\n\r\n-- query_4: select encrypt password\r\nSELECT AES_DECRYPT(password, 'Mar-a-Lago') FROM user_encrypted_ex;\r\n-- Output : Russian_RouletteMelania\r\n\r\n-- query_3: select encrypt password retrieve the salt\r\nSELECT REPLACE(CAST(AES_DECRYPT(password,'Mar-a-Lago') AS CHAR(100)), AES_DECRYPT(salt, 'Mar-a-Lago'), '') FROM user_encrypted_ex;\r\n-- Output : Russian_Roulette\r\n\r\n-- DETAIL FOR PASSWORD\r\n-- password => REPLACE(CAST(AES_DECRYPT(password,'Mar-a-Lago') AS CHAR(100)), AES_DECRYPT(salt, 'Mar-a-Lago'), '')\r\n\r\n-- query_4: select all\r\nSELECT AES_DECRYPT(username, 'Mar-a-Lago'), REPLACE(CAST(AES_DECRYPT(password,'Mar-a-Lago') AS CHAR(100)), AES_DECRYPT(salt, 'Mar-a-Lago'), ''), AES_DECRYPT(address, 'Mar-a-Lago') FROM user_encrypted_ex;\r\n<\/pre>\n<p><b>The first query (query_1), a select query of  encrypted data : username, address<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2018\/02\/mysql_aes_encrypt_aes_decrypt_1.jpg\" width=\"640\" height=\"480\" alt=\"MySQL, Encrypt, Decrypt - Encryption, decryption data in PHP, MySQL and some elements on the GDPR Compliance\"><\/p>\n<p><b>The second query (query_2), a select query of  encrypted data : password<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2018\/02\/mysql_aes_encrypt_aes_decrypt_2.jpg\" width=\"640\" height=\"480\" alt=\"MySQL, Encrypt, Decrypt - Encryption, decryption data in PHP, MySQL and some elements on the GDPR Compliance\"><\/p>\n<p><b>The third query (query_3), a select query of  encrypted data : password without the salt string<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2018\/02\/mysql_aes_encrypt_aes_decrypt_3.jpg\" width=\"640\" height=\"480\" alt=\"MySQL, Encrypt, Decrypt - Encryption, decryption data in PHP, MySQL and some elements on the GDPR Compliance\"><\/p>\n<p><b>The fourth query (query_4), a select query of  encrypted data : username, address, password without the salt string<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2018\/02\/mysql_aes_encrypt_aes_decrypt_4.jpg\" width=\"640\" height=\"480\" alt=\"MySQL, Encrypt, Decrypt - Encryption, decryption data in PHP, MySQL and some elements on the GDPR Compliance\"><\/p>\n<p><b>BAD: the table user_non_encrypted_ex from encrypt_db<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2018\/02\/mysql_aes_encrypt_aes_decrypt_5.jpg\" width=\"640\" height=\"480\" alt=\"MySQL, Encrypt, Decrypt - Encryption, decryption data in PHP, MySQL and some elements on the GDPR Compliance\"><\/p>\n<p><b>GOOD: the table user_encrypted_ex from encrypt_db with same information encrypted.<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2018\/02\/mysql_aes_encrypt_aes_decrypt_6.jpg\" width=\"640\" height=\"480\" alt=\"MySQL, Encrypt, Decrypt - Encryption, decryption data in PHP, MySQL and some elements on the GDPR Compliance\"><\/p>\n<h2>A note on decrypting password<\/h2>\n<p><b>Don&#8217;t do it! The ability to decrypt user&#8217;s passwords is made only for fun and the purpose of this post to understand encrypt, decrypt methods with a salt system in particular.<\/b> If you&#8217;re storing user passwords, you should hash them with sha1 or md5, not encrypt them. There&#8217;s really no valid use case for decrypting customer passwords. The best thing to do, it is just to think of a recovery password procedure. So the users can completely reset their password rather than your application emails them their current.<\/p>\n<h2>POC : a mini CRUD with encrypted data<\/h2>\n<p><b>I found a great article on webslesson.info. It is the next step after understanding how to encrypt data. This step is how to manipulate data with the help of PHP, in a secure way with encryption and decryption.<\/b><\/p>\n<p><i>The funny thing is that the videos available on youtube, see below for the links, has been recorded and translated with a non-human voice from Google.<\/i><\/p>\n<p>Source : <a href=\"http:\/\/www.webslesson.info\/2017\/12\/encryption-and-decryption-form-data-in-php.html\" target=\"_blank\" rel=\"noopener\">http:\/\/www.webslesson.info\/2017\/12\/encryption-and-decryption-form-data-in-php.html<\/a><\/p>\n<p><b>In function.php, the scripting method, the most important part, that is the key to encrypt and decrypt the data.<\/b><\/p>\n<pre lang=\"php\">\r\n $encrypt_method = \"AES-256-CBC\";\r\n    $secret_key = 'i7fh3x68dch#jh1ey0s+j9$(h128+(i9g)725*k0grt!'; \/\/ 44 characters\r\n    $secret_iv = '8mgo+i40!l-jtr!fb@vb='; \/\/ 21 characters\r\n<\/pre>\n<p>For those, you want to read more on Encryption Standard especially on AES-256-CBC:<br \/>\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Advanced_Encryption_Standard\" target=\"_blank\" rel=\"noopener\">https:\/\/en.wikipedia.org\/wiki\/Advanced_Encryption_Standard<\/a><\/p>\n<h2>Things to remember about security<\/h2>\n<p>Apparently, if your database is hacked, it will be impossible to decrypt the data. The idea is to protect the key as much you can, be not a mule smuggling drugs for cartels. The idea is to keep this api key in the safer place possible. So apparently, the best idea is to &#8220;use an ini file that&#8217;s read at runtime and that is not publicly accessible within the scope of the Web server&#8221;.<\/p>\n<ol>\n<li>Fully rely on the MySQL decryption and encryption abilities may be very problematic if the database has internal failures. It will render your application unusable.<\/li>\n<li>No need to solicit the decryption and encryption abilities of MySQL. Using PHP may optimise the speed and efficiency of your application.<\/li>\n<li>MySQL often logs transactions, so if the database\u2019s server has been compromised, then the log file would produce both the encryption key and the original value.<\/li>\n<\/ol>\n<p>Source: <a href=\"https:\/\/www.smashingmagazine.com\/2012\/05\/replicating-mysql-aes-encryption-methods-with-php\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.smashingmagazine.com\/2012\/05\/replicating-mysql-aes-encryption-methods-with-php\/<\/a><\/p>\n<p><b>What is an initialization vector?<\/b><br \/>\nI was intrigued by the value secret_iv. Just for my personal information. iv stands for initialization vector (IV). An initialization vector (IV) is an arbitrary number that can be used along with a secret key for data encryption. This number, also called a nonce, is employed only one time in any session. The use of an IV prevents repetition in data encryption, making it more difficult for a hacker using a dictionary attack to find patterns and break a cipher.<\/p>\n<p><b>Enter some records inside the Dashboard<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2018\/02\/mysql_aes_encrypt_aes_decrypt_7.jpg\" width=\"640\" height=\"480\" alt=\"MySQL, Encrypt, Decrypt - Encryption, decryption data in PHP, MySQL and some elements on the GDPR Compliance\"><\/p>\n<p><b>The records inside the database are encrypted<\/b><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/flaven.fr\/wp-content\/uploads\/2018\/02\/mysql_aes_encrypt_aes_decrypt_8.jpg\" width=\"640\" height=\"480\" alt=\"MySQL, Encrypt, Decrypt - Encryption, decryption data in PHP, MySQL and some elements on the GDPR Compliance\"><\/p>\n<p>You can find the files @<a href=\"https:\/\/github.com\/bflaven\/BlogArticlesExamples\/tree\/master\/manage_potus\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/bflaven\/BlogArticlesExamples\/tree\/master\/manage_potus<\/a><\/p>\n<h2>Read more<\/h2>\n<ul>\n<li>Very nice article. Encryption and Decryption Form Data in PHP<br \/><a href=\"http:\/\/www.webslesson.info\/2017\/12\/encryption-and-decryption-form-data-in-php.html\" target=\"_blank\" rel=\"noopener\">http:\/\/www.webslesson.info\/2017\/12\/encryption-and-decryption-form-data-in-php.html<\/a><\/li>\n<li>Encrypt Decrypt Hashing &#8211; PHP &#038; MYSQL &#8211; Protect your data in your database<br \/><a href=\"https:\/\/www.youtube.com\/watch?v=WwxAyiAtrbM\" target=\"_blank\" rel=\"noopener\">https:\/\/www.youtube.com\/watch?v=WwxAyiAtrbM<\/a><\/li>\n<li>The tag GDPR in Janrain resources<br \/><a href=\"https:\/\/www.janrain.com\/resources\" target=\"_blank\" rel=\"noopener\">https:\/\/www.janrain.com\/resources\/by-topic\/gdpr<\/a><\/li>\n<li>MYSQL Database Encryption<br \/><a href=\"https:\/\/www.youtube.com\/watch?v=X7ACdLRb6Wk\" target=\"_blank\" rel=\"noopener\">https:\/\/www.youtube.com\/watch?v=X7ACdLRb6Wk<\/a><\/li>\n<li>Few principles on Mysql &#8211; Encryption<br \/><a href=\"https:\/\/www.youtube.com\/watch?v=CX-btPUPPdw\" target=\"_blank\" rel=\"noopener\">https:\/\/www.youtube.com\/watch?v=CX-btPUPPdw<\/a><\/li>\n<li>Very nice article. ENCRYPT MYSQL DATA USING AES TECHNIQUES<br \/><a href=\"http:\/\/thinkdiff.net\/mysql\/encrypt-mysql-data-using-aes-techniques\/\" target=\"_blank\" rel=\"noopener\">http:\/\/thinkdiff.net\/mysql\/encrypt-mysql-data-using-aes-techniques\/<\/a><\/li>\n<li>Replicating MySQL AES Encryption Methods With PHP<br \/><a href=\"https:\/\/www.smashingmagazine.com\/2012\/05\/replicating-mysql-aes-encryption-methods-with-php\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.smashingmagazine.com\/2012\/05\/replicating-mysql-aes-encryption-methods-with-php\/<\/a><\/li>\n<li>PHP MySQL AES encrypt\/decrypt on gitbub<br \/><a href=\"https:\/\/github.com\/noprotocol\/php-mysql-aes-crypt\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/noprotocol\/php-mysql-aes-crypt<\/a><\/li>\n<li>How to Use MySQL&#8217;s AES_ENCRYPT and AES_DECRYPT to Store Information in a Database<br \/><a href=\"http:\/\/www.johnboy.com\/blog\/how-to-use-mysqls-aes_encrypt-and-aes_decrypt-to-store-information-in-a-database\" target=\"_blank\" rel=\"noopener\">http:\/\/www.johnboy.com\/blog\/how-to-use-mysqls-aes_encrypt-and-aes_decrypt-to-store-information-in-a-database<\/a><\/li>\n<li>How to Encrypt &#038; Decrypt Form Data using PHP Ajax &#8211; 1 from webslesson.info<br \/><a href=\"https:\/\/www.youtube.com\/watch?v=chegnVgCl64\" target=\"_blank\" rel=\"noopener\">https:\/\/www.youtube.com\/watch?v=chegnVgCl64<\/a><\/li>\n<li>How to Encrypt &#038; Decrypt Form Data using PHP Ajax &#8211; 2 from webslesson.info<br \/><a href=\"https:\/\/www.youtube.com\/watch?v=izPOTdRKvAY\" target=\"_blank\" rel=\"noopener\">https:\/\/www.youtube.com\/watch?v=izPOTdRKvAY<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Due to the coming GDPR (General Data Protection Regulation), that should come into force on 25th May 2018. Many organisations have to rethink their privacy&hellip; <\/p>\n<p class=\"text-center\"><a href=\"https:\/\/flaven.fr\/2018\/02\/mysql-encrypt-decrypt-encryption-decryption-data-in-php-mysql-and-some-elements-on-the-gdpr-compliance\/\" class=\"more-link\">Continue reading &rarr; <span class=\"screen-reader-text\">MySQL, Encrypt, Decrypt &#8211; Encryption, decryption data in PHP, MySQL and some elements on the GDPR Compliance<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":11076,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"bf_ai_meta_description":"GDPR compliance requires encrypting data in PHP and MySQL. This guide covers tools and outcomes for secure data handling and privacy.","bf_ai_og_title":"GDPR: Encrypt Data in PHP, MySQL","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[3437,3454,3444,3447,3448,3449,3450,3435],"tags":[2420,2183,2398,1244,2421,192,2211,20,2422],"class_list":["post-11064","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-business-case-studies","category-journalism-writing","category-programming-databases","category-technology-trends","category-tools-productivity","category-tutorials-how-to","category-ux-product-design","category-web-development","tag-aes","tag-api","tag-crud","tag-europe","tag-gdpr","tag-json","tag-mysql","tag-php","tag-security"],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3Vuhl-2Ss","jetpack_featured_media_url":"https:\/\/flaven.fr\/wp-content\/uploads\/2018\/02\/mysql_aes_encrypt_aes_decrypt_b.jpg","_links":{"self":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/11064","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/comments?post=11064"}],"version-history":[{"count":8,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/11064\/revisions"}],"predecessor-version":[{"id":11821,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/posts\/11064\/revisions\/11821"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/media\/11076"}],"wp:attachment":[{"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/media?parent=11064"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/categories?post=11064"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/flaven.fr\/happy-api\/wp\/v2\/tags?post=11064"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}