Thứ Tư, 27 tháng 6, 2018

Tư vấn tuyển sinh ngành CNTT

Tư vấn tuyển sinh ngành CNTT

Phần tư vấn của mình gồm có 7 phần:
  • Phần 1. Tổng quan ngành CNTT.
  • Phần 2. Những tính chất bạn cần có khi học ngành CNTT.
  • Phần 3. Đặc trưng ngành CNTT.
  • Phần 4. Nên chọn trường nào.
  • Phần 5: Q & A.
  • Phần 6. Tư vấn mua máy tính & điện thoại.
  • Phần 7. Quảng cáo.

PHẦN 1. Tổng quan ngành CNTT

Ngày xưa, người ta hiểu ngành Công nghệ Thông tin (CNTT) là ngành làm việc với máy tính và xử lý thông tin, truyền tải thông tin. Dễ dàng thấy nhất là lập trình ra phần mềm ứng dụng, quản lý mạng máy tính,…
Nhưng đó là ngày xưa, còn ngày nay thì khác rồi. Ngành CNTT hiện tại là ngành công nghệ phát triển nhanh nhất thế giới. Nó phát triển nhanh đến nỗi ngày hôm qua là chúng ta có thể lạc hậu so với thế giới của ngày hôm nay. Chúng ta không chỉ đơn giản làm việc với máy tính nữa mà còn những thiết bị khác như điện thoại di động thông minh, đồng hồ đeo tay thông minh, tivi thông minh… Và biết đâu một ngày không xa, ngay cả con chuột, cái loa, ghề ngồi, bàn làm việc, cái giường cũng có thể trở thành chiếc máy tính nho nhỏ và tất cả được kết nối với nhau lại.
Để biết tổng quan hơn về ngành CNTT, bạn hãy xem hình ở dưới:
Đây là cách chia theo mô hình của Việt Nam theo quan điểm của mình. Ở trên thế giới thì Khoa học máy tính là gốc chứ không phải là 1 nhánh riêng.Ở Việt Nam thì chúng ta thường gọi là "Công nghệ thông tin" nhưng ở thế giới thì ngành này có tên là "Computer Science" (Khoa học máy tính).

Có rất nhiều bạn thích vào CNTT là vì muốn làm game, làm ra trang web, làm ra các app điện thoại,… thì những hướng đi này thuộc nhánh “Kỹ thuật phần mềm”.
Để hiểu rõ hơn về ngành CNTT, bạn có thể xem 1 bài viết của riêng mình nhé.

PHẦN 2. Những tính chất bạn cần có khi học ngành CNTT

Người ta thường hay nói “bác sĩ, kỹ sư”. Hàm ý câu nói này là chỉ những ngành nghề có tính đặc thù cao, những người có học thức cao trong xã hội.
Và ngành CNTT cũng vậy.

Ngành CNTT là có một tính chất đặc thù đó là cần trình độ chuyên môn cao. Vì vậy những tay ngang, học qua loa rất khó để theo đuổi dài lâu.
Bây giờ bạn đang chán với nghề hiện tại, bạn thích chuyển sang học làm bác sĩ. Người ta nói học bác sĩ cần 6 năm, 8 năm, 10 năm… Học lâu như vậy thì mới đủ trình độ chuyên môn, vậy thì liệu bạn có đủ kiên trì để theo đuổi đến cùng ?
Và bạn hiểu ý mình rồi đấy, ngành CNTT cũng vậy.

Đam mê

Tính chất đầu tiên và cũng là tính chất quan trọng hàng đầu khi bạn theo đuổi ngành CNTT, đó là ĐAM MÊ. ĐAM MÊ VÔ TẬN, ĐAM MÊ TỚI CÙNG.
Sự đam mê xuất phát từ sự yêu thích và tò mò. Bạn thấy người khác làm ra game hay quá và bạn cũng muốn làm ra game như vậy. Bạn thấy trang web này sao mà lung linh, tuyết rơi đẹp quá. Bạn thấy những con chatbot có thể chat được với con người. Bạn tò mò làm sao mà Google có thể tìm kiếm được thông tin nhanh và chính xác như vậy.
Bạn thích, bạn muốn làm ra chúng. Đam mê dần dần hình thành.

Sự đam mê chỉ thật sự hình thành khi bạn có sự trải nghiệm một chút. Bạn thấy thích làm game, nhưng khi bạn thử lập trình một tí bạn thấy nản, như vậy có vẻ bạn chỉ dừng lại ở mức độ “thích” chứ chưa phải là “đam mê”. Sự trải nghiệm cũng rất dễ dàng, có rất nhiều trang web giúp bạn tự học lập trình, bạn thử làm một chút, cảm thụ nó, tâng bốc sản phẩm của mình lên, dần dần cảm thấy phấn khích hơn, sự đam mê dần dần hình thành.

Thành công vĩ đại bắt đầu từ những điều nhỏ bé.

Kỹ năng IT

Tính chất tiếp theo mà bạn cần có, đó là kỹ năng IT.
Trong thực tế, rất nhiều bạn mới vào Đại học ngành CNTT đều chưa có kỹ năng IT. Nếu bạn là người mới bắt đầu (beginner) thì bạn cũng đừng quá lo lắng.
Kỹ năng IT giống như những công cụ, vũ khí trong nhà bạn vậy. Bạn muốn tạo ra 1 cái ghế nhưng bạn thiếu công cụ chuyên môn, bạn phải làm thủ công, bạn sẽ cực khổ hơn. Người khác cũng muốn làm ra 1 cái ghế nhưng họ có công cụ đầy đủ, họ làm rất nhanh, nhanh hơn rất nhiều lần so với bạn, thậm chí sản phẩm còn đẹp hơn của bạn.

Kỹ năng IT là vậy đấy.
Kỹ năng IT là những công cụ, vũ khí đắc lực giúp bạn đi nhanh hơn, đi xa hơn so với người khác. Vậy thì kỹ năng IT là gì ?
Kỹ năng IT bao gồm tất cả những kỹ năng sử dụng máy tính, bao gồm kỹ năng tìm kiếm với Google, lướt web, cài đặt & sử dụng các phần mềm thông dụng (Word, Excel, Powerpoint, WinRAR,…), thiết lập thông số máy tính, máy ảo, diệt virus bằng tay, v.v

Ở mức độ cơ bản, bạn hãy rèn luyện lại kỹ năng sử dụng Microsoft Office (Word, Excel, Powerpoint), tìm hiểu nhiều hơn về hệ điều hành đang sử dụng (Windows, Ubuntu,…), học nhiều hơn về trình duyệt web và những tính năng hữu ích của nó,… Những cái này là không bao giờ thừa bạn nhé.

Tiếng Anh

Chúng ta đều biết tiếng Anh quan trọng như thế nào trong xã hội hiện nay, nhưng với ngành CNTT thì tiếng Anh càng có ý nghĩa quan trọng.
Đa số những câu hỏi thảo luận trong ngành CNTT đều là tiếng Anh. Đa số những tài liệu tuyệt vời chi tiết đều viết bằng tiếng Anh. Nếu bạn không rèn luyện tiếng Anh, làm sao bạn có thể tiếp cận những nguồn tri thức lớn như vậy ?
Chúng ta chỉ mới xét đến đọc & hiểu tiếng Anh. Nếu bạn muốn có mức lương cao hơn thì tiếng Anh là điều không thể thiếu.
Có 2 bạn tuyển dụng vào 1 vị trí trong công ty:
  • 1 bạn trình độ chuyên môn cao, 10 điểm luôn, nhưng tiếng Anh thì rất tệ.
  • 1 bạn trình độ khá, 8 điểm thôi, nhưng bạn này tốt tiếng Anh, có thể giao tiếp được với người nước ngoài.
Nếu công ty đang muốn mở rộng đối tác sang nước ngoài thì bạn trình độ khá 90% được chọn. Thậm chí nếu công ty chọn cả 2 bạn thì bạn trình độ khá có thể được lương cao hơn. Đơn giản vì bạn này là cầu nối giúp công ty làm việc với khách hàng nước ngoài tiện lợi hơn.
Tiếng Anh giúp bạn khai sáng kiến thức, cho bạn cơ hội – cơ hội nghề nghiệp, cơ hội mở rộn kiến thức, cơ hội để giao tiếp và tạo ra mối quan hệ với nhiều người hơn trên thế giới.

Tư duy & Toán học

Để học tốt ngành CNTT, bạn cần có tư duy và kỹ năng giải quyết vấn đề (problem solving).
Tư duy ở đây là tư duy theo kiểu lập trình. Khi bạn gặp 1 vấn đề nào đó, bạn có thể suy nghĩ ra từng bước từng bước để giải quyết vấn đề đó.

Ví dụ: cho bài toán “tìm số lớn nhất trong 3 số a, b, c”.
Ở góc độ của 1 người bình thường, nhìn vào 3 số họ thấy ngay đáp án. Nhưng đây không phải là tư duy theo phương pháp lập trình. Nếu ta tư duy theo phương pháp lập trình thì ta có thể tìm số lớn nhất trong hàng trăm số, hàng triệu số chỉ với…1 giây…
  • Gọi m là số lớn nhất trong 3 số.
  • Bước 1. Đặt m = a (giả sử số lớn nhất là a).
  • Bước 2. Kiểm tra nếu m < b thì ta đặt m = b.
  • Bước 3. Kiểm tra nếu m < c thì ta đặt m = c.
Sau khi thực hiện 3 bước này thì m là số lớn nhất mà ta cần tìm.

Thật ra, điều mình muốn nói là tư duy thuật toán. Trong suốt quá trình học CNTT, bạn sẽ rèn luyện tư duy thuật toán. Ở góc độ cơ bản thì chúng không hề khó một chút nào mà còn thú vị nữa chứ.

Đi kèm với tư duy thì ta còn 1 yếu tố khác: Toán học.
Có nhiều người nói rằng học CNTT bắt buộc phải giỏi Toán học. Đối với quan điểm của mình thì điều này chưa được chính xác.
Tất nhiên, bạn nên cần học Toán nhưng còn tùy vào con đường bạn chọn mà sẽ học ở mức độ nào.
  • Nếu bạn học để ra các sản phẩm bình thường, bạn chỉ cần học cơ bản Toán phổ thông là đủ.
  • Nếu bạn muốn học thiên về nghiên cứu và đi sâu xuống dưới, đặc biệt là học sâu về Khoa học máy tính thì bạn sẽ không bao giờ né được Toán.
  • Nếu bạn muốn tạo ra sự khác biệt và đi lên cao hơn thì Toán có vai trò quan trọng.
Có một số bạn lầm tưởng và ghét học Toán vì thấy nó hàn lâm không có ý nghĩa không có ứng dụng vào thực tế. Vấn đề là chỉ khi bạn học CNTT, bạn mới dần dần thấy được Toán có ý nghĩa thế nào. Đâu phải tự dưng những bạn giỏi Toán đi thi Olympic Tin học đi thi HSG Tin học được giải cao đâu.
Có 1 khoảng trống giữa lý thuyết và thực tế, nếu rút ngắn được khoảng trống này thì bạn có động lực cao hơn để học Toán.

Học Toán trước hết là rèn luyện cách tư duy và giải quyết vấn đề.

Sự may mắn

Wow, mới đọc thì nghe thật là buồn cười. Nhưng quan điểm của mình là vậy đấy.
Sẽ có nhiều lúc bạn bỏ cuộc trước những vấn đề nan giải, nhưng nhờ có sự may mắn đã vô tình giúp bạn thành công.
Sự may mắn này không phải ngẫu nhiên mà nó, nó cần được tập luyện .

PHẦN 3. Đặc trưng ngành CNTT

Sự tự học cao

Ngành CNTT có đặc điểm là có thể tự học. Và những bạn có khả năng tự học cao là những bạn giỏi.
Trường học chỉ dạy bạn 10%, 90% còn lại là tùy vào khả năng tự học của bạn.
Với kỹ năng Google tìm kiếm thông tin kèm với kinh nghiệm keyword, bạn có thể tìm kiếm những khóa học phù hợp để học.

Lương cao

Lương cao đó là một điều chắc chắn không thể nào phủ nhận.
Nhưng, không phải lúc nào cũng lương cao, điều đó phụ thuộc vào năng lực của bạn.

Gần đến mùa tuyển sinh, các trường đua nhau PR quảng cáo.
Vấn đề là có những bài viết PR lố, tiêm nhiễm vào đầu các bạn sinh viên với mức lương khủng, để rồi ra trường thì ảo tưởng sức mạnh ghê gớm. Có bạn học hành đéo ra gì mà deal lương như siêu nhân.

Nếu bạn chỉ là một tay mơ, khả năng bạn sẽ không có cơ hội việc làm t ốt. Thậm chí dù có đi nữa thì mức lương trong ngành CNTT sẽ thấp. Như vậy điều quan trọng là cá nhân bạn cần rèn luyện kỹ năng chuyên môn và rèn luyện nhiều kỹ năng khác để nâng cao giá trị bản thân nhé.

Bệnh tật

Ngồi máy tính lâu, bạn sẽ bị suy giảm sức khỏe trầm trọng.
Màn hình máy tính sẽ phát ra ánh sáng xanh làm hại mắt. Nếu màn hình không tốt sẽ gây mỏi mắt.
Nếu bạn ngồi máy tính ở 1 chỗ liên tục, ít vận động, bạn có thể bị yếu đi, khô người, bị ảnh hưởng đến cột sống, và tai hại hơn là có thể bị dính bệnh trĩ.

Vì vậy nên nhiều người nói rằng tuổi thọ nghề CNTT không cao. Tuy nhiên nếu bạn ý thức được điều đó, giữ sức khỏe tốt thì bạn có thể làm việc lâu dài. Hãy ý thức về sức khỏe cao hơn nhé.

Dễ bị stress

Bạn thường xuyên gặp các vấn đề nan giải. Thậm chí bạn mất nhiều ngày cũng chưa giải quyết được.
Khi gần đến hạn chót (deadline) mà bạn chưa hoàn thành, bạn có thể cần phải “chạy đua gấp rút”, làm việc tăng ca (OT – overtime).
Với những ngành khác, sau khi đi làm về thì đầu óc của bạn sẽ thoải mái cùng với vợ con, gia đình…
Nhưng với ngành CNTT, sau khi đi làm về thì bạn có thể không ngừng suy nghĩ về vấn đề của mình. Điều này dễ dàng gây stress.

PHẦN 4. Nên chọn học trường nào

Phần này hơi bị động chạm 1 chút . Tất cả đều là đánh giá của cá nhân mình.
Mình sẽ liệt kê theo dạng danh sách, không phải trường nào xuất hiện ở phía trên tức là giỏi hơn trường ở phía dưới.

TP Hồ Chí Minh

Tại TP Hồ Chí Minh có 3 trường top về đào tạo CNTT trong miền Nam:
  • Đại học Bách Khoa – ĐH Quốc gia TP. HCM
  • Đại học Khoa học Tự nhiên – ĐH Quốc gia TP. HCM
  • Đại học Công nghệ Thông tin – ĐH Quốc gia TP. HCM
Trường Đại học Bách Khoa: cái mác “Bách Khoa” đủ để nói được thanh danh và chất lượng đào tạo của trường. Điểm đầu vào rất cao. Với mình thì trường Bách Khoa đào tạo rất hàn lâm và hướng về điện tử, vì vậy ngày xưa mình không muốn học tại trường này. Trường có 2 ngành là “Khoa học máy tính” và “Kỹ thuật máy tính”. Bạn nên nộp vào ngành “Khoa học máy tính” thay vì “Kỹ thuật máy tính”, vì “Kỹ thuật máy tính” bạn sẽ làm việc nhiều đến điện tử, mạch số, lập trình nhúng.
Những người bạn học Bách Khoa mình từng gặp đều là người giỏi, có ý chí cao, có khả năng tự học rất cao.

Trường Đại học Khoa học Tự nhiên: đây là ngôi trường mà mình học. Chương trình đào tạo ít hàn lâm hơn so với Bách Khoa (tuy nhiên gần đây mình thấy chương trình đào tạo có vẻ bất ổn hơn, có vài môn hàn lâm xuất hiện). Trường có đầy đủ các chuyên ngành cho bạn đi theo: Công nghệ phần mềm, Mạng máy tính, Hệ thống thông tin, Khoa học máy tính, Thị giác máy tính & robot, Công nghệ tri thức.
Cá nhân mình thấy trường đào tạo rất tốt. Trường có các thầy cô rất giỏi và nổi tiếng như thầy Đinh Bá Tiến – người từng được NASA mời về, thầy Trần Minh Triết,… Đi theo những người thầy cô giỏi, bạn sẽ được định hướng tốt hơn trên con đường tương lai. Trường KHTN của mình cũng rất mạnh về mảng Competitive Programming, trường có đào tạo đội ngũ ACM riêng, điều này phù hợp với những bạn từng đi thi Học sinh giỏi Tin học và thích thuật toán.
Mình học trường KHTN tất nhiên mình phải PR cho trường mình rồi, nếu bạn muốn có cơ hội trở thành siêu nhân, hãy vào trường ĐH Khoa học Tự nhiên.

Trường Đại học Công nghệ Thông tin có tuổi đời ít hơn so với BK và KHTN. Trường mạnh về đào tạo Mạng máy tính và bảo mật. Vì vậy những bạn nào thích học về “hacker” thì có thể nên nộp đơn vào ngành Mạng máy tính nhé. Bên cạnh Mạng máy tính thì thường có đào tạo về các chuyên ngành khác nữa. Có 1 khuyết điểm đó là bạn cần phải đăng ký vào chuyên ngành luôn Mình rất thích khuôn viên của trường, mát mẻ và dễ chịu.

TP Hà Nội

Tại Hà Nội có 3 trường sau:
  • Đại học Bách Khoa Hà Nội
  • Đại học Công nghệ – ĐH Quốc gia Hà Nội
  • Học viện công nghệ Bưu chính viễn thông
Với mình thì trường Đại học Bách Khoa Hà Nội là đào tạo tốt nhất ở miền Bắc. Mình có quen biết nhiều bạn và cũng có nhiều bạn học trò tại trường này.
Trường BKHN có vài môn hàn lâm khó học nhưng dù sao mình cảm thấy vẫn đỡ hơn Bách Khoa TP HCM. Sinh viên CNTT của trường có nền tảng Toán và tư duy tốt, rất chăm học.
Dẫu biết rằng CNTT có sự tự học cao nhưng các bạn nói với mình rằng thầy cô dạy nhanh quá nên nếu chưa có nền tảng thì khó theo kịp. Có một khuyết điểm mình nhận diện ra đó là nhiều bạn học tại BKHN lập trình yếu vì chưa rèn luyện nhiều, những môn học nền tảng thì chưa có đồ án hoặc bài tập lớn để rèn luyện ra sản phẩm. Ở giai đoạn chuyên ngành thì các bạn ổn hơn.

Trường Đại học Công nghệ, thật ra thì mình chưa quen biết nhiều bạn tại đây. Nhưng thông qua việc trò chuyện mình cũng hiểu được phần nào. Do đó mình mạn phép không đánh giá cụ thể trường nhưng mình vẫn đánh giá rằng trường đào tạo tốt.

Học viện công nghệ Bữu chính Viễn thông ở Hà Nội thì cũng rất nổi tiếng (ở TP HCM thì không nổi tiếng bằng). Tuy nhiên mình cảm thấy chưa đủ thông tin nên mình chưa đánh giá cụ thể được.

Trường khác

Những trường thuộc hàng top thì dĩ nhiên điểm chuẩn sẽ cao. Nếu điểm của bạn không đủ cao để vào thì sao ?
Mình giới thiệu trường Đại học FPT dành cho bạn nào có điều kiện tài chính và không cần điểm thi cao. Trường Đại học FPT có cơ sở ở Hà Nội lẫn TP HCM. Mình đánh giá cao về trường ở việc đào tạo bằng tiếng Anh, thực hành nhiều. Tuy nhiên mình cảm giác như trường dạy quá nhanh nên sinh viên không có nền tảng thì rất thiệt thòi.

PHẦN 5. Q & A

Q: Em muốn làm hacker thì em thi vào trường nào vậy anh ?
A: Làm về hacking tức là thiên về bảo mật & mạng máy tính. Em nên tìm hiểu trường nào đào tạo tốt về Mạng máy tính & Bảo mật. Ở TP HCM có trường Đại học Công nghệ Thông tin – ĐHQG TP HCM. Ngoài ra còn có Học viện Kỹ thuật Quân sự, Học viện Kỹ thuật Mật mã. Nói vậy không có nghĩa em muốn làm hacker thì phải vào đúng trường. Bản chất là em vẫn phải học những kiến thức nền tảng bên dưới. Chỉ cần em biết được hướng đi của em là bảo mật & hacking thì em sẽ có nhiều chủ đề để học.

Q: Em là con gái thì liệu có phù hợp với ngành CNTT không anh ?
A: Ngành CNTT có nữ nữa chứ em, trường anh có nhiều giảng viên là nữ và rất giỏi. Người ta thường khuyên là con gái thì nên học về tester, BA hoặc thiết kế web, tuy nhiên anh không nghĩ vậy. Nếu em thích CNTT thì cứ học đi nhé ^^.

Q: Em mới bắt đầu thì em nên học gì vậy anh ?
A: Anh sẽ cho em xem 1 hình.
Em mới bắt đầu thì nên học làm quen với máy tính, sử dụng nó thành thạo. Em nên rèn luyện kỹ năng tìm kiếm với Google.
Sau đó em có thể bắt đầu học lập trình được rồi.
Để đạt cảnh giới tốt và tư duy tốt, em nên bắt đầu với ngôn ngữ C/C++ hoặc Python nhé. Đừng vội học ngôn ngữ khác từ đầu trừ khi em đã có định hướng tốt.


Q: Học theo hướng nào thì cơ hội việc làm cao hơn vậy anh ?
A: Anh xin khẳng định 100% ngành CNTT không bao giờ thiếu việc làm. Tin tuyển dụng ở khắp mọi nơi. Như vậy mấu chốt quan trọng là kiến thức của em như thế nào và lương bao nhiêu thôi em.
Nếu anh nói rằng hiện nay học về web và Big Data đang rất là hot, vậy thì liệu em có theo không ? Và trong vài năm sau, khi Big Data đã hết hot, liệu em sẽ tiếp tục theo nó, và biết đâu 1 ngày nào đó công nghệ mà em học đã bị xóa sổ khỏi thế giới, em sẽ như thế nào ?
Thật ra mấu chốt ở đây là em thích cái nào thì em theo cái đó. Em thích em đi theo đến cùng, em học giỏi và có nền tảng thì sẽ không bao giờ lương thấp (cho dù em học bất kì chuyên ngành gì, kể cả chuyên ngành ít người theo học). Giỏi ở đây là giỏi đúng nghĩa: em giỏi chuyên môn, đồng thời em giỏi quan hệ, em tìm ra công ty tuyển dụng phù hợp với em. Khi người có kiến thức và người tuyển dụng gặp nhau, mọi chuyện sẽ rất tuyệt vời.
Nền tảng là gốc rễ của nhiều kiến thức. Những kiến thức và công nghệ ở bên trên có thể sụp đổ vào 1 ngày nào đó, nhưng nền tảng ở phía dưới thì gần như không bao giờ sụp đổ. Do đó cái quan trọng là em nắm thật vững nền tảng nhé. Nền tảng bao gồm tư duy lập trình, lập trình hướng đối tượng, cấu trúc dữ liệu & giải thuật, kiến trúc máy tính, mạng máy tính cơ bản, nguyên lý hệ điều hành, cơ sở dữ liệu,…

Q: Em thích học CNTT nhưng em không thích vào Đại học. Em muốn tự học hoặc vào trường nghề, vào trung tâm để học cho lẹ.
A: Anh thừa nhận rằng trường Đại học có nhiều môn hàn lâm, nhiều lúc thầy cô dạy dở, chán. Cuộc đời là vậy mà em.
Nhưng ngành CNTT thì rất là tự do, tại sao em phải giới hạn tầm hiểu biết của em qua lời giảng của thầy cô thay vì em có thể chủ động học từ bạn bè, chủ động lên Google tìm kiếm bài giảng khác ?
Trường Đại học cho em môi trường để rèn luyện, cho em người thầy cô giỏi để định hướng, cho em kiến thức chuyên môn tốt nhất, cho em nền tảng tuyệt vời để phát triển, cho em cơ hội việc làm cao hơn, cho em những người bạn cùng đi với em trên con đường phía trước – Nguyễn Trung Thành.
Vậy, sao em vẫn không muốn học Đại học ?

PHẦN 6. Tư vấn mua máy tính & điện thoại

Vì bài viết đã quá dài nên mình mạn phép cắt bỏ đi .

PHẦN 7. Quảng cáo

Nếu bạn mới bước chân vào ngành CNTT và bạn chưa biết bắt đầu từ đâu, chưa biết định hướng con đường ra sao, thì bạn có thể học với mình.
Hiện tại mình đào tạo 2 môn học lập trình nền tảng nhất trong ngành CNTT.
Môn học “Nhập môn lập trình”: https://drive.google.com/file/d/0B_s3E_YllMagU0EwOXRyWmVSejA/view
Môn học “Kỹ thuật lập trình”: https://drive.google.com/file/d/0B_s3E_YllMagMENhZ2tZWUo1Rzg/view

Phần tư vấn của mình đã xong rồi.
Nếu bạn có thắc mắc, hãy comment bên dưới và mình sẽ giải đáp (P/S: mình trả lời khá lâu). Nếu được mình sẽ đưa phần câu hỏi comment lên phần Q & A luôn nhé ^^.

Thứ Tư, 20 tháng 6, 2018

Băm và lưu password đúng cách

Sau khi đọc bài viết băm mật khẩu đúng cách của anh thaidn, mình nhớ lại lúc trước cũng đã từng nghĩ về vấn đề này (lúc đó mình khá thích môn IA ở trường) nhưng chưa bao giờ hiểu tường tận. Chỉ biết là không nên:
  • Lưu password ở dạng plain-text.
  • Hash với một thuật toán hash mạnh, không nên xài MD5, SHA-1 ...
  • Hash với salt.
Chỉ hiểu rằng phải nên làm thế, nhưng không hiểu tại sao lại như vậy và một số câu hỏi khác cũng chưa trả lời được như:
  • Password user gửi lên, nên hash ở client hay ở server.
  • Salt nên lưu ở đâu.
  • Salt có cần giữ bí mật hay không?
  • Salt chung cho tất cả, hay salt riêng cho từng user?
Hôm nay, mình quyết định đi tìm câu trả lời cho những vấn đề mình thắc mắc, thay vì mặc định nó đúng.

1. Tại sao không nên lưu plain-text, encrypt hoặc dùng MD5, SHA-1

Nếu lưu plain-text, database bị hack, SQL-injection, password user chìa ra theo một cách không thể dễ dàng hơn để đánh cắp.
Nếu mã hóa 2 chiều, sẽ luôn có một cách để giải mã bằng một chìa-khóa nào đó, sẽ phải tìm cách lưu chìa-khóa một cách an toàn.
MD5 và SHA-1 được chứng minh có đụng độ, nghĩa là 2 password khác nhau, khi hash bằng MD5 hoặc SHA-1 có thể ra cùng một chuỗi.

2. Tại sao phải salt

Ta đã biết, hash algorithm là one-way-function, tức là không thể suy ngược trực tiếp ra password nếu có hash_value (khác với mã hóa, có thể giải mã thông qua chìa-khóa).
Tuy nhiên vẫn có cách để từ hash_value có thể suy gián tiếp ra được password ví dụ brute-force attach, dictionary attach -> điểm chung là ta cần thử và đoán password nhiều lần cho tới khi đúng cái cần tìm.
Một cách khác đó là ta có thể tính toán trước giá trị hash của tất cả các trường hợp và của tất cả các thuật toán -> cách này khó, tốn thời gian, nhưng bây giờ với tốc độ tính toán của máy tính, ta vẫn có thể làm được. Bảng lưu trữ password + hash_value của password gọi là Rainbow Table, có thể tự tạo hoặc tải một số bản miễn phí hoặc trả tiền để mua. Từ bây giờ nếu ta có hash_value ta có thể mapping để suy ra được password.
Tuy nhiên nếu ta chỉ hash mỗi password, ta gặp vấn đề đó là:
  • 2 password giống nhau (user vô tình trùng password) thì chuỗi hash(password) sẽ giống nhau.
  • User cố tình đặt password đơn giản và phổ biến (ví dụ password < 4 kí tự, toàn số, toàn chữ) -> dễ nhớ cho user nhưng dễ tra ngược.
Và nếu chỉ hash password thì nếu mất hash_value, có thể tra trong rainbow table để tìm ra được password của người dùng.
Giờ ta thử thay vì hash(password) ta sẽ hash(salt + password):
Từ md5(123456)
id |          hash_md5                |
---------------------------------------
1  | e10adc3949ba59abbe56e057f20f883e |
Thành md5(7nWZLcCK0vsPzIM + 123456)
id |          hash_md5                |    salt         |
---------------------------------------------------------
1  | 0510210d4b370165658bdc0d0b005244 | 7nWZLcCK0vsPzIM |
Giờ giả sử, ta mất bảng dữ liệu gồm hash_md5, salt, kẻ tấn công sẽ phải tính toán lại rainbow table của tất cả các trường hợp cộng với salt. Nếu salt là random cho từng user, kẻ tấn công sẽ phải tính toán toàn bộ trường hợp cộng với riêng từng salt cho toàn bộ user.
Chi phí cho 2 phép tính trên là vô cùng lớn và tốn rất nhiều thời gian để thực hiện. Vậy tóm lại mục đích của salt và random-salt là:
  • Bảo vệ user kể cả khi user dùng password phổ biến và password không mạnh vì user không thể nhớ được các password phức tạp nhưng tốc độ tính toán của máy tính thì càng ngày càng nhanh.
  • Tạo ra nhiều chi phí tính toán, kẻ tấn công không thể tính toán trước rainbow table.
=> Ta trả lời đc 3 câu hỏi:
  • Salt có thể lưu trong database, cùng với hash_value.
  • Không cần tìm cách giữ bí mật salt, nhưng cũng đừng tự ý công khai salt.
  • Nhưng bắt buộc phải random salt cho từng user.

3. Hash ở đâu?

Giờ giả sử hash(password) ở client-side thì vấn đề là gì?
  • Biết được thuật toán dùng để hash.
  • Salt sẽ phải sinh ra ở client, vì ta cần hash password với salt (hash(salt + password)), và db chỉ lưu kết quả hash, không lưu salt.
  • Nhưng nếu salt sinh ra ở client và salt random thì làm sao để compare với hash_value trong database? Vì lần chứng thực tới, salt sẽ lại random và sẽ khác với kết quả trong database -> salt phải duy nhất cho tất cả các trường hợp.
  • Hoặc salt có thể lưu ở DB, nhưng server phải gửi salt về trước cho user trước khi thực hiện hash -> dễ dàng biết được salt hơn.
Nhìn sơ thì thấy việc dùng duy nhất một salt đã chống lại luận điểm ở mục số 2. Vậy quy trình chứng thực đúng là như thế nào?
  • User sẽ gửi plain-text password lên server và over HTTPs.
  • Server sẽ kiểm tra trong database lấy ra salt của user đó, cộng chuỗi ta được salt + password.
  • Thực hiện hash(salt + password) trên server side.
  • Compare kết quả trên với hash_md5 trong database.

4. Tại sao dùng bcrypt thay cho SHA-512

Kết quả của SHA-512 có độ dài 128 kí tự, độ dài của key là 64 bytes. Trông có vẻ cũng khá chắc chắn, vậy tại sao OWASP recommend sử dụng PBKDF2, bcrypt hoặc scrypt hơn là SHA2?
SHA2 là hash algorithm (tất nhiên), nó được thiết kế với mục tiêu là tốc độ, với các CPU hiện đại, có thể generate hàng triệu kết quả trên giây. Nếu dùng một thuật toán có tốc độ như SHA2 tức là bạn đã đem lợi điểm tới cho kẻ tấn công brute-force. Thuật toán nhanh + cấu hình server mạnh, việc brute-force càng trở lên nhanh chóng hơn.
Trong khi đó, bcrypt được gọi là slow-hash algorithm, có nghĩa là vẫn đạt được mục đích hash nhưng giảm thiểu nguy cơ tấn công brute-force.
Tóm lại: SHA-512 không phải là một thuật toán yếu, mà vấn đề là SHA-512 không phù hợp cho việc hash password. Nếu cần hash password thì ta nên dùng các thuật toán slow hash như PBKDF2, bcrypt và scrypt.

5. Tại sao cần Pepper?

Một thực tế là nếu bạn chỉ có "muối" mà không có "tiêu", ăn thịt gà luộc sẽ không ngon :v. Giả sử, database bạn chạy RAID-1, một ổ cứng hư và cần thay một ổ cứng mới. Nhưng như ta biết, đĩa bị hư là mirror của đĩa còn lại, bạn phải tiêu hủy ổ cứng hư đó nếu không ai đó có thể lục thùng rác và tái tạo lại một phần dữ liệu trong đĩa hư đó.
Xin lưu ý, bạn cần wipe trước khi vứt bỏ một ổ cứng có dữ liệu dù cá nhân hay server, tuy nhiên đĩa bị sốc điện, bad-sector thì wipe cũng chưa đủ an toàn, tốt nhất nên ngiền ra bã.
Dù random-salt đã làm tăng chi phí tạo ra rainbow table nhưng đời không biết đâu mà lần, kẻ tấn công luôn có những động lực không tưởng để đạt được cái mình muốn. Giả sử kẻ tấn công có một siêu siêu máy tính và một mirror ổ cứng hư lục từ một cái thùng rác nào đó. Với siêu máy tính đó, ta có rainbow-table để tra ngược ra password cần tìm.
Vậy làm sao để giảm thiểu nguy cơ trên? Nguyên tắc là không bỏ tất cả trứng trong một giỏ, đó là pepper. Pepper là một chuỗi tương tự như salt, nhưng khác biệt là ta cần giữ bí mật pepper, lưu ở một chỗ khác ngoài database, và không cần pepper-per-user, chỉ cần 1 pepper là đủ.
Từ
hash(salt + password)
Thành
hash(pepper + salt + password)
Ta nên lưu pepper ở application hoặc ở một service khác, nếu database bị compromise, thì kẻ tấn công cũng không có pepper để tạo ra rainbow-table.

6. Bonus


Trong khi tìm câu trả lời để viết bài này, mình tìm được một bài blog của dropbox nói về cách họ lưu password như thế nào. Thấy có 2 điểm khá hay nên muốn nói thêm.
  • Trước khi hash password với salt-per-user, họ có SHA512(password) trước để cố định độ dài của input-password. Theo Dropbox thì việc này giải quyết 2 issues của bcrypt
    • Một số implementation của bcrypt cắt đầu vào còn 72 bytes.
    • Một số implementation khác của bcrypt thì không cắt đầu vào nhưng dẫn tới một vấn đề khác là DoS attack bởi vì cho phép độ dài mật khẩu tùy ý.
  • Dropbox cũng có global pepper nhưng thay vì dùng nó để hash thì họ encrypt. Tức là thay vì hash(pepper + salt + password) thì họ AES256(salt + password) + global-pepper-key. Theo như họ giải thích thì pepper là một lớp phòng thủ sâu hơn và lưu trữ ở một nơi riêng biệt. Nhưng đồng nghĩa với việc là nơi lưu trữ pepper vẫn có thể bị compromise, và khi bị compromise thì việc rotate key không dễ dàng. Dùng pepper để encrypt vẫn đạt được mục đích bảo mật tương tự nhưng thêm khả năng rotate key khi bị compromise.

7. Migrate

Sau khi viết bài này, bạn @vanhtuan0409 có một câu hỏi về việc làm thế nào migrate một hệ thống dùng SHA1 --> bcrypt. Mình thấy đây là một điểm cũng khá cần thiết nên xin phép note thêm.
Ở đây có 2 trường hợp:
  • Hash password bằng SHA1 nhưng không có salt -> mình gọi là sha1_value.
  • Hash password bằng SHA1 + trong DB có salt-per-user, mình có sha1_value, salt.
Về ý tưởng thì ta sẽ dùng SHA1 như cách Dropbox dùng SHA512 để cố định độ dài input.
Với trường hợp đầu ta cần sinh ra thêm salt-per-user và migrate bcrypt(salt, sha1_value) trong đó sha1_value = SHA1(password) -> Tương tự cách của dropbox, may mắn là do sai thiết kế từ đầu (thiếu salt) nên migrate dễ.
Với trường hợp thứ 2 thì hơi lằng nhằng hơn 1 xíu, ta cần migrate kiểu bcrypt(salt, SHA1(salt, password))nếu thực sự muốn bcrypt với salt hoặc thực ra chỉ cần bcrypt(SHA1(salt, password) cũng được. Tùy tình huống bạn cần tradeoff có thể lựa chọn cách phù hợp.

8. Thông tin của bạn có an toàn?

Như ta thấy, ta đã làm rất nhiều thứ để đảm bảo rằng thông tin của chúng ta trở lên an toàn. Vậy thực sự thông tin của chúng ta đã an toàn hay không? Câu trả lời rất tiếc là KHÔNG? Thông tin của chúng ta có thể an toàn với "bên ngoài" nhưng không an toàn với "bên trong". Tại sao lại vậy?
Giờ bắt đầu với thông tin cơ bản nhất như địa chỉ, email, sở thích ... Khi ta build staing environment, thông tin user được copy sang một môi trường khác, developer có thể overwrite hash_value của user bằng value của hash(salt + 654321) và dễ dàng đăng nhập trên staing environment với password là 654321 và tất cả các thông tin cơ bản của user đã có thể đọc được. Nhưng developer vẫn không biết chính xác password của user là gì.
Nhưng, lại là nhưng. Người quản trị hệ thống có mọi quyền trên server mà họ quản trị, password dù đã over HTTPs nhưng tới server vẫn là plain-text. Vẫn có thể capture request ngay ở đầu server và output ra plain-text password của user và cuối cùng thì người quản trị hệ thống vẫn biết được chính xác password của user là gì. Đó là lí do tại sao ta không nên dùng một password cho tất cả các dịch vụ.
Vậy làm thế nào để bảo vệ info của user trong trường hợp này, rất tiếc về mặt kỹ thuật không có cách nào để đảm bảo việc này. Ta chỉ có thể áp dụng policy, NDA về mặt con người để hạn chế vấn đề này thôi.

9. Ref

Lưu ý:

  • Trong bài viết dùng MD5 để minh họa cho đơn giản, trong thực tế ta không dùng MD5.
  • Trong bài viết giả định kẻ tấn công bằng cách nào đó có db users, trong thực tế việc này rất khó do có các tầng bảo mật khác như thiết kế infrastructure, define rule/policy về con người ... Trong bài này mình không bàn đến các vấn đề đó.

Mai Viên IT

.

© 2018 www.maivienit.com

Khu Công nghệ cao Hòa Lạc – Km29 Đại lộ Thăng Long, Thạch Thất, TP. Hà Nội
Email: maivienit@gmail.com
Điện thoại: 0973 983 546 ; Liên hệ quảng cáo: 01299 725 789.