Hướng dẫn mã hóa password trong lập trình c năm 2024

Trong quá trình phát triển ứng dụng việc bảo vệ nội dung các file cấu hình là rất cần thiết, trong bài này tôi giới thiệu với các bạn một đoạn code nhỏ giúp mã hóa và giải mã có sử dụng mật khẩu để mã hóa.

Khai báo mật khẩu như sau:

string key = "2giotoitaigoccayda"; Viết hàm sau để mã hóa:

///

    /// Mã hóa chuỗi có mật khẩu  
    /// 
/// Chuỗi cần mã hóa /// Chuỗi đã mã hóa public static string Encrypt(string toEncrypt) { bool useHashing = true; byte[] keyArray; byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } Hàm sau đây để phục hồi dữ liệu:

///

    /// Giản mã  
    /// 
/// Chuỗi đã mã hóa /// Chuỗi giản mã public static string Decrypt(string toDecrypt) { bool useHashing = true; byte[] keyArray; byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return UTF8Encoding.UTF8.GetString(resultArray); } Sử dụng 2 hàm này như sau:

string chuoimahoa = Encrypt("abc"); ...... string chuoigiaima = Decrypt(chuoimahoa); Hi vọng sẽ hữu ích với bạn.

CodeLearn is an online platform that helps users to learn, practice coding skills and join the online coding contests.

Links

Learning

Training

Fights

Information

About Us

Terms of Use

Help

Help

Discussion

Powered by CodeLearn © 2024. All Rights Reserved. rev 2/5/2024 5:31:56 PM

Mã hóa và lưu trữ password là việc làm rất quen thuộc với các lập trình viên. Tuy nhiên hiểu nó một cách tường tận sẽ giúp chúng ta hiểu và thực hiện bảo vệ các thông tin password của hệ thống một cách tốt nhất.

Bài viết nhằm cung cấp một vài kiến thức cơ bản giúp người mới lập trình hiểu để có thể thực hiện việc mã hóa và lưu trữ mật mã (password). Thực tế, có lẽ có 4 cấp độ lập trình viên thực hiện việc này lần lượt như sau:

Cấp độ 1: Ngây thơ

Với những lập trình viên mới bắt đầu lập trình (web nói riêng), nhiều người sẽ lưu trữ mật mã (password) ở dạng plain-text. Có nghĩa người dùng đăng kí với mật mã là ‘123456’ thì cột mật mã trong bảng người dùng cũng lưu là ‘123456’. Thực tế ứng dụng vẫn chạy ổn định. Tuy nhiên, vấn đề là ở chỗ nếu một ai đó truy xuất được vào cơ sở dữ liệu – hacker chẳng hạn – sẽ thấy được mật mã này và thực hiện đăng nhập một cách thoải mái mà không ai biết. Trước đây, ngay cả Samsung cũng gặp phải lỗi rất ư ngây thơ này.

Nếu là một ứng dụng web, khi triển khai lên hosting, dĩ nhiên người cho thuê hosting có quyền truy cập vào CSDL của bạn và dễ dàng lấy được mật khẩu người dùng mà chẳng cần cực nhọc gì.

Cấp độ 2: Sử dụng hàm băm

Ở cấp độ này, developer sử dụng một hàm băm được hỗ trợ của hệ quản trị CSDL để mã hóa chuỗi mật khẩu ban đầu thành một chuỗi được mã hóa sau đó mới lưu vào cơ sở dữ liệu. Ví dụ ‘123456’ khi mã hóa dùng MD5 sẽ cho ra kết quả là ‘e10adc3949ba59abbe56e057f20f883e’ và chuỗi kết quả này này được lưu vào cơ sở dữ liệu.

Hiện nay, các hệ quản trị CSDL đều hỗ trợ việc thực hiện mã hóa bằng các thuật toán băm phổ biến như MD5, SHA1, SHA2…Các hàm băm có đặc điểm là các hàm 1 chiều. Dữ lệu sau khi mã hóa không thể giải mã thành dữ liệu ban đầu được.

Ok, vậy là giải quyết được vấn đề lộ thông tin. Dù ai đó có kiểm soát được cơ sở dữ liệu đi nữa cũng không biết mật mã của người dùng là gì.

Vậy ổn chưa? Câu trả lời là chưa. Hàm băm không thể dịch ngược, tuy nhiên có thể dò tìm thông qua thuật toán vét cạn. Như các bạn biết, người dùng thường sẽ sử dụng một mật mã dễ nhớ dạng như ‘123456’ hay ‘000000’…, các hacker biết điều này và sẽ lập một danh sách các mật khẩu phổ biến nhất (weak password dictionary) sau đó dùng danh sách này để thử sai và dò ra mật mã ban đầu. Như vậy các hàm băm cũng chỉ làm khó cho hacker thêm 1 chút xíu mà thôi.

Cấp độ 3: Dùng salt khắc phục weak password

Người dùng có thể chọn một mật khẩu yếu, đó là chuyện bình thường. Tuy nhiên, là người xây dựng hệ thống các bạn cần phải khắc phục điều này. Giải pháp là sử dụng thêm một chuỗi mà thường được gọi là salt.

Hiểu đơn giản như thế này, trong cấu hình của ứng dụng các bạn lưu trữ một chuỗi (phức tạp dài dòng) và chuỗi này sẽ được gọi là salt. Trước khi lưu trữ mật mã vào cơ sở dữ liệu chúng ta thực hiện việc kết hợp salt với mật mã. Có nhiều kiểu kết hợp khác nhau, đơn giản nhất như nối chúng lại (ví dụ với PHP):

$crypPassword= md5($rawPassword.$salt);

Và rồi chúng ta lưu mật mã mới này vào cơ sở dữ liệu. Khi đó, dù ai đó có toàn bộ dữ liệu của chúng ta cũng không dễ dàng để dò ra mật khẩu dựa vào weak password dictionary được.

Cấp độ 4: Chuỗi salt duy nhất cho mỗi password

Chúng ta đã đi khá xa trong chủ đề này, tuy nhiên vẫn còn có thể làm cho hệ thống tốt hơn bằng việc sử dụng salt duy nhất cho mỗi mật mã.

Thông thường hệ thống sẽ có hàng vạn thành viên, và việc các thành viên dùng mật khẩu giống nhau là phổ biến. Hãy đặt tình huống hacker có cả hai thông tin là dữ liệu và salt. Nếu chúng ta đã sử dụng một salt duy nhất, khi ấy tất cả các tài khoản có chung mật mã thì mật mã được mã hóa (crypPassword) đều sẽ giống nhau. Kẻ tấn công sẽ chỉ cần brute force một trong số đó là cũng có các tài khoản còn lại mà không tốn thêm công sức gì. Để tránh rủi ro này và làm tăng thêm khó khăn cho kẻ tấn công, hệ thống nên sử dụng các salt duy nhất cho mỗi mật mã. Lúc ấy, mỗi crypPassword sẽ là khác nhau (dù rawPassword giống nhau) và tất nhiên hacker sẽ không có được danh sách các tài khoản có mật mã giống nhau. Hacker sẽ phải brute force từng tài khoản một.

Có nhiều giải pháp để tạo salt độc nhất. Việc này sẽ dễ dàng nếu bạn có kiến thức về các hàm entropy trong ngôn ngữ lập trình đang dùng.

Nói thêm về các hàm băm

Hàm băm ngoài ứng dụng trong việc mã hóa thông điệp 1 chiều như trên còn có nhiều ứng dụng trong các lĩnh vực khác như chứng thực thông điệp, chứng chỉ số, chữ kí số…. và nếu là lập trình viên tốt chắc chắn bạn cũng biết cách sử dụng các hash-map trong lập trình để giảm thời gian thực thi khi xử lý các khối chuỗi kích thước lớn.

Cho tới thời điểm năm 2005 thì các hàm băm dùng phổ biến như MD5, SHA1 đều đã bị tấn công và không còn an toàn nữa.

Tới thời điểm hiện tại (2014), hàm băm SHA2 vẫn còn an toàn và chưa thể bị tấn công kể cả về mặt lý thuyết (chứ chưa nói đến thực hiện).

Ngay từ năm 2007. Viện Tiêu chuẩn và công nghệ Hoa Kì (NIST) đã tổ chức một cuộc thi để tìm ra thuật toán băm thế hệ tiếp theo. Ngày 02/10/2012 thuật toán Keccak (có tác giả là người từng tạo ra AES) đã được chọn đạt giải cao nhất. Các bạn có thể tham khảo thêm ở link này

Kết luận

Bài viết đề cập một cách tổng quát cách thức để bảo vệ tốt nhất thông tin mật mã (password) của người dùng cho các ứng dụng nói chung và ứng dụng web nói riêng.

Nếu bạn ở cấp độ dưới 3 chắc chắn các bạn còn rất nhiều điều phải học để trở thành một lâp trình viên giỏi. Và hi vọng bài viết này giúp ích được các bạn một chút trong việc mở rộng thêm kiến thức của bản thân.