2012-11-13 42 views
5

Tôi đang cố gắng mã hóa dữ liệu của mình bằng thuật toán AES với chế độ CBC. Vì lý do này tôi sử dụng .Net Library 'Bouncy Castle'. Tôi không có nền tảng về mật mã, vì vậy tôi đang cố gắng sử dụng nó một cách đơn giản. Đây là mã mã hóa của tôicách xóa dữ liệu trước khi mã hóa bằng bouncyCastle

public byte[] encrypt(byte[] key, byte[] iv,byte[] data) 
    { 
     IBlockCipher engine=new AesFastEngine(); 
     KeyParameter keyParam = new KeyParameter(key); 
     CbcBlockCipher cipher = new CbcBlockCipher(engine); 

     ICipherParameters parameters = new ParametersWithIV(keyParam, iv); 

     byte[] output=new byte[16+data.Length]; 
     cipher.Init(true, parameters); 
     cipher.ProcessBlock(data, 0, output, data.Length); 

     //process output 
     byte[] cipherArray = new byte[data.Length]; 
     /* 
     int k=0; 
     for (int i = 0; i < output.Length; i++) 
     { 
      if (output[i]!= 0) 
      { 
       cipherArray[k++] = output[i]; 
      } 
     } 
     */ 
     return cipherArray; 

    } 

Khi tôi thử đầu vào không phải là bội số 16, tôi có ngoại lệ. Khi tôi pad mảng bên phải với một số (16-length% 16) với số không ở bên trái, tôi có thể nhận được kết quả. Nhưng kết quả là một vấn đề đối với tôi. Nó mang lại cho tôi kết quả như sau:

[0][0][0][0[111][22][33][44][66][77][33][12][32][23][0][0][0][0][0] 

số 0 ở cả bên trái và bên phải.

Tôi nghĩ có thể là do tôi sử dụng chức năng ProcessBlock(data, 0, output, data.Length). Tôi sử dụng nó với giả định rằng đầu ra sẽ là văn bản được mã hóa của tôi, nhưng có vẻ như đầu ra phải dài hơn độ dài đầu vào. vì tôi không có tài liệu về chức năng này, tôi có thể đang sử dụng nó theo cách sai. Mọi trợ giúp sẽ là ứng dụng

Trả lời

4

Bouncy Castle sẽ làm đệm cho bạn, để bắt đầu bạn cần phải thiết lập cihper của bạn như:

PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding()); 

Đối với phần còn lại của mã của bạn để làm việc sẽ cần phải sử dụng cipher.GetOutputSize(data.Length)ProcessBytesDoFinal nên đệm được thêm chính xác.

byte[] output = new byte[cipher.GetOutputSize(data.Length)]; 
int len = cipher.ProcessBytes(data, 0, data.Length, output, 0); 
cipher.DoFinal(output, len); 

Tôi có một ví dụ đơn giản về sử dụng AES-GCM in Bouncy Castle on CodeReview

AES-GCM cho biết thêm chứng thực mã hóa, nhưng nguyên tắc cơ bản của việc sử dụng api là như nhau.

Tôi cũng có một C# cảng khung mã hóa cao cấp, Kecyzar, mà tôi sử dụng Bouncy Castle như là phụ trợ, mặc dù nó là một ví dụ khó khăn hơn, các trừu tượng đang mã hóa SymmetricStream được thiết lập cho việc sử dụng AES-CBC trong BouncyAesKey

+0

cảm ơn bạn jbtule, nhưng tôi có một vấn đề với patter này khi tôi cố gắng sử dụng paddedCipher.DoFinal (đầu ra, len); nó ném một ngoại lệ "khối cuối cùng không đầy đủ trong decription", processBytes phương pháp trả về một giá trị đó là một phép nhân của 16 đó là nhỏ hơn chiều dài dữ liệu, bạn sẽ biết những gì gây ra vấn đề này? cảm ơn – ikbal

+0

@paskalnikov Tôi đã thêm nhiều mã hơn để hiển thị cách sử dụng.'ProcessBytes' sẽ xuất byte cho mỗi khối hoàn chỉnh và giữ phần còn lại đệm (bạn cũng có thể gọi 'ProcessBytes' nhiều lần bạn muốn cho nó một phần dữ liệu cùng một lúc), nó sẽ không giả sử bạn đã hoàn thành cho đến khi bạn gọi 'DoFinal', và sau đó' DoFinal' sẽ ghi ra các byte cuối cùng (với padding), vì vậy nếu bạn có 'DoFinal' ghi vào mảng đầu ra cuối cùng của bạn, bạn cần cung cấp cho nó chỉ mục của nó sẽ ghi vào đâu mảng. – jbtule

2

Thông thường, người dùng sẽ sử dụng thuật toán đệm tiêu chuẩn để đảm bảo dữ liệu văn bản thuần được căn chỉnh với kích thước khối cho một mật mã.

Bạn hiện đang viết tay zero padding. Đây không phải là một lựa chọn tuyệt vời vì nó cấm dữ liệu ban đầu kết thúc bằng một byte không - làm thế nào bạn có thể phân biệt được từ phần đệm?

Tôi khuyên bạn nên sử dụng đệm tiêu chuẩn, chẳng hạn như PKCS #7 padding. Lưu ý rằng điều này thường được gọi là "PKCS # 5 padding", vì chúng rất giống nhau.

Bạn có thể tham khảo câu hỏi SO khác - Encrypt/Decrypt using Bouncy Castle in C# - để biết ví dụ về cách sử dụng đệm tiêu chuẩn.

Các vấn đề liên quan