Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Mã hóa Laravel AES-256 &MySQL

Cập nhật

PR 31721 đã được hợp nhất vào Laravel 7.0.8, sửa lỗi các dấu gạch chéo về phía trước đã thoát trong mã hóa json. Trước đó, mã hóa cùng một dữ liệu sẽ cung cấp cho bạn kết quả kích thước thay đổi. Giờ đây, kể từ 7.0.8, việc mã hóa cùng một dữ liệu sẽ cho bạn kết quả cùng kích thước mọi lúc.

TL; DR:

Phương thức mã hóa của Laravel sẽ trả về một chuỗi, vì vậy kiểu dữ liệu phải là biến thể varchar hoặc văn bản, tùy thuộc vào kích thước của dữ liệu được mã hóa.

Để xác định kích thước gần đúng, bạn có thể sử dụng một loạt các phép tính sau:

Laravel> =7.0.8

Hãy để a =kích thước của dữ liệu không được mã hóa được tuần tự hóa (strlen(serialize($data)) )
Cho b =a + 16 - (a MOD 16) (tính toán kích thước của dữ liệu được mã hóa)
Hãy c =(b + 2 - ((b + 2) MOD 3)) / 3 * 4 (tính toán kích thước của dữ liệu được mã hóa base64)
Hãy d =c + 117 (thêm kích thước của mã hóa MAC, IV và json)
Hãy e =(d + 2 - ((d + 2) MOD 3)) / 3 * 4 (tính toán kích thước của dữ liệu được mã hóa base64)

Mặc dù giá trị không xác định, nhưng kích thước của kết quả là. Ví dụ:nếu bạn mã hóa một số an sinh xã hội gồm 9 chữ số, kết quả sẽ luôn là 216 ký tự.

Laravel <7.0.8

Hãy để a =kích thước của dữ liệu không được mã hóa được tuần tự hóa (strlen(serialize($data)) )
Cho b =a + 16 - (a MOD 16) (tính toán kích thước của dữ liệu được mã hóa)
Hãy c =(b + 2 - ((b + 2) MOD 3)) / 3 * 4 (tính toán kích thước của dữ liệu được mã hóa base64)
Hãy d =c + 117 + 8 + ((c + 2 - ((c + 2) MOD 3)) / 3) (thêm kích thước mã hóa MAC, IV và json, cộng với bộ đệm bổ sung cho các dấu gạch chéo có khả năng thoát)
Hãy e =(d + 2 - ((d + 2) MOD 3)) / 3 * 4 (tính toán kích thước của dữ liệu được mã hóa base64)

Ví dụ:nếu bạn mã hóa một số an sinh xã hội gồm 9 chữ số, kết quả sẽ có tối thiểu 216 ký tự và tối đa là 308 ký tự (mặc dù đây có thể là điều không thể thống kê). Nếu bạn chạy một vòng lặp gồm hơn 100000 mã hóa, bạn sẽ thấy kích thước thường nằm trong khoảng 216 - 224. Công thức được cung cấp ở trên sẽ yêu cầu bạn đặt trường của mình thành 248 ký tự, đây là vùng đệm tốt trên phạm vi dự kiến, nhưng không phải là không thể đạt được về mặt thống kê.

Chi tiết:

Giá trị được trả về từ phương thức mã hóa không chỉ là văn bản được mã hóa mà còn là biểu diễn được mã hóa base64 của mảng trọng tải được mã hóa json chứa (1) giá trị được mã hóa base64 của dữ liệu được tuần tự hóa, (2) vectơ khởi tạo được mã hóa base64 ( IV), và (3) mã xác thực tin nhắn (MAC). Vì vậy, để xác định kích thước của trường cần thiết, bạn sẽ cần biết kích thước tối đa của dữ liệu sẽ được mã hóa và sau đó thêm một số chỗ cho các phần thông tin bổ sung này được nhồi trong chuỗi trả về.

Đầu tiên, hãy tính kích thước tối đa của giá trị được mã hóa của bạn. Vì thuật toán mã hóa của bạn (AES-256-CBC) là một mật mã khối, điều này khá dễ dàng thực hiện với một công thức. AES sử dụng các khối 16 byte và yêu cầu ít nhất một byte đệm, vì vậy kích thước của giá trị được mã hóa sẽ là bội số tiếp theo của 16. Vì vậy, nếu dữ liệu gốc của bạn là 30 byte, thì dữ liệu được mã hóa của bạn sẽ là 32 byte. Nếu dữ liệu ban đầu của bạn là 32 byte, thì dữ liệu được mã hóa của bạn sẽ là 48 byte (vì AES yêu cầu ít nhất một byte đệm, 32 byte của bạn sẽ trở thành 33 và sau đó tăng lên bội số tiếp theo của 16 đến 48). Công thức cho điều này sẽ là x + 16 - (x MOD 16) . Vì vậy, với 30 byte, bạn nhận được 30 + 16 - (30 MOD 16) = 32 .

Khi tính toán kích thước của giá trị được mã hóa, hãy nhớ rằng dữ liệu được mã hóa lần đầu tiên được tuần tự hóa. Vì vậy, ví dụ:nếu bạn đang mã hóa một số an sinh xã hội, giá trị thuần chỉ là 9 ký tự, nhưng giá trị được tuần tự hóa thực sự là 16 ký tự (s:9:"xxxxxxxxx"; ). Vì giá trị được tuần tự hóa là giá trị thực sự được mã hóa và nó là 16 byte, nên kích thước của giá trị được mã hóa sẽ là 32 byte (16 + 16 - (16 MOD 16) = 32 ).

Ngoài ra, openssl_encrypt hàm trả về dữ liệu được mã hóa đã được mã hóa base64. Mã hóa Base64 tăng kích thước của giá trị lên khoảng 4/3. Đối với mỗi 3 byte trong dữ liệu gốc, mã hóa base64 sẽ tạo ra một biểu diễn 4 byte (ký tự). Vì vậy, đối với ví dụ SSN, kết quả được mã hóa là 32 byte. Khi dịch sang base64, 32 byte cho chúng ta (32 / 3) = 10.6 Phân đoạn 3 byte. Vì base64 đệm đến byte tiếp theo, hãy lấy giá trị trần và nhân với 4, cho ra 11 * 4 = 44 byte. Vì vậy, giá trị mã hóa 32 byte ban đầu của chúng ta trở thành một chuỗi 44 ký tự. Nếu bạn cần một công thức cho việc này, bạn có thể sử dụng (x + 2 - ((x + 2) MOD 3)) / 3 * 4 . Vì vậy, (32 + 2 - ((32 + 2) MOD 3)) / 3 * 4 = 44 .

Thông tin tiếp theo là MAC. MAC là giá trị băm SHA256, vì vậy chúng tôi biết rằng nó sẽ có 64 ký tự.

Phần thông tin cuối cùng là IV. IV thuần túy là 16 byte ngẫu nhiên. IV được lưu trữ trong mảng trọng tải là giá trị được mã hóa base64 của IV thuần túy. Vì vậy, chúng ta có thể sử dụng công thức trên để tính kích thước của IV được mã hóa base64:(16 + 2 - ((16 + 2) MOD 3)) / 3 * 4 = 24 .

Ba phần thông tin này được nén thành một mảng, và sau đó được json_encoded. Do biểu diễn json và tên của các giá trị trong mảng, điều này sẽ thêm 29 byte khác.

Ngoài ra, trong Laravel <7.0.8, bất kỳ dấu gạch chéo về phía trước nào trong dữ liệu được mã hóa base64 đều được thoát bằng dấu gạch chéo ngược trong chuỗi json, do đó, điều này thêm một số byte thay đổi tùy thuộc vào số lượng dấu gạch chéo về phía trước. Đối với ví dụ SSN, có 68 ký tự của dữ liệu được mã hóa base64 (44 cho dữ liệu được mã hóa, 24 cho IV). Giả sử số lượng dấu gạch chéo về phía trước tối đa có thể là khoảng 1/3 kết quả, hoặc khoảng 23 byte thừa. Trong Laravel> =7.0.8, các dấu gạch chéo về phía trước này không được thoát ra, vì vậy không có byte thừa.

Cuối cùng, giá trị json_encoded này là base64_encoded, một lần nữa sẽ tăng kích thước lên khoảng 4/3.

Vì vậy, để tổng hợp tất cả những điều này lại với nhau, hãy một lần nữa tưởng tượng bạn đang mã hóa một số an sinh xã hội. openssl_encrypt kết quả sẽ là 44 ký tự, MAC là 64 ký tự, IV là 24 ký tự và biểu diễn json thêm 29 ký tự khác.

Trong Laravel <7.0.8, cũng có bộ đệm thêm 23 ký tự. Điều này mang lại cho chúng tôi (44 + 64 + 24 + 29 + 23 = 184 ) nhân vật. Kết quả này được mã hóa base64, cho chúng ta ((184 + 2 - ((184 + 2) MOD 3)) / 3 * 4 = 248 ) ký tự.

Trong Laravel> =7.0.8, không có bộ đệm bổ sung. Điều này mang lại cho chúng tôi (44 + 64 + 24 + 29 = 161 ) nhân vật. Kết quả này được mã hóa base64, cho chúng ta ((161 + 2 - ((161 + 2) MOD 3)) / 3 * 4 = 216 ) ký tự.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Truy vấn SQL nhiều giá trị trong một ô

  2. Cách tốt nhất để đồng bộ hóa dữ liệu giữa MS Access và MySQL là gì?

  3. CHỌN nhiều hàng MÀ phù hợp với hai điều kiện

  4. Cách hiệu quả nhất để lưu trữ thứ tự sắp xếp trên một nhóm bản ghi trong cơ sở dữ liệu là gì?

  5. Cách chọn giá trị từ JSON trong mysql