Đồ án Secure Socket Layer

TLS tạo cách sử dụng hàm tạo số ngẫu nhiên dùng cho PRF để mở rộng các secret(phần bí mật) thành các khối dữ liệu cho mục đích sinh khóa hay phê chuẩn.Đối tượng là để tạo ra cách sử dụng các giá trị shared secret nhỏ có liên hệ với nhau, nhưng để phát sinh các khối dài hơn theo cách an toàn khỏi sự tấn công dựa trên hàm băm và MACx.PRF dựa trên hàm mở rộng dữ liệu sau:

pdf62 trang | Chia sẻ: maiphuongdc | Lượt xem: 2603 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Đồ án Secure Socket Layer, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
a: A(0)=seed A(i) =HMAC_hash(secret,A(i-1)) PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 24 Hàm mở rộng dữ liệu tạo cách sử dụng giải thuật HMAC, với hoặc MD5 hoặc SHA-1 như là trên cơ sở hàm băm.Như ta có thể thấy,P_hash có thể lặp đi lặp lại nhiều lần như sự cần thiết để tạo ra số lượng dữ liệu được yêu cầu.Ví dụ, nếu P_SHA-1 được dùng để sinh ra 64 byte dữ liệu,nó sẽ được lặp đi lặp lại 4 lần tạo ra 80 byte dữ liệu,mà 16 byte cuối bị loại bỏ.Trong trường hợp này,P_MD5 cũng sẽ được lặp lại 4 lần,tạo ra chính xác 64 bytes dữ liệu.Chú ý rằng mỗi lần lặp lại sẽ gọi 2 hàm thực thi HMAC, mỗi một cái sẽ quay sang gọi 2 hàm thực thi trên cơ sở giải thuật hàm băm. Để tạo ra PRF an toàn đến mức có thể,nó sử dụng 2 giải thuật băm theo cách mà sẽ đảm bảo sự an toàn của nó nếu giải thuật vẫn còn bảo mật.PRF được định nghĩa : hash(ClientHello.random || ServerHello.random || ServerParams) PRF lấy khi đầu vào một giá trị bí mật, một nhãn xác định, và một giá trị hạt giống(seed) và tạo ra một output có chiều dài tùy ý.Output được tạo bằng cách phân cắt giá trị bí mật thành hai nửa (S1 và S2 và biểu diễn P_hash ở mỗi nửa,sử dụng MD5 ở một nửa và SHA-1 ở nửa khác.Hai kết quả được thực hiện bởi phép XOR để tạo ra output, cho mục đích này,P_MD5 nhìn chung phải lặp lại nhiều lần hơn P_SHA-1 để tạo một lượng dữ liệu ngang bằng cho input bằng hàm XOR) I.8.4 Mã cảnh báo : TLS hỗ trợ tất cả các mã alert code được định nghĩa trong SSLv3 với ngoại lệ no_certificate. Một số các code thêm vào được định nghĩa trong TLS, sau đây là một số cảnh báo mức nguy hiểm:  decryption_failed : một cipher text được giải mã theo cách sai, hoặc nó không phải là phép nhân của chiều dài khối hoặc giá trị đệm của nó,khi kiểm tra là không đúng. PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 25  record_overflow:một TLS record được nhận với một payload(ciphertext) có chiều dài 214+2048 bytes, hoặc ciphertext được giải mã với chiều dài lớn hơn 214+1024 byte.  unknown_ca : một chuỗi certificate hợp lệ hoặc 1 phần chuỗi được nhận,nhưng certificate không được chấp nhận bởi vì CA certificate không thể được cấp phát hoặc không thể tạo ra kết nối với 1 CA hiểu biết,tin cậy.  access_defined: một certificate hợp lệ được nhận, vì khi access_control được thừa nhận, sender quyết định không thực thi với thỏa thuận.  decord_error : một thông điệp không thể được giải mã vì 1 trường bị thiếu range đặc biệt hoặc chiều dài của message không đúng.  export_restriction : một thỏa thuận không được chấp nhận với việc xuất ra các hạn chế trên chiều dài khóa bị phát hiện.  protocol_version: phiên bản giao thức mà client nỗ lực thỏa thuận được nhận thấy nhưng không hỗ trợ.  insufficient_security: trả về thay thế handshake_failure khi thỏa thuận bị thất bại 1 cách đặc biệt bởi vì server yêu cầu cipher nhiều bảo mật hơn những cái khác được hỗ trợ bởi client.  internal_error: một lỗi bên trong không liên hệ với cấp tương đương hoặc sự sửa lỗi của giao thức tạo ra không thể để tiếp tục. Phần còn lại của các cảnh báo mới bao gồm:  decrypt_error: toán hạng mã hóa bắt tay bị hư, bao gồm không thể xác minh 1 chữ kí,mã hóa 1 trao đổi khóa hay công nhận 1 thông điệp hoàn tất.  user_canceled: quá trình bắt tay này bị hoãn lại vì 1 số lí do không liên quan đến sự thất bại giao thức.  no_renegotiation: gửi đi bởi client trong phần đáp lại client hello sau khi thiết lập bắt tay.hoặc những thông điệp này sẽ có kết quả bình thường trong việc thỏa thuận lại,nhưng cảnh báo này chỉ ra rằng sender không thể thỏa thuận.Thông điệp này luôn luôn là 1 cảnh báo(warning). I.8.5 Cipher suite : Có nhiều sự khác nhau nhỏ giữa các cipher suite sẵn có dưới SSLv3 và dưới TLS:  Trao đổi khóa:TLS hỗ trợ tất cả các công nghệ trao đổi khóa của SSLv3 với ngoại lệ của Fortezza.  Các giải thuật mã hóa đối xứng:TLS bao gồm tất cả các giải thuật mã hóa đối xứng được tìm thấy trong SSLv3,với ngoại lệ của Fortezza. I.8.6 Các dạng client certificate : TLS định nghĩa cá kiểu certificate sau đây được yêu cầu trong thông điệp certificate_request:rsa_sign,dss_sign,rsa_fixed_dh, và dss_fixed_dh. Tất cả những kiểu này được định nghĩa trong SSLv3. Thêm vào đó,SSLv3 bao gồm rsa_ephemeral_dh, dss_ephemeral_dh và fortezza_kea. Ephemeral Diffie-Hellman bao gồm đánh dấu các tham số Difie-Hellman với hoặc RSA hoặc DSS, với TLS, rsa_sign và kiểu đánh dấu riêng không cần thiết để đánh dấu các tham số Diffie-Hellman.TLS không bao gồm hê thống Fortezza. PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 26 I.8.7 Certificate Verify và Finished Message : Trong thông điệp TLS_certificate_verify, mã băm MD5 và SHA-1 được tính toán chỉ trên các thông điệp bắt tay(handshake_message).Nhớ lại rằng SSLv3 tính toán hàm băm còn bao gồm master_secret và đệm.Các trường thêm vô này thất bại trong việc cộng thêm bảo mật không được thêm vào. Khi các thông điệp hoàn tất trong SSLv3, thông điệp kết thúc trong TLS là 1 mã băm dựa trên shared_master_secret, thông điệp bắt tay ở trước, và một nhãn xác định client hay server, việc tính toán có đôi chút khác biệt. Đối với TLS ta có: PRF(master_secret, finished_label, MD5(handshake_messages)|| SHA-1(handshake_messages)) Với finished_label là chuỗi “client_finished” đối với client và “server finished” đối với server. I.8.8 Tính toán mã hóa : Pre_master_secret đối với TLS được tính toán cùng 1 cách như trong SSLv3.Như trong SSLv3, master_secret trong TLS được tính toán như 1 hàm băm của pre_master_secret và hai số ngẫu nhiên hello.Công thức của phép tính toán TLS khác với công thức tính của SSLv3,được định nghĩa như sau: master_secret = PRF(pre_master_secret, "master secret", ClientHello.random || ServerHello.random) Giải thuật biểu diễn cho đến khi 48 byte của output số ngẫu nhiên được tạo ra.Phép tính toán của khối vật liệu key(MAC secret keys,khóa mã hóa phiên, và ma trận khởi tạo IVs) được định nghĩa như sau: key_block = PRF(master_secret,"key expansion",SecurityParameters.server_random || SecurityParameters.client_random) Cho đến khi đủ output được sinh ra.Như với SSLv3,key_block là 1 hàm của master_secret và client và server random numbers, nhưng với TLS giải thuật thực tế là khác biệt. I.8.9 Phần đệm : Trong SSL, phần đệm thêm vào trước để mã hóa dữ liệu user là số lượng nhỏ nhất được yêu cầu để mà kích thước tổng của dữ liệu được mã hóa là một phép nhân của chiều dài khối của cipher.Trong TLS, padding có thể là bất kì số lượng nào mà có kết quả trong một tổng mà là một phép nhân của chiều dài khối của cipher lên đến 1 giá trị lớn nhất là 255 byte.Ví dụ, nếu 1 plaintext (hoặc văn bản nén được dùng) cộng với MAC+padding length byte là dài 79 byte.Sau đó chiều dài padding,tính theo byte, có thể là 1,9,17 và hơn nữa,đến 249. Chiều dài phần đệm tùy biến có thể chống lại các tấn công dựa trên một phép phân tích các chiều dài của các thông điệp trao đổi. PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 27 Chương II : II.1 Quan hệ giữa các Class : Để liên lạc một cách bảo mật, cả hai đầu của kết nối phải kích hoạt SSL. Trong JSSE API, những lớp đầu cuối của kết nối là SSLSocket và SSLEngine . Trong biểu đồ bên dưới, những class lớn được dùng để tạo SSLSocket/SSLEngines được sắp xếp theo trật tự logic. Một SSLSocket thì được tạo bởi một SSLSocketFactory hoặc một SSLServerSocket cho việc nhận vào một kết nối inbound.( mặt khác, một SSLServerSocket được tạo bởi một SSLServerSocketFactory) . Cả các đối tượng SSLSocketFactory và SSLServerSocketFactory được tạo bởi SSLContext. Một SSLEngine được tạo một cách trực tiếp bởi SSLContext, và dựa vào ứng dụng để quản lý tất cả I/O. Ghi chú: Khi sử dụng SSLSockets/SSLEngines ta nên kiểm tra xác thực đầu cuối trước khi gửi dữ liệu. Lớp SSLSocket/SSLEngine sẽ không tự động xác minh, ví dụ hostname trong một URL trùng với hostname trong xác thực đầu cuối. Ứng dụng có thể bị lợi dụng URL spoofing nếu hostname không được xác minh Có hai cách để sử dụng và khởi tạo một SSLContext: PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 28 Đơn giản nhất là gọi phương thức tĩnh getDefault trên lớp SSLSocketFactory hoặc SSLServerSocketFactory . Những phương thức này tạo một SSLContext mặc định với một KeyManager, TrustManager và một bộ khởi tạo số bí mật ngẫu nhiên. (Một KeyManagerFactory và TrustManagerFactory mặc định được sử dụng để tạo KeyManager và TrustManager tương ứng.) Key material được tìm thấy trong keystore/truststore mặc định, được định rõ bởi tính chất hệ thống mô tả trong Customizing the Default Key and Trust Stores, Store Types, and Store Passwords. Phương thức trao đổi bên gọi phần lớn điều khiển cách hoạt động của context được tạo thì gọi là phương thức tĩnh getInstance trên lớp SSLContext , sau đó khởi tạo context bằng cách gọi phương thức riêng init của trường hợp . Một thực thể của phương thức init mang ba phần sau: một dãy đối tượng KeyManager, một dãy đối tượng TrustManager và một bộ sinh số bí mật ngẫu nhiên SecureRandom. Đối tượng KeyManager và TrustManager được tạo bởi việc bổ sung các interface(s) thích hợp hoặc dùng lớp KeyManagerFactory và TrustManagerFactory để phát sinh các bổ sung. KeyManagerFactory và TrustManagerFactory có thể được khởi tạo với mỗi key material chứa trong KeyStore qua phương thức TrustManagerFactory/KeyManagerFactory init. Cuối cùng phương thức getTrustManagers (trong TrustManagerFactory) và phương thức getKeyManagers (trong KeyManagerFactory) có thể được gọi để sử dụng những chuỗi của trust hoặc key managers,một cho mỗi loại của trust hoặc key material. Mỗi một kết nối SSL được khởi tạo thì một SSLSession được tạo chứa các thông tin đa dạng, như là ID khởi tạo, bộ mã hóa được dùng , .v.v. . SSLSession khi đó được dùng thể hiện mối liên hệ xảy ra bên trên và thông tin trạng thái giữa hai thực thể . Mỗi kết nối SSL bao gồm 1 phiên tại một thời điểm nhưng phiên đó thì lại có thể được dùng bởi nhiều kết nối giữa những thực thể đó,đồng thời hoặc theo thứ tự. II.2 Các Class và Interface chính : II.2.1 Lớp SocketFactory và ServerSocketFactory : Lớp trừu tượng javax.net.SocketFactory được dùng để tạo socket. Nó phải là subclassed của các factories khác, mà tạo những subclasses riêng biệt của sockets và vì vậy cung cấp một framework tổng quát cho phần thêm vào của chức năng public socket-level. (xem ví dụ SSLSocketFatory ) Lớp javax.net.ServerSocketFactory thì tương tự lớp SocketFactory, nhưng nó chỉ dành riêng cho việc tạo server sockets. Socket factories là cách đơn giản để các chính sách liên quan đến sockets được xây dựng,việc thiết lập sockets theo một cách nào đó thì không yêu cầu cấu hình riêng biệt cho code mà đòi hỏi: Vì sự đa hình của factories và sockets, những dạng khác nhau của sockets có thể cùng dùng code ứng dụng mà bỏ qua các dạng khác nhau của factories. Factories có thể tự tùy chỉnh thông số với các thông số sử dụng trong xây dựng socket. Ví dụ factories tự điều chỉnh để trả về sockets với những timeouts mạng khác nhau hoặc thông số security đã cấu hình . Sockets trả về ứng dụng subclasses của java.net.Socket (hay javax.net.ssl.SSLSocket), cho nên ta có thể trình bày một APIs mới cho những đặc trưng như nén , bảo mật ,đánh dấu record,lựa chọn thống kê, hay vượt tường lữa. II2.2 Lớp SSLSocketFactory và SSLServerSocketFactory : Một javax.net.ssl.SSLSocketFactory hoạt động như một factory cho việc tạo secure sockets. Lớp này là một phân lớp trừu tượng của javax.net.SocketFatory PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 29 Secure socket factories đóng gói chi tiết của việc tạo và cấu hình ban đầu secure sockets. Bao gồm xác thực keys, công nhận certificate đầu bên kia, kích hoạt bộ mã hóa và tương tự. Lớp javax.net.ssl.SSLServerSocketFactory thì tương tự lớp SSLSocketFactory, nhưng được sử dụng riêng cho việc tạo server sockets. Tạo một SSLSocketFactory : Có ba cách cơ bản để tạo SSLSocketFactory: Lấy factory mặc định bằng việc gọi phương thức tĩnh SSLSocketFactory.getDefault. Nhận một factory như là 1 thông số API .Đó là code cần tạo sockets nhưng không quan tâm chi tiết như thế nào sockets được cấu hình có thể bao gồm 1 phương thức với 1 thông số SSLSocketFactory được gọi bởi clients để chỉ rõ SSLSocketFactory dùng để tạo sockets,vd : javax.net.ssl.HttpsURLConnection. Xây dựng một factory mới với cách chạy được cấu hình riêng biệt. Factory mặc định được cấu hình đặc trưng để hổ trợ chứng thực server chỉ khi sockets được tạo bởi một factory mặc định không rò rĩ bất cứ thông tin nào về về client hơn một TCP socket bình thường làm. Nhiều lớp tạo và dùng sockets thì không cần biết chi tiết của cách tạo sockets.Việc tạo sockets qua một sockets factory được lướt qua như một thông số như là một cách tốt để cách ly chi tiết của cấu hình socket và tăng sự tái dụng của lớp mà tạo và dùng sockets. Bạn có thể tạo một socket factory mới bằng việc triển khai socket factory subclass của bạn hay sử dụng lớp khác mà hoạt động như một factory cho socket factories. Một ví dụ là lớp SSLContext mà được cung cấp trong JSSE như là một lớp cung cấp cấu hình cơ sở. II.2.3 Lớp SSLSocket và SSLServerSocket : Lớp javax.net.ssl.SSLSocket là một subclass của lớp chuẩn java.net.Socket . Nó hỗ trợ tất cả phương thức socket chuẩn và thêm những phương thức bổ sung đặc trưng vào secure sockets. Cá biệt của lớp này là đóng gói SSLContext bên dưới những gì mà nó tạo. Có những APIs điều khiển việc tạo secure socket sessions cho một socket riêng biệt nhưng việc quản lý trust và key không được che đậy một cách trực tiếp. Lớp javax.net.ssl.SSLServerSocket thì tương tự lớp SSLSocket ,nhưng được dùng đặc trưng cho cho việc tạo server sockets. Để ngăn spoofing đầu bên,bạn nên luôn xác minh đầu cuối cho một SSLSocket. Ghi chú bổ sung : do sự phức tạp của giao thức SSL và TLS ,nó khó để dự đoán có hay không bytes vào trên một kết nối là handshake hay dữ liệu ứng dụng,và như thế nào dữ liệu có thể tác động trạng thái kết nối hiện tại (ngoại trừ trường hợp quá trình bị block). Trong thực thi của Sun JSSE, phương thức available()trên đối tượng đạt được từ SSLSocket.getInputStream()trả về tổng số của bytes dữ liệu ứng dụng giải mã thành công từ kết nối kết nối SSL nhưng lúc này chưa đọc bởi ứng dụng. Tạo một SSLSocket : SSLSocket có thể tạo được bằng hai cách. Thứ nhất, một SSLSocket có thể tạo bởi SSLSocketFactory qua một vài phương thức createSocket trên lớp đó. Cách thứ hai tạo SSLSockets qua phương thức accept trên lớp SSLServerSocket . PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 30 II.2.4 Non-blocking I/O với SSLEngine : SSL/TLS đang ngày càng phổ biến. Nó được dùng trong các ứng dụng đa dạng trên một diện rộng các nền máy tính . Theo đà sự phổ biến hiện nay dẫn đến yêu cầu sử dụng nó với những I/O và mô hình chuỗi khác nhau để mà thỏa mãn hiệu suất , khả năng , theo dõi và những yêu cầu khác của ứng dụng.Đó là sự đòi hỏi sử dụng nó trong trong những kênh I/O blocking và non-blocking , I/O không đồng bộ, các luồng input và output đa dạng , và những bộ đệm byte.Đó là sự yêu cầu nó trong môi trường nhạy cảm có độ biến đổi và hiệu suất cao mà yêu cầu quản lý hàng ngàn network connections. Trước J2SE 5 , JSSE API hổ trợ chỉ một khái niệm trừu tượng transport đơn : luồng sockets nền thông qua SSLSocket. Trong khi dạng này tương thích với nhiều ứng dụng , nó không gặp phải những yêu cầu của ứng dụng mà cần dùng I/O khác nhau hay mô hình liên kết. Trong 1.5.0 , một khái niệm trừu tượng mới được giới thiệu để cho phép ứng dụng sử dụng giao thức SSL/TLS trong một đường vận chuyển độc lập , vì vậy những ứng dụng tự do chọn cách thức vận chuyển và mô hình tính toán tốt nhất mà nó cần. Nó còn thích nghi với nhiều mô hình liên kết. Điếu này cho phép một cách hiệu quả I/O và liên kết vào ứng dụng . Bởi vì tính linh hoạt này , ứng dụng bây giờ phải quản lý I/O và liên kết ( những topic phức tạp vào trong chính nó) cũng như nắm rõ giao thức SSL/TLS. Một khái niệm trừu tượng mới cho ra một API cao cấp : người dùng nên sử dụng SSLSocket. Một người mới tiếp xúc API có thể tự hỏi “ Tại sao không chỉ có một SSLSocketChannel mà thuộc java.nio.channels.SocketChannel?" Có hai lý do chính sau : Có nhiều câu hỏi khó về một SSLSocketChannel thì nên như thế nào gồm cả hệ thống phân lớp của nó và nó nên liên kết với Selectors và những dạng khác của SocketChannels như thế nào.Mỗi đề xuất thì mang lại nhiều câu hỏi hơn là trả lời . Nó được giải thích rằng khái niệm trừu thượng API mới mở rộng để làm việc với SSL/TLS yêu cầu cùng một các phép phân tích quan trọng và có thể dẫn đến những APIs lớn và phức tạp. Bất kỳ việc thực thi JSSE nào cho một API mới sẽ tự do chọn lựa I/O và chiến lược tính toán tốt nhất , nhưng ẩn đi những chi tiết không thích hợp cho yêu cầu điều khiển ứng dụng đó. Bất kỳ sự thực thi đặc trưng nên tách rời với các phân đoạn ứng dụng. Bằng việc trừu tượng I/O và dữ liệu xữ lý như những chuỗi bytes, kết quả được giải quyết và API mới có thể sử dụng với bất cứ mô hình I/O nào hiện nay và sắp tới.Trong khi giải pháp này làm I/O và CPU chuyển giao trách nhiệm cho người lập trình , việc thực thi JSSE thì bị ngăn không cho trở nên không sử dụng được bởi vì những chi tiết bên trong không thể cấu hình hay thay đổi. Người dùng những API ngôn ngữ lập trình lập trình Java khác như JGSS và SASL sẽ thông báo những điều tương tự rằng ứng dụng thì cũng chịu trách nhiệm cho dữ liệu vận chuyển. SSLEngine Lớp chính trong khái niệm mới này là javax.net.ssl.SSLEngine .Nó đóng gói một SSL/TLS cơ chế trạng thái và cách vận hành trên bộ đệm byte inbound và outbound hổ trợ bởi người dùng của SSLEngine. Lược đồ sau sẽ minh họa luồng dữ liệu của data từ ứng dụng , đến SSLEngine , đến cơ chế vận chuyển và quay về PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 31 Tầng ứng dụng ở bên trái cung cấp dữ liệu ứng dụng (plaintext) trong một application buffer và chuyển nó cho SSLEngine . SSLEngine xử lý dữ liệu chứa trong buffer hoặc bất cứ dữ liệu handshaking nào để tạo ra dữ liệu đã mã hóa SSL/TLS vào đặt vào network buffer cung cấp bởi ứng dụng. Ứng dụng thì sau đó chịu trách nhiệm cho việc vận chuyển tương ứng (bên phải) để gửi nội dung của network buffer đến đầu bên.Lúc nhận dữ liệu đã mã hóa SSL/TLS từ đầu bên ( thông qua tầng vận chuyển) , ứng dụng đưa dữ liệu vào trong network buffer và chuyển nó đến SSLEngine . SSLEngine xử lý nội dung network buffer để tạo ra dữ liệu handshaking hay dữ liệu ứng dụng. Về tổng thể , SSLEngine có thể là một trong năm trạng thái : 1. Creation – sẵn sàng để cấu hình. 2. Initial handshaking - thực thi chứng thực và thương lượng thông số truyền thông. 3. Application data – sẵn sàng cho trao đổi dữ liệu. 4. Rehandshaking - tái thương lượng thông số truyền thông / chứng thực;dữ liệu handshaking có thể đã được gắn vào dữ liệu ứng dụng. 5. Closure – sẵn sàng đóng kết nối. Năm trạng thái này được miêu tả chi tiết hơn trong tài liệu lớp SSLEngine II.2.5 Quá trình khởi động : Để tạo một SSLEngine , bạn sử dụng phương thức SSLContext.createSSLEngine() . Bạn phải cấu hình cơ chế hoạt động như một client hoặc một server, cũng như đặt các thông số cấu hình khác như là cipher suites được dùng và có yêu cầu chứng thực client không. Đây là một ví dụ mà tạo một SSLEngine . Chú ý rằng tên server và số port thì không được dùng cho liên lạc với server – tất các vận chuyển là trách nhiệm của ứng dụng.Chúng gợi ý cho người cung cấp JSSE sử dụng việc cache SSL session, và cho việc thực thi Kerberos-cipher suite cơ bản để định rõ ủy quyền server nào nên được chọn. import javax.net.ssl.*; import java.security.*; // Khởi tạo SSLContext với key material char[] passphrase = "passphrase".toCharArray(); // Khởi tạo lần đầu key và trust material. KeyStore ksKeys = KeyStore.getInstance("JKS"); PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 32 ks.load(new FileInputStream("testKeys"), passphrase); KeyStore ksTrust = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("testTrust"), passphrase); // KeyManager's quyết định key material nào được dùng. KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ksKeys, passphrase); // TrustManager's quyết định có cho phép kết nối không. TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ksTrust); sslContext = SSLContext.getInstance("TLS"); sslContext.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null); // Chúng ta đã sẵn sàng cho một engine SSLEngine engine = sslContext.createSSLengine(hostname, port); // Sử dụng như một client engine.setUseClientMode(true); II.2.6 Phát sinh và xử lý dữ liệu SSL/TLS : Hai phương thức chính SSLEngine wrap() và unwrap() thì chịu trách nhiệm cho việc phát sinh và sử dụng dữ liệu network tương ứng. phụ thuộc vào trạng thái SSLEngine, dữ liệu này có thể là dữ liệu handshake hay ứng dụng. Mỗi SSLEngine có một vài giai đoạn trong suốt thời gian sống của nó. Trước khi dữ liệu ứng dụng có thể được gửi/nhận , giao thức SSL/TLS yêu cầu một handshake để khởi tạo thông số mã hóa. Handshake này yêu cầu một loạt các bước tới và lui bởi SSLEngine. SSL Process có thể cung cấp thêm chi tiết về handshake của chính nó. Suốt quá trình handshacking ban đầu, wrap() và unwrap() khởi tạo và sử dụng dữ liệu handshake, và ứng dụng thì chịu trách nhiệm cho việc vận chuyển dữ liệu. Chuỗi wrap()/unwrap() được lập lại cho đến khi hanshake được hoàn tất. Mỗi quá trình hoạt động SSLEngine khởi tạo một SSLEngineResult, của trường SSLEngineResult.HandshakeStatus nào được dùng để xác định cơ chế nào cần xảy ra tiếp theo để tiến tới handshake . Một handshake điển hình có thể như sau: Client SSL/TLS message HSStatus wrap() ClientHello NEED_UNWRAP unwrap() ServerHello/Cert/ServerHelloDone NEED_WRAP wrap() ClientKeyExchange NEED_WRAP wrap() ChangeCipherSpec NEED_WRAP wrap() Finished NEED_UNWRAP unwrap() ChangeCipherSpec NEED_UNWRAP unwrap() Finished FINISHED Bây giờ thì việc handshaking đã hoàn thành, trạng thái tiếp theo sẽ gọi wrap()để thử dùng dữ liệu ứng dụng và packages cho vận chuyển. unwrap()thì làm ngược lại. Để gửi dữ liệu đến đầu bên , ứng dụng trước hết phải cung cấp dữ liệu mà nó muốn gửi đến SSLEngine thông qua SSLEngine.wrap() để thu được dữ liệu đã mã hóa SSL/TLS tương ứng.Ứng dụng sau đó gửi dữ liệu cho đầu bên theo cơ chế vận chuyển mà nó đã chọn . Khi ứng dụng nhận được dữ liệu đã mã hóa SSL/TLS qua cơ chê PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 33 vận chuyển, nó cung cấp dữ liệu này cho SSLEngine thông qua SSLEngine.unwrap() để thu được dữ liệu plaintext mà đầu kia muốn gửi. Đây là một thí dụ của một ứng dụng SSL mà sử dụng một non-blocking SocketChannel để liên lạc với bên kia(Nó có thể được tạo thẳng và có thể hay đổi bẳng việc dùng một Selector với non-blocking SocketChannel.) Đoạn code sau sẽ gửi chuỗi "hello" đến đầu bên kia, bằng việc viết mã nó sử dụng SSLEngine đã tạo trong ví dụ trước.Nó sử dụng thông tin từ SSLSession để định nghĩa độ lớn của byte buffers là bao nhiêu. // Tạo một non-blocking socket channel SocketChannel socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); socketChannel.connect(new InetSocketAddress(hostname, port)); // Hoàn tất việc kết nối while (!socketChannel.finishedConnect()) { // làm bất cứ gì cho đến khi kết nối hoàn tất } // Tạo byte buffers cho việc giữ ứng dụng và dữ liệu đã mã hóa SSLSession session = engine.getSession(); ByteBuffer myAppData = ByteBuffer.allocate(session.getApplicationBufferSize()); ByteBuffer myNetData = ByteBuffer.allocate(session.getPacketBufferSize()); ByteBuffer peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize()); ByteBuffer peerNetData = ByteBuffer.allocate(session.getPacketBufferSize()); // Làm Handshake ban đầu doHandshake(socketChannel, engine, myNetData, peerNetData); myAppData.put("hello".getBytes()); myAppData.flip(); while (myAppData.hasRemaining()) { // Sinh ra dữ liệu mã hóa SSL/TLS (dữ liệu handshake hoặc ứng dụng) SSLEngineResult res = engine.wrap(myAppData, myNetData); // Xử lý trạng thái của bên gọi if (res.getStatus() == SSLEngineResult.Status.OK) { myAppData.compact(); // Gửi dữ liệu mã hóa SSL/TLS cho đầu bên kia while(myNetData.hasRemaining()) { int num = socketChannel.write(myNetData); if (num == -1) { // điều khiển đóng channel } else if (num == 0) { // Nếu không byte nào được viết thì thử lại lần nữa } } } // Điều khiển những trạng thái khác: BUFFER_OVERFLOW, CLOSED ... PTIT 2009 Đề tài môn Bảo mật thông tin Secure Socket Layer 34 } Đoạn code sa

Các file đính kèm theo tài liệu này:

  • pdfssl_1217.pdf
Tài liệu liên quan