2009-05-19 33 views
24

Vì vậy, sau CodingHorror's fun with encryption và các nhận xét về việc đánh đập, chúng tôi đang xem xét lại việc thực hiện mã hóa riêng của mình.Làm cách nào để bắt đầu sử dụng BouncyCastle?

Trong trường hợp này, chúng tôi cần chuyển một số thông tin xác định người dùng đến dịch vụ của bên thứ 3, sau đó sẽ gọi lại dịch vụ trên trang web của chúng tôi cùng với thông tin cộng với băm.

Dịch vụ thứ hai tra cứu thông tin về người dùng đó và sau đó chuyển nó trở lại dịch vụ của bên thứ 3.

Chúng tôi muốn mã hóa thông tin người dùng này đi vào dịch vụ của bên thứ 3 và giải mã nó sau khi nó xuất hiện. Vì vậy, nó không phải là một mã hóa lâu dài.

Trên bài viết kinh dị mã hóa, Coda Hale đề xuất BouncyCastle và một sự trừu tượng mức cao trong thư viện để thực hiện việc mã hóa cụ thể cho một nhu cầu cụ thể.

Vấn đề của tôi là các không gian tên BouncyCastle rất lớn và tài liệu không tồn tại. Bất cứ ai có thể chỉ cho tôi thư viện trừu tượng mức cao này? (Hoặc một tùy chọn khác ngoài BouncyCastle?)

+5

xem xét lại văn bản lib mã hóa riêng của bạn? Sự lựa chọn tốt! – Cheeso

+0

Mặc dù không có nhiều tài liệu với BouncyCastle, tôi thấy danh sách gửi thư của họ rất hữu ích http://www.bouncycastle.org/csharpdevmailarchive/index.html. Bạn cũng có thể đăng ký để đặt câu hỏi. Bạn cũng nên lấy mã nguồn đi kèm với các ví dụ và kiểm tra, bao gồm hầu hết các trường hợp sử dụng. – Emmanuel

+0

Bạn đang mô tả những âm thanh như trường hợp sử dụng điển hình cho OAuth - bạn đã cân nhắc sử dụng điều đó chưa? –

Trả lời

10

Trừu tượng mức cao? Tôi cho rằng trừu tượng mức cao nhất trong các thư viện Bouncy Castle sẽ bao gồm:

Tôi gần như quen thuộc với phiên bản Java của thư viện. Có lẽ đoạn mã này sẽ cung cấp cho bạn một sự trừu tượng đủ cao cho mục đích của bạn (ví dụ đang sử dụng mã hóa AES-256):

public byte[] encryptAES256(byte[] input, byte[] key) throws InvalidCipherTextException { 
    assert key.length == 32; // 32 bytes == 256 bits 
    CipherParameters cipherParameters = new KeyParameter(key); 

    /* 
    * A full list of BlockCiphers can be found at http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/BlockCipher.html 
    */ 
    BlockCipher blockCipher = new AESEngine(); 

    /* 
    * Paddings available (http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/paddings/BlockCipherPadding.html): 
    * - ISO10126d2Padding 
    * - ISO7816d4Padding 
    * - PKCS7Padding 
    * - TBCPadding 
    * - X923Padding 
    * - ZeroBytePadding 
    */ 
    BlockCipherPadding blockCipherPadding = new ZeroBytePadding(); 

    BufferedBlockCipher bufferedBlockCipher = new PaddedBufferedBlockCipher(blockCipher, blockCipherPadding); 

    return encrypt(input, bufferedBlockCipher, cipherParameters); 
} 

public byte[] encrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException { 
    boolean forEncryption = true; 
    return process(input, bufferedBlockCipher, cipherParameters, forEncryption); 
} 

public byte[] decrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException { 
    boolean forEncryption = false; 
    return process(input, bufferedBlockCipher, cipherParameters, forEncryption); 
} 

public byte[] process(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters, boolean forEncryption) throws InvalidCipherTextException { 
    bufferedBlockCipher.init(forEncryption, cipherParameters); 

    int inputOffset = 0; 
    int inputLength = input.length; 

    int maximumOutputLength = bufferedBlockCipher.getOutputSize(inputLength); 
    byte[] output = new byte[maximumOutputLength]; 
    int outputOffset = 0; 
    int outputLength = 0; 

    int bytesProcessed; 

    bytesProcessed = bufferedBlockCipher.processBytes(
      input, inputOffset, inputLength, 
      output, outputOffset 
     ); 
    outputOffset += bytesProcessed; 
    outputLength += bytesProcessed; 

    bytesProcessed = bufferedBlockCipher.doFinal(output, outputOffset); 
    outputOffset += bytesProcessed; 
    outputLength += bytesProcessed; 

    if (outputLength == output.length) { 
     return output; 
    } else { 
     byte[] truncatedOutput = new byte[outputLength]; 
     System.arraycopy(
       output, 0, 
       truncatedOutput, 0, 
       outputLength 
      ); 
     return truncatedOutput; 
    } 
} 

Sửa: Rất tiếc, tôi chỉ đọc bài viết bạn liên kết đến. Nghe có vẻ như anh ấy đang nói về sự trừu tượng cấp cao hơn tôi nghĩ (ví dụ: "gửi một thông điệp bí mật"). Tôi sợ tôi không hoàn toàn hiểu những gì anh ta đang nhận được.

+0

Cảm ơn bạn đã xem bài viết ... sẽ rất tuyệt khi có thư viện giống như những gì anh ấy mô tả là cách sử dụng để mã hóa rất nhiều và lạm dụng thậm chí là lớn hơn. –

+0

+1 cho nỗ lực nhưng không thực sự là một câu trả lời tôi có thể sử dụng. –

+0

Adam Paynter cũng có một cái nhìn vào câu hỏi của tôi. Tôi chỉ muốn mã hóa văn bản bằng chcacha20. http://stackoverflow.com/questions/38050559/illegalargumentexception-chacha20-requires-128-bit-or-256-bit-key – Nepster

3

Giả sử bạn viết ứng dụng của mình bằng Java Tôi khuyên bạn không nên sử dụng một nhà cung cấp cụ thể, nhưng bạn phát triển ứng dụng của mình trên JCE của Sun (Tiện ích mã hóa Java). Làm như vậy có thể làm cho bạn độc lập với bất kỳ nhà cung cấp cơ bản nào, tức là bạn có thể chuyển đổi nhà cung cấp dễ dàng miễn là bạn sử dụng mật mã được triển khai rộng rãi. Nó cung cấp cho bạn một mức trừu tượng nhất định vì bạn không phải biết tất cả các chi tiết của việc triển khai và có thể bảo vệ bạn một chút từ việc sử dụng các lớp sai (ví dụ như sử dụng mã hóa thô mà không có đệm thích hợp). một số lượng lớn tài liệu và mẫu mã.

0

JCE sẽ không hoạt động đối với tôi vì chúng tôi muốn có cường độ 256 bit và không thể thay đổi cấu hình java trên hệ thống để cho phép. Quá xấu Lâu đài Bouncy không có API cao cấp như JCE.

"Tuy nhiên, lưu ý rằng bouncycastle bao gồm hai thư viện, thư viện mật mã nhẹ và thư viện giao diện nhà cung cấp JCE. Các hạn chế về khóa được thực thi bởi lớp JCE, nhưng bạn không cần sử dụng lớp này.Nếu bạn chỉ cần sử dụng mật mã API nhẹ trực tiếp bạn không có bất kỳ hạn chế, không có vấn đề gì các file chính sách được hoặc không được cài đặt." http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography

+0

Tôi muốn bỏ yêu cầu 256 bit so với khả năng sử dụng giao diện cấp cao và khả năng chuyển đổi nhà cung cấp dễ dàng. Tôi không phải là fan của thư viện bouncycastle, vì nó có quá nhiều sai sót đối với khẩu vị của tôi. Do đó ngay cả khi tôi muốn sử dụng bouncycastle trong quá trình phát triển, tôi muốn có thể chuyển đổi nó cho một cái gì đó tốt hơn khi mã của tôi đi vào sản xuất. Tính linh hoạt là một khía cạnh quan trọng khi thiết kế một ứng dụng mã hóa. Khóa xuống một nhà cung cấp hoặc tập hợp các nguyên thủy crypto có thể làm tổn thương bạn rất nhiều. – Accipitridae

1

tôi đã thực sự phát hiện ra rằng mẫu này sử dụng mã hóa mặc định 128 bit thay vì 256 bit tôi đã thực hiện một chút thay đổi:.

BlockCipher blockCipher = new AESEngine(); 

lúc này là:

BlockCipher blockCipher = new RijndaelEngine(256); 

và nó hoạt động cùng với ứng dụng của tôi client C++ AES256 mã hóa

2

Một ví dụ về một cao (er) API -level trong BouncyCastle sẽ là CMS (Cryptographic Message Syntax) gói. Điều này tàu trong một jar riêng biệt (bcmail) từ nhà cung cấp chính nó, và được ghi vào JCE (Phiên bản C# được viết với API nhẹ tuy nhiên).

"Gửi tin nhắn bí mật" được thực hiện, gần bằng lớp CMSEnvelopedDataGenerator và tất cả những gì bạn thực sự cần làm là cung cấp tin nhắn, chọn thuật toán mã hóa (tất cả chi tiết được xử lý nội bộ) và sau đó chỉ định một hoặc nhiều cách để người nhận có thể đọc tin nhắn: điều này có thể dựa trên khóa công khai/chứng chỉ, bí mật được chia sẻ, mật khẩu hoặc thậm chí là giao thức thỏa thuận khóa. Bạn có thể có nhiều người nhận trên một tin nhắn và bạn có thể kết hợp và kết hợp các loại người nhận.

Bạn có thể sử dụng CMSSignedDataGenerator để gửi thư xác minh tương tự. Nếu bạn muốn đăng nhập và mã hóa, cấu trúc CMS có thể lồng ghép/có thể gộp (nhưng thứ tự có thể là quan trọng). Ngoài ra còn có CMSCompressedDataGenerator và gần đây đã thêm CMSAuthenticatedData.

1

Bạn có thể sử dụng:

byte[] process(bool encrypt, byte[] input, byte[] key) 
{ 
    var cipher = CipherUtilities.GetCipher("Blowfish"); 
    cipher.Init(false, new KeyParameter(key)); 
    return cipher.DoFinal(input); 
} 

// Encrypt: 
byte[] encrypted = process(true, clear, key); 

// Decrypt: 
byte[] decrypted = process(false, encrypted, key); 

Xem: https://github.com/wernight/decrypt-toolbox/blob/master/dtDecrypt/Program.cs

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