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:
62 trang |
Chia sẻ: maiphuongdc | Lượt xem: 2694 | Lượt tải: 1
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:
- ssl_1217.pdf