Mã hóa dữ liệu trong Database

Đôi lúc vì một số lý do bảo mật mà bạn muốn các dữ liệu lưu trong database phải được mã hóa trước khi được lưu vào. Data Encryption and Decryption sử dụng AES (Advanced Encryption Standard) là phương thức phổ biến để thực hiện. Ở trong bài này, mình sẽ hướng dẫn cách sử dụng kĩ thuật này nhằm giúp cho database của bạn luôn luôn được mã hóa.
Ví dụ: Tạo bảng user vs email và address sẽ luôn được mã hóa.

 - Cấu trúc của table khi không được mã hóa:

 CREATE TABLE `user` (  
 `id` INT NOT NULL AUTO_INCREMENT ,  
 `email` VARCHAR(100) NOT NULL ,  
 `address` VARCHAR(100) NOT NULL ,  
 PRIMARY KEY (`id`)  
 ENGINE = InnoDB  
 DEFAULT CHARACTER SET = utf8  
 COLLATE = utf8_general_ci  

- Cấu trúc của table khi email và address được mã hóa

 CREATE TABLE `user` (  
 `id` INT NOT NULL AUTO_INCREMENT ,  
 `email` VARBINARY(116) NOT NULL ,  
 `address` VARBINARY(116) NOT NULL ,  
 PRIMARY KEY (`id`)  
 ENGINE = InnoDB  
 DEFAULT CHARACTER SET = utf8  
 COLLATE = utf8_general_ci  

Sự khác biệt ở đây là ở table không được mã hóa, email và address sử dụng VARCHAR còn table mã hóa sử dụng VARBINARY. Bởi vì để mã hóa dữ liệu ta sẽ sử dụng 2 phương thức AES_ENCRYPT() và AES_DECRYPT(). Khi sử dụng AES_ENCRYPT() dữ liệu sẽ được chuyển từ kiểu chuỗi ( string ) sang chuỗi nhị phân ( binary string ) và ngược lại với AES_DECRYPT().

Bạn cũng có thể tính toán được độ dài của dữ liêu theo công thức:

 16 × (trunc(string_length / 16) + 1)  

Theo ví dụ trên:
Ta có email VARCHAR(100) theo công thức ta có:

 16 x (trunc(100 / 16) + 1)  
 = 16 x (trunc(6.25) + 1)  
 = 16 x 7.25  
 = 116  

Suy ra VARCHAR(100) = VARBINARY(116).

Cú pháp để sử dụng phương thức AES_ENCRYPT và AES_DECRYPT

 AES_ENCRYPT(str, key_str);  
 AES_DECRYPT(crypt_str,key_str);  

Ví dụ cho table trên:
 - Mã hóa (Encrypt) và lưu vào database:

 INSERT into user (email, address) VALUES (AES_ENCRYPT('nguyennhatcuong.it@gmail.com', 'secret'),AES_ENCRYPT('Da Nang, Viet Nam', 'secret'));  

 - Giải mã (Decrypt) và lấy dữ liệu ra:

 SELECT AES_DECRYPT(email, 'secret'), AES_DECRYPT(address, 'secret') from user;  

Bài viết có sử dụng một số nguồn tham khảo ở:
https://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html#function_aes-encrypt
http://thinkdiff.net/mysql/encrypt-mysql-data-using-aes-techniques/

Nhận xét

  1. trong trường hợp mình có 1 file exel danh sách khách hàng, mình xuất ra .csv
    và import vào database , yêu cầu là cột địa chỉ và cột số điện thoại sẽ bị mã hóa

    vậy có thể mã hóa ngay lúc import dc không ? vì danh sách file excel thì rất nhiều, không thể làm thủ công từng record

    Trả lờiXóa

Đăng nhận xét

Bài đăng phổ biến từ blog này

Upload và remove hình ảnh trong laravel

Chuyển đổi HTML sang PDF sử dụng Javascript