2010-06-10 47 views
6

Tôi khá mới trong lập trình. Tôi đã viết mã bên dưới để nhắc người dùng mật khẩu mã hóa tệp, Nhưng nó chỉ hoạt động khi độ dài của mật khẩu là 8, Tôi có thể làm gì để chấp nhận bất kỳ số ký tự nào cho mật khẩu?Mã hóa bằng rijndael

string pass = textBox2.Text.ToString(); 
      string password = @"" + pass + ""; 
      UnicodeEncoding UE = new UnicodeEncoding(); 
      byte[] key = UE.GetBytes(password); 


      FileStream fsCrypt = new FileStream(@"c:\\users\\new", FileMode.Create); 
      name = fsCrypt.Name; 
      RijndaelManaged RMCrypto = new RijndaelManaged(); 

      CryptoStream cs = new CryptoStream(fsCrypt, 
       RMCrypto.CreateEncryptor(key, key), 
       CryptoStreamMode.Write); 

      FileStream fsIn = new FileStream(filename, FileMode.Open); 

      int data; 
      while ((data = fsIn.ReadByte()) != -1) 
       cs.WriteByte((byte)data); 
+0

tôi một chút bối rối bởi dòng: mật khẩu string = @ "" + vượt qua + ""; những gì bạn đang cố gắng để đạt được bằng cách tham gia một chuỗi emtpy vào mỗi đầu của một chuỗi, dẫn đến một chuỗi giống hệt nhau. –

Trả lời

1

Nhận trực tiếp Biểu mẫu khóa mật khẩu của bạn với Encoding.GetBytes() sẽ chỉ hoạt động nếu kết quả của GetBytes() là một KeySize hợp pháp.

Quan trọng hơn, nó tạo ra một khóa rất yếu, đặc biệt khi bạn chọn mã hóa Unicode. Mẫu byte trong khóa của bạn cho "foobar" là 66 00 6F 00 6F 00 62 00 61 00 72 00. Bạn có thấy tất cả 00 byte không?

Cách chính thức là sử dụng lớp Rfc2898DeriveBytes. Ngoài ra nó có lẽ không phải là một ý tưởng tốt để sử dụng Key như IV, tôi không hoàn toàn chắc chắn về điều này.

Đồng thời xem this SO question.

+0

Nhờ đề cập đến nó, vâng bạn đã đúng, nó đã biến mất. – Mohammad

+0

Sử dụng lại khóa như IV thực sự là một ý tưởng tồi. Tôi đã viết về nó ở đây: http://crazyscot.livejournal.com/304065.html – crazyscot

+0

@crazyscot: Có, thx cho các liên kết. Nhưng lưu ý rằng nó có phần chấp nhận được để mã hóa các chuỗi ngắn trong khi tránh chi phí vận chuyển muối và IV. Nhưng nó phải được đánh dấu rõ ràng và hiểu là yếu. –

2

Bạn cần một chức năng có nghĩa là sẽ có được một chiều dài khóa hợp lệ cho Rijndael từ mật khẩu của bạn, và vào lúc này, việc bạn sử dụng UnicodeEncoding.GetBytes chỉ sẽ cung cấp cho này đối với một số độ dài rời rạc của mật khẩu, như bạn đã khám phá ra.

Bạn nên sử dụng chức năng khác để lấy khóa từ mật khẩu của mình - có thể lấy mảng byte bạn đã tạo và chạy hàm băm mật mã như SHA1 trên đó. SHA1 sẽ cung cấp cho bạn một chiều dài 128 bit, giống như mật khẩu 8 ký tự của bạn hiện đang làm, nhưng bất kể độ dài của mật khẩu.

+0

Hãy để tôi thấy tôi đã làm đúng không? Bạn có nghĩa là tôi nên có một giá trị băm của mật khẩu (mà chắc chắn là đủ dài) và sau đó vượt qua đó là chìa khóa? – Mohammad

+0

@user ####: Có. –

0

Check-out PasswordDeriveBytes

http://msdn.microsoft.com/en-us/library/system.security.cryptography.passwordderivebytes(v=VS.100).aspx

Bạn sẽ cần một giá trị muối cố định cũng như thông qua, điều này ngăn chặn người ta làm việc ra các mật khẩu từ các thuật toán.

Nó được sử dụng như thế này cho TripleDES và nên dễ sửa đổi cho Rijndael:

// Create a TripleDESCryptoServiceProvider object. 
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); 

// Create a PasswordDeriveBytes object and then create 
// a TripleDES key from the password and salt. 
PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwd, salt); 


// Create the key and set it to the Key property 
// of the TripleDESCryptoServiceProvider object. 
tdes.Key = pdb.CryptDeriveKey("TripleDES", "SHA1", 192, tdes.IV);