Các Bước Mã Hóa Dữ Liệu Cho Web API

Các Bước Mã Hóa Dữ Liệu Cho Web API

Ở phần trước chúng ta đã cùng nhau tìm hiểu về RESTful Api với Laravel. Ở phần tiếp theo này chúng ta sẽ cùng nhau tìm hiểu cách thức mã hóa dữ liệu trên api đã tạo ở bài trước nhé.

Có 2 thứ mà khi nhắc đến REST API chúng ta không thể bỏ qua được, đó là request và response. Phát triển API ngày càng được chú trọng hơn. Tuy nhiên trong quá trình phát triển các API, việc viết API thực ra có thể viết đơn giản cũng được, nhưng rồi sẽ đến lúc các API bị săm soi,những dữ liệu quan trọng vô tình lọt ra ngoài.

Mặc dù HTTPS là giao thức HTTP đi kèm mã hóa đầu cuối để phòng chống MITM. Thế nhưng đây vẫn là chưa đủ, và những nhà phát triển API cần đi thêm 1 bước nữa trên con đường phòng chống những kẻ tò mò. 

Mã hóa là gì?

Hiểu nôm na mã hóa là phương thức ngụy trang hoặc che giấu một tin nhắn bằng cách áp dụng một số bước lập trình máy tính thành các chuỗi ký tự đặc biệt để ngăn những người không phận sự tiếp cận vào thông tin đó.

Những thuật ngữ mã hóa như kiểu mã hóa, thuật toán mã hóa và độ mạnh mã hóa thường khiến người dùng nhầm lẫn, hãy phân tích nó nhé:

Kiểu mã hóa:

Là loại mã hóa liên quan đến phương pháp mã hóa được hoàn thành. Có rất nhiều loại phương pháp mã hóa khác nhau đã ra đời. Mỗi loại có những ưu và nhược điểm riêng. Ta có thể phân chia các phương pháp mã hóa thành 4 loại chính:

  1. Mã hóa cổ điển
  2. Mã hóa một chiều
  3. Mã hóa đối xứng
  4. Mã hóa bất đối xứng

Thuật toán mã hóa:

Khi nói về độ mạnh mã hóa, chúng ta thường nói về một thuật toán mã hóa cụ thể. Các thuật toán có tên thú vị như Triple DES, RSA hoặc AES. Tên thuật toán mã hóa thường đi kèm với giá trị bằng số, như AES-128, AES-256. Con số này đề cập đến kích thước khóa mã hóa và xác định thêm độ mạnh của thuật toán.

Các loại mã hóa tạo thành nền tảng cho thuật toán mã hóa, trong khi thuật toán mã hóa chịu trách nhiệm về độ mạnh mã hóa. Chúng ta nói về độ mạnh mã hóa theo bit. Dưới đây là một số thuật toán mã hóa phổ biến nhất:

  1. Data Encryption Standard (Tiêu chuẩn mã hóa dữ liệu - DES)
  2. TripleDES
  3. RSA
  4. Advanced Encryption Standard (Tiêu chuẩn mã hóa tiên tiến - AES)
  5. Twofish

Laravel đang sử dụng AES nên chúng ta đi qua về AES chút nhé.

Advanced Encryption Standard (AES) hiện là tiêu chuẩn mã hóa của Chính phủ Hoa Kỳ sử dụng. Nó dựa trên thuật toán Rijndael được phát triển bởi hai nhà mật mã người Bỉ, Joan Daemen và Vincent Rijmen.

AES là thuật toán khóa đối xứng và sử dụng mật mã khối đối xứng. Nó bao gồm ba kích thước chính: 128, 192 hoặc 256 bit. Hơn nữa, có các vòng mã hóa khác nhau cho mỗi kích thước khóa. Một vòng là quá trình chuyển văn bản thô thành văn bản mã hóa. Đối với 128-bit, có 10 vòng (round); 192-bit có 12 vòng, và 256-bit có 14 vòng.

Có những cuộc tấn công lý thuyết chống lại thuật toán AES, nhưng tất cả đều yêu cầu lưu trữ dữ liệu cụ thể và thời gian nhất định, do đó không khả thi trong thời điểm hiện tại. Ví dụ, một cuộc tấn công vào mã hóa AES cần 38 nghìn tỷ dữ liệu, nhiều hơn tất cả dữ liệu được lưu trữ trên tất cả các máy tính trên toàn thế giới trong năm 2016. Ước tính thời gian cần thiết để tạo tấn công brute-force khóa AES-128 là hàng tỷ năm.

Laravel dùng thuật toán này để mã hóa dữ liệu vậy việc chúng ta cần làm là những gì? Chúng ta chỉ cần làm các bước như sau:

  1. Tạo 1 Secret Key trên server.
  2. Chia sẻ Secret Key giữa client và server.
  3. Dùng Secret Key với mã hóa AES (Cái này Laravel đã làm rồi) mã hóa response trả về từ server.
  4. Dùng Secret Key để giải mã trở lại lấy thông tin từ Response.(Nhiệm vụ này là của client nhé)

Mã hóa API response

Ở trong document của Laravel có nói Laravel sử dụng OpenSSL để cung cấp mã hóa AES-256 và AES-128. Tất cả giá trị mã hóa của Laravel được đăng ký sử dụng một mã (MAC) để phát hiện chỉnh sửa ở chuỗi được mã hóa.

Trước khi sử dụng mã hõa của Laravel, bạn phải đặt một key trong file cấu hình config/app.php. Bạn có dùng lệnh 

php artisan key:generate

để tạo ra key này vì lệnh Artisan command sẽ sử dụng secure random bytes của PHP để tạo ra key. Nếu giá trị này không được đặt, tất cả mã hóa của Laravel sẽ không an toàn.

Chúng ta mở config/app.php để xem có gì nào

/*
    |--------------------------------------------------------------------------
    | Encryption Key
    |--------------------------------------------------------------------------
    |
    | This key is used by the Illuminate encrypter service and should be set
    | to a random, 32 character string, otherwise these encrypted strings
    | will not be safe. Please do this before deploying an application!
    |
    */

    'key' => env('APP_KEY'),

    'cipher' => 'AES-256-CBC',

đây là phần chính, key đang được lấy từ file env giá trị của APP_KEY và tất cả các giá trị được mã hoá sử dụng OpenSSL và thuật toán AES-256-CBC cipher.

Phần mô tả trên bảo chúng ta nên đặt chuối 32 ký tự ngẫu nhiên làm key nếu không ứng dụng sẽ không hoạt động.

Chúng ta mở env tìm đến APP_KEY và random chuỗi 32 ký tự nhé

APP_KEY=ABCDEF123ERD456EABCDEF123ERD456E

Vậy là xong phần cấu hình, tiếp theo chúng ta mở file app/Modules/Api/Controllers/Products.php tại ngay method index chúng ta chỉnh sửa như sau:

public function index(){
        $data  = Product::all();
        $payload = Crypt::encrypt($data);
        return response()->json([
            'status' => 200,
            'message' => 'success',
            'data' => $payload
        ],Response::HTTP_OK);
}

Ở trên Laravel có sử Crypt facade Illuminate\Support\Facades\Crypt; giúp chúng ta thực hiện mã hóa và giải mã. Encrypt có input là dữ liệu của chúng ta lấy ra, chúng ta hứng dữ liệu đã được mã hóa bằng biến $payload.

Ở phần return mình có sử dụng response của Illuminate\Http\Response và phương thức json() sẽ tự động thiết lập Content-Type header thành 'application/json' nó tương tự như phương thức json_encode của PHP. phương thức này có 2 đối số, đối số 1 là dữ liệu cần trả về và đối số thứ 2 là status code mà phần trước mình đã nói ở đây Response::HTTP_OK dược define là 200.

Khi chúng ta test trên Postman kết quả là đây:


Ở phía client hoặc api khác muốn giải mã sẽ cần KEY chuối 32 ký tự là chúng ta gán ở file env và phương thức mã hóa AES-256-CBC mới giải mã được data này. Như vậy chúng ta đã hoàn thành việc mã hóa dữ liệu để trao đổi an toàn hơn,thế còn việc giải mã thì sao nhỉ, chúng ta chỉ cần sử dụng method decrypt của Crypt là xong:

public function decode(){
        $data = ''; // chuỗi này chính là đoạn mã hóa mà chúng cần giải mã
        return response()->json([
            'status' => 200,
            'message' => 'success',
            'data' => Crypt::decrypt($data)
        ],Response::HTTP_OK);
}

kết quả:

Tạm kết

Như vậy là chúng ta đã hoàn thành việc tìm hiểu và mã hóa dữ liệu response cho API trong Laravel là như thế nào rồi đấy. Hãy đón chờ bài kế tiếp của mình nhé, chúc các bạn thành công.