2012-03-30 55 views
6

Tôi cần làm việc với ổ cắm TCP trên TLS cho ứng dụng tôi đang làm việc. Tôi đã trải qua hàng chục ví dụ và trong khi tôi không gặp vấn đề gì trong việc bắt tay, tôi dường như không đọc luồng đầu vào thông qua bất kỳ phương tiện nào (đã thử nhiều, bao gồm readline(), đọc tới mảng ký tự, v.v.). mỗi khi tôi thử, ứng dụng bị đóng băng tại chỗ đó. Nếu tôi gỡ lỗi, nó không bao giờ đi đến dòng mã tiếp theo.Ví dụ về Android SSLEngine

Trong một giải pháp đã cố gắng, tôi quyết định chuyển sang sử dụng SSLEngine, vì đó được cho là câu trả lời Java 1.5 cho java.nio cho SSL. Tuy nhiên, tôi đã tìm thấy một ví dụ (ở đây: http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/samples/sslengine/SSLEngineSimpleDemo.java) điều này khiến tôi hơi bối rối và tôi đã không triển khai thành công nó. Khi tôi thử, hàm unrap() tạo ra một bộ đệm trống, nơi mà tôi biết (từ việc sử dụng OpenSSL trên dòng lệnh) rằng dịch vụ được đề cập sẽ đẩy dữ liệu xuống đường ống.

Đề xuất được hoan nghênh, tôi đã đốt cháy quá nhiều thời gian cho việc này rồi. Dưới đây là các mã có liên quan:

SSLEngine engine = sslContext.createSSLEngine(uri.getHost(), uri.getPort()); 
      engine.setUseClientMode(true); 
      engine.beginHandshake(); 
      SSLSession session = engine.getSession(); 
      int bufferMax = session.getPacketBufferSize(); 
      int appBufferMax = session.getApplicationBufferSize() + 50; 
      ByteBuffer cTo = ByteBuffer.allocateDirect(bufferMax); 
      ByteBuffer sTo = ByteBuffer.allocateDirect(bufferMax); 

      ByteBuffer out = ByteBuffer.wrap(sessionId.getBytes()); 
      ByteBuffer in = ByteBuffer.allocate(appBufferMax); 


      debug("sending secret"); 
      SSLEngineResult rslt = engine.wrap(out, cTo); 
      debug("first result: " + rslt.toString()); 
      sTo.flip(); 
      rslt = engine.unwrap(sTo, in); 
      debug("next result" + rslt.toString()); 
+0

Là bản cập nhật, tôi cũng đã thử lặp lại cuộc gọi không mong muốn trong khi (rslt.getStatus()! = SSLEngineResult.Status.OK) và không bao giờ được điền, và trạng thái không bao giờ trở thành OK. – Paul

+0

Bạn đã thử chạy mã này trong một ứng dụng Java thông thường chưa? Điều đó ít nhất sẽ giúp xác định xem một vấn đề cụ thể của nó cho Android hay không. – elevine

+0

Vâng, tôi không nghĩ rằng nó dành riêng cho android, tôi chỉ tình cờ làm việc đó trong một dự án android. – Paul

Trả lời

1

thi này thiếu một số phần quan trọng. Cụ thể là việc bắt tay có thể bị trả lại giữa một số tiểu bang NEED_WRAP, NEED_UNWRAP, NEED_TASK để thương lượng một kết nối. Điều này có nghĩa là bạn không thể chỉ gọi một cái và cái kia. Bạn sẽ cần phải lặp lại các trạng thái cho đến khi bắt tay đã hoàn thành.

while (handshaking) { 
     switch (state) { 
      case NEED_WRAP: 
       doWrap(); 
       break; 
      case NEED_UNWRAP: 
       doUnwrap(); 
       break; 
      case NEED_TASK: 
       doTask(); 
       break; 
     } 
    } 

A full working example of Java SSL and NIO

Bây giờ mà nói, bạn nên lưu ý các SSLEngine trên Android is broken. Google khuyên bạn nên sử dụng các chủ đề và chặn các ổ cắm theo chủ đề đó.

0

unwrap() có thể mang lại một bộ đệm trống nếu những gì đã tháo được một thông báo SSL handshake hoặc cảnh báo, chứ không phải là dữ liệu ứng dụng. Không có đủ thông tin ở đây để nói thêm. Tình trạng động cơ sau đó là gì?

0

beginHandshake không tiến hành bắt tay, nó chỉ được sử dụng để thông báo cho SSLEngine mà bạn muốn thực hiện bắt tay cho các cuộc gọi tiếp theo để gói/unwrap. Rất hữu ích khi bạn muốn thực hiện một cái bắt tay khác. Đối với cái đầu tiên, nó không cần thiết vì cuộc gọi đầu tiên để bọc sẽ bắt đầu cái bắt tay.

Bên cạnh đó, bạn phải kiểm tra kết quả của phương pháp bọc và unwrap để biết liệu tất cả dữ liệu đã được mã hóa chính xác hay chưa. Nó có thể xảy ra mà bạn phải gọi các phương thức nhiều lần để xử lý tất cả dữ liệu.

Các liên kết sau đây có thể giúp: http://onjava.com/onjava/2004/11/03/ssl-nio.html

Hoặc câu hỏi này: SSL Handshaking Using Self-Signed Certs and SSLEngine (JSSE)

0

Tôi đã viết một cái gì đó để làm cho việc sử dụng SSLEngine dễ dàng hơn. Nó có thể được sử dụng với NIO hoặc cho các trường hợp sử dụng khác. Available here SSLFacade