Movatterモバイル変換


[0]ホーム

URL:


Skip toContent

Java Secure Socket Extension (JSSE) Reference Guide


Introduction

Data that travels across a network can easily be accessed bysomeone who is not the intended recipient. When the data includesprivate information, such as passwords and credit card numbers,steps must be taken to make the data unintelligible to unauthorizedparties. It is also important to ensure that the data has not beenmodified, either intentionally or unintentionally, duringtransport. The Secure Sockets Layer (SSL) and Transport LayerSecurity (TLS) protocols were designed to help protect the privacyand integrity of data while it is being transferred across anetwork.

The Java Secure Socket Extension (JSSE) enables secure Internetcommunications. It provides a framework and an implementation for aJava version of the SSL and TLS protocols and includesfunctionality for data encryption, server authentication, messageintegrity, and optional client authentication. Using JSSE,developers can provide for the secure passage of data between aclient and a server running any application protocol (such as HTTP,Telnet, or FTP) over TCP/IP. For an introduction to TLS, seeTransport Layer Security (TLS) Protocol Overview.

By abstracting the complex underlying security algorithms andhandshaking mechanisms, JSSE minimizes the risk of creating subtlebut dangerous security vulnerabilities. Furthermore, it simplifiesapplication development by serving as a building block thatdevelopers can integrate directly into their applications.

JSSE provides both an application programming interface (API)framework and an implementation of that API. The JSSE APIsupplements the core network and cryptographic services defined bythejava.security andjava.net packagesby providing extended networking socket classes, trust managers,key managers, SSL contexts, and a socket factory framework forencapsulating socket creation behavior. Because theSSLSocket class is based on a blocking I/O model, theJava Development Kit (JDK) includes a nonblockingSSLEngine class to enable implementations to choosetheir own I/O methods.

The JSSE API supports the following security protocols:

These security protocols encapsulate a normal bidirectional stream socket, and the JSSE API adds transparent support for authentication, encryption, and integrity protection.

JSSE is a security component of the Java SE platform, and isbased on the same design principles found elsewhere in theJava Cryptography Architecture(JCA) framework. This framework for cryptography-relatedsecurity components allows them to have implementation independenceand, whenever possible, algorithm independence. JSSE uses thecryptographicservice providers defined by the JCA framework.

Other security components in the Java SE platform include theJava Authentication andAuthorization Service (JAAS) and theJava Security Tools. JSSEencompasses many of the same concepts and algorithms as those inJCA but automatically applies them underneath a simple streamsocket API.

The JSSE API was designed to allow other SSL/TLS protocol andPublic Key Infrastructure (PKI) implementations to be plugged inseamlessly. Developers can also provide alternative logic todetermine if remote hosts should be trusted or what authenticationkey material should be sent to a remote host.

Features and Benefits

JSSE includes the following important features:

JSSE StandardAPI

The JSSE standard API, available in thejavax.netandjavax.net.ssl packages, provides:

SunJSSE Provider

Oracle's implementation of Java SE includes a JSSE providernamedSunJSSE, which comes preinstalled and preregisteredwith the JCA. This provider supplies the following cryptographicservices:

More information about this provider is available in theSunJSSE sectionof the Oracle Providers Documentation.

Related Documentation

The following list contains links to online documentation andnames of books about related subjects:

Terms and Definitions

Several terms relating to cryptography are used within thisdocument. This section defines some of these terms.

authentication

The process of confirming the identity of a party with whom oneis communicating.

ciphersuite

A combination of cryptographic parameters that define thesecurity algorithms and key sizes used for authentication, keyagreement, encryption, and integrity protection.

certificate

A digitally signed statement vouching for the identity andpublic key of an entity (person, company, and so on). Certificatescan either be self-signed or issued by a Certificate Authority (CA)— an entity that is trusted to issue validcertificates for other entities. Well-known CAs include Comodo, DigiCert,and GoDaddy. X509 is a common certificate formatthat can be managed by the JDK'skeytool.

cryptographic hash function

An algorithm that is used to produce a relatively smallfixed-size string of bits (called a hash) from an arbitrary blockof data. A cryptographic hash function is similar to a checksum andhas three primary characteristics: it is a one-way function,meaning that it is not possible to produce the original data fromthe hash; a small change in the original data produces a largechange in the resulting hash; and it does not require acryptographic key.

Cryptographic Service Provider

Sometimes referred to simply asproviderfor short, the Java Cryptography Architecture (JCA) defines it as apackage (or set of packages) that implements one or more engineclasses for specific cryptographic algorithms. An engine classdefines a cryptographic service in an abstract fashion without aconcrete implementation.

decryption

Seeencryption/decryption.

digital signature

A digital equivalent of a handwritten signature. It is used toensure that data transmitted over a network was sent by whoeverclaims to have sent it and that the data has not been modified intransit. For example, an RSA-based digital signature is calculatedby first computing a cryptographic hash of the data and thenencrypting the hash with the sender's private key.

encryption/decryption

Encryption is the process of using a complex algorithm toconvert an original message (cleartext) to an encodedmessage (ciphertext) that is unintelligible unless it isdecrypted. Decryption is the inverse process of producing cleartextfrom ciphertext.

The algorithms used to encrypt and decrypt data typically comein two categories: secret key (symmetric) cryptographyand public key (asymmetric) cryptography.

handshake protocol

The negotiation phase during which the two socket peers agree touse a new or existing session. The handshake protocol is a seriesof messages exchanged over the record protocol. At the end of thehandshake, new connection-specific encryption and integrityprotection keys are generated based on the key agreement secrets inthe session.

key agreement

A method by which two parties cooperate to establish a commonkey. Each side generates some data, which is exchanged. These twopieces of data are then combined to generate a key. Only thoseholding the proper private initialization data can obtain the finalkey. Diffie-Hellman (DH) is the most common example of a keyagreement algorithm.

key exchange

A method by which keys are exchanged. One side generates aprivate key and encrypts it using the peer's public key (typicallyRSA). The data is transmitted to the peer, who decrypts the keyusing the corresponding private key.

keymanager/trust manager

Key managers and trust managers use keystores for their keymaterial. A key manager manages a keystore and supplies public keysto others as needed (for example, for use in authenticating theuser to others). A trust manager decides who to trust based oninformation in the truststore it manages.

keystore/truststore

A keystore is a database of key material. Key material is usedfor a variety of purposes, including authentication and dataintegrity. Various types of keystores are available, includingPKCS12 and Oracle's JKS.

Generally speaking, keystore information can be grouped into twocategories: key entries and trusted certificate entries. A keyentry consists of an entity's identity and its private key, and canbe used for a variety of cryptographic purposes. In contrast, atrusted certificate entry contains only a public key in addition tothe entity's identity. Thus, a trusted certificate entry cannot beused where a private key is required, such as in ajavax.net.ssl.KeyManager. In the JDK implementation ofJKS, a keystore may contain both key entries and trustedcertificate entries.

A truststore is a keystore that is used when making decisionsabout what to trust. If you receive data from an entity that youalready trust, and if you can verify that the entity is the onethat it claims to be, then you can assume that the data really camefrom that entity.

An entry should only be added to a truststore if the user truststhat entity. By either generating a key pair or by importing acertificate, the user gives trust to that entry. Any entry in thetruststore is considered a trusted entry.

It may be useful to have two different keystore files: onecontaining just your key entries, and the other containing yourtrusted certificate entries, including CA certificates. The formercontains private information, whereas the latter does not. Usingtwo files instead of a single keystore file provides a cleanerseparation of the logical distinction between your own certificates(and corresponding private keys) and others' certificates. Toprovide more protection for your private keys, store them in akeystore with restricted access, and provide the trustedcertificates in a more publicly accessible keystore if needed.

message authentication code (MAC)

Provides a way to check the integrity of information transmittedover or stored in an unreliable medium, based on a secret key.Typically, MACs are used between two parties that share a secretkey in order to validate information transmitted between theseparties.

A MAC mechanism that is based on cryptographic hash functions isreferred to as HMAC. HMAC can be used with any cryptographic hashfunction, such as Secure Hash Algorithm(SHA-256), in combination with a secret shared key. HMAC is specifiedin RFC 2104.

public-key cryptography

A cryptographic system that uses an encryption algorithm inwhich two keys are produced. One key is made public, whereas theother is kept private. The public key and the private key arecryptographic inverses; what one key encrypts only the other keycan decrypt. Public-key cryptography is also calledasymmetriccryptography.

Record Protocol

A protocol that packages all data (whether application-level oras part of the handshake process) into discrete records of datamuch like a TCP stream socket converts an application byte streaminto network packets. The individual records are then protected bythe current encryption and integrity protection keys.

secret-key cryptography

A cryptographic system that uses an encryption algorithm inwhich the same key is used both to encrypt and decrypt the data.Secret-key cryptography is also calledsymmetriccryptography.

session

A named collection of state information including authenticatedpeer identity, cipher suite, and key agreement secrets that arenegotiated through a secure socket handshake and that can be sharedamong multiple secure socket instances.

trust manager

Seekey manager/trust manager.

truststore

Seekeystore/truststore.

Transport Layer Security (TLS) Protocol Overview

Transport Layer Security (TLS) is the most widely usedprotocol for implementing cryptography on the web. TLS uses acombination of cryptographic processes to provide securecommunication over a network. The pageTransport Layer Security (TLS) Protocol Overviewprovides an introduction to TLS and the cryptographic processes it uses.

JSSE Classes andInterfaces

To communicate securely, both sides of the connection must beSSL-enabled. In the JSSE API, the endpoint classes of theconnection areSSLSocket andSSLEngine.In the figureJSSE Classes Used to Create SSLSocket andSSLEngine, the major classes used to createSSLSocket andSSLEngine are laid out in alogical ordering. The text following the diagram, explains thecontents of the illustration.

ClassesUsed to Create SSLSocket and SSLEngine
This image illustrates the JSSE classes required to create SSLEngineand SSLSocket classes. The image also describes the JSSE classes andinterfaces and their relationships. The sections following this imagedescribe these classes and interfaces.

AnSSLSocket is created either by anSSLSocketFactory or by anSSLServerSocketaccepting an inbound connection. In turn, anSSLServerSocket is created by anSSLServerSocketFactory. BothSSLSocketFactory andSSLServerSocketFactory objects are created by anSSLContext. AnSSLEngine is createddirectly by anSSLContext, and relies on theapplication to handle all I/O.


Note: When using rawSSLSocket orSSLEngine classes, you should always check the peer'scredentials before sending any data. Since JDK 7, endpointidentification/verification procedures can be handled duringSSL/TLS handshaking. See the methodSSLParameters.setEndpointIdentificationAlgorithm. Forexample, the host name in a URL should match the host name in thepeer's credentials. An application could be exploited with URLspoofing if the host name is not verified.


Core Classes andInterfaces

The core JSSE classes are part of thejavax.net andjavax.net.ssl packages.

SocketFactory andServerSocketFactory Classes

The abstractjavax.net.SocketFactory class is usedto create sockets. Subclasses of this class are factories thatcreate particular subclasses of sockets and thus provide a generalframework for the addition of public socket-level functionality.For example, seeSSLSocketFactory andSSLServerSocketFactory.

The abstractjavax.net.ServerSocketFactory class isanalogous to theSocketFactory class, but is usedspecifically for creating server sockets.

Socket factories are a simple way to capture a variety ofpolicies related to the sockets being constructed, producing suchsockets in a way that does not require special configuration of thecode that asks for the sockets:

SSLSocketFactory and SSLServerSocketFactoryClasses

Thejavax.net.ssl.SSLSocketFactory class acts as afactory for creating secure sockets. This class is an abstractsubclass ofjavax.net.SocketFactory.

Secure socket factories encapsulate the details of creating andinitially configuring secure sockets. This includes authenticationkeys, peer certificate validation, enabled cipher suites, and thelike.

Thejavax.net.ssl.SSLServerSocketFactory class isanalogous to theSSLSocketFactory class, but is usedspecifically for creating server sockets.

Obtaining an SSLSocketFactory

The following ways can be used to obtain anSSLSocketFactory:

The default factory is typically configured to support serverauthentication only so that sockets created by the default factorydo not leak any more information about the client than a normal TCPsocket would.

Many classes that create and use sockets do not need to know thedetails of socket creation behavior. Creating sockets through asocket factory passed in as a parameter is a good way of isolatingthe details of socket configuration, and increases the reusabilityof classes that create and use sockets.

You can create new socket factory instances either byimplementing your own socket factory subclass or by using anotherclass which acts as a factory for socket factories. One example ofsuch a class isSSLContext, which is provided with theJSSE implementation as a provider-based configuration class.

SSLSocket andSSLServerSocket Classes

Thejavax.net.ssl.SSLSocket class is a subclass ofthe standard Javajava.net.Socket class. It supportsall of the standard socket methods and adds methods specific tosecure sockets. Instances of this class encapsulate theSSLContext under which they were created. Thereare APIs to control the creation of secure socket sessions for asocket instance, but trust and key management are not directlyexposed.

Thejavax.net.ssl.SSLServerSocket class isanalogous to theSSLSocket class, but is usedspecifically for creating server sockets.

To prevent peer spoofing, you should always verify the credentialspresented to anSSLSocket. SeeCipher Suite Choice and Remote EntityVerification.


Note: Due to the complexity of the SSL and TLSprotocols, it is difficult to predict whether incoming bytes on aconnection are handshake or application data, and how that datamight affect the current connection state (even causing the processto block). In the Oracle JSSE implementation, theavailable() method on the object obtained bySSLSocket.getInputStream() returns a count of thenumber of application data bytes successfully decrypted from theSSL connection but not yet read by the application.


Obtaining an SSLSocket

Instances ofSSLSocket can be obtained in one of thefollowing ways:

Cipher Suite Choice and Remote Entity Verification

The SSL/TLS protocols define a specific series of steps to ensurea protected connection. However, the choice of cipher suite directlyaffects the type of security that the connection enjoys. For example,if an anonymous cipher suite is selected, then the application hasno way to verify the remote peer's identity. If a suite with noencryption is selected, then the privacy of the data cannot beprotected. Additionally, the SSL/TLS protocols do not specify thatthe credentials received must match those that peer might be expectedto send. If the connection were somehow redirected to a rogue peer,but the rogue's credentials were acceptable based on the currenttrust material, then the connection would be considered valid.

When using rawSSLSocket andSSLEngineclasses, you should always check the peer's credentials beforesending any data. TheSSLSocket andSSLEngineclasses do not automatically verify that the host name in a URLmatches the host name in the peer's credentials. An application couldbe exploited with URL spoofing if the host name is not verified.Since JDK 7, endpoint identification/verification procedures can behandled during SSL/TLS handshaking. See theSSLParameters.getEndpointIdentificationAlgorithm method.

Protocols such as HTTPS (HTTP Over TLS) do require host nameverification. Since JDK 7, the HTTPS endpoint identification isenforced during handshaking forHttpsURLConnection bydefault. See theSSLParameters.getEndpointIdentificationAlgorithm method.Alternatively, applications can use theHostnameVerifierinterface to override the default HTTPS host name rules.

SSLEngine Class

TLS is becoming increasingly popular. It is being used in awide variety of applications across a wide range of computingplatforms and devices. Along with this popularity come demands touse TLS with different I/O and threading models to satisfy theapplications' performance, scalability, footprint, and otherrequirements. There are demands to use TLS with blocking andnonblocking I/O channels, asynchronous I/O, arbitrary input andoutput streams, and byte buffers. There are demands to use it inhighly scalable, performance-critical environments, requiringmanagement of thousands of network connections.

Abstraction of the I/O transport mechanism using theSSLEngine class in Java SE allows applications to usethe TLS protocol in a transport-independent way, and thusfrees application developers to choose transport and computingmodels that best meet their needs. Not only does this abstractionallow applications to use nonblocking I/O channels and other I/Omodels, it also accommodates different threading models. Thiseffectively leaves the I/O and threading decisions up to theapplication developer. Because of this flexibility, the applicationdeveloper must manage I/O and threading (complex topics in and ofthemselves), as well as have some understanding of the SSL/TLSprotocols. The abstraction is therefore an advanced API: beginnersshould useSSLSocket.

Users of other Java programming language APIs such as the JavaGeneric Security Services (Java GSS) and the Java SimpleAuthentication Security Layer (Java SASL) will notice similaritiesin that the application is also responsible for transportingdata.

The core class isjavax.net.ssl.SSLEngine.It encapsulates a TLS state machine and operates on inboundand outbound byte buffers supplied by the user of theSSLEngine class. The diagramFlow of Data Through SSLEngine illustrates theflow of data from the application, throughSSLEngine,to the transport mechanism, and back.

Flow ofData Through SSLEngine
The following text describes this figure.

The application, shown on the left, supplies application(plaintext) data in an application buffer and passes it toSSLEngine. TheSSLEngine object processesthe data contained in the buffer, or any handshaking data, toproduce TLS encoded data and places it to the network buffersupplied by the application. The application is then responsiblefor using an appropriate transport (shown on the right) to send thecontents of the network buffer to its peer. Upon receiving TLSencoded data from its peer (via the transport), the applicationplaces the data into a network buffer and passes it toSSLEngine. TheSSLEngine object processesthe network buffer's contents to produce handshaking data orapplication data.

An instance of theSSLEngine class can be in one ofthe following states:

Understanding SSLEngine Operation Statuses

To indicate the status of the engine and what actions theapplication should take, theSSLEngine.wrap() andSSLEngine.unwrap() methods return anSSLEngineResult instance, as shown in the exampleUsing a Nonblocking SocketChannel. ThisSSLEngineResult object contains two pieces of statusinformation: the overall status of the engine and the handshakingstatus.

The possible overall statuses are represented by theSSLEngineResult.Status enum. The following statusesare available:

The exampleHandling BUFFER_UNDERFLOW andBUFFER_OVERFLOW illustrates how to handle theBUFFER_UNDERFLOW andBUFFER_OVERFLOWstatuses of theSSLEngine.unwrap() method. It usesSSLSession.getApplicationBufferSize() andSSLSession.getPacketBufferSize() to determine howlarge to make the byte buffers.

Handling BUFFER_UNDERFLOW andBUFFER_OVERFLOW
SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);switch (res.getStatus()) {case BUFFER_OVERFLOW:// Maybe need to enlarge the peer application data buffer.if (engine.getSession().getApplicationBufferSize() > peerAppData.capacity()) {// enlarge the peer application data buffer} else {// compact or clear the buffer}// retry the operationbreak;case BUFFER_UNDERFLOW:// Maybe need to enlarge the peer network packet bufferif (engine.getSession().getPacketBufferSize() > peerNetData.capacity()) {// enlarge the peer network packet buffer} else {// compact or clear the buffer}// obtain more inbound network data and then retry the operationbreak;// Handle other status: CLOSED, OK...}

The possible handshaking statuses are represented by theSSLEngineResult.HandshakeStatus enum. They representwhether handshaking has completed, whether the caller must obtainmore handshaking data from the peer or send more handshaking datato the peer, and so on. The following handshake statuses are available:

Having two statuses per result allows theSSLEngine toindicate that the application must take two actions: one in response tothe handshaking and one representing the overall status of thewrap() andunwrap() methods. For example,the engine might, as the result of a singleSSLEngine.unwrap() call, returnSSLEngineResult.Status.OK to indicate that the inputdata was processed successfully andSSLEngineResult.HandshakeStatus.NEED_UNWRAP toindicate that the application should obtain more TLS encodeddata from the peer and supply it toSSLEngine.unwrap()again so that handshaking can continue. As you can see, theprevious examples were greatly simplified; they would need to beexpanded significantly to properly handle all of thesestatuses.

The exampleChecking and Processing Handshaking Statuses and Overall Statuses illustrates how to processhandshaking data by checking handshaking status and the overallstatus of thewrap() andunwrap()methods.

Checking andProcessing Handshaking Statuses and Overall Statuses
void doHandshake(SocketChannel socketChannel, SSLEngine engine,ByteBuffer myNetData, ByteBuffer peerNetData) throws Exception {// Create byte buffers to use for holding application dataint appBufferSize = engine.getSession().getApplicationBufferSize();ByteBuffer myAppData = ByteBuffer.allocate(appBufferSize);ByteBuffer peerAppData = ByteBuffer.allocate(appBufferSize);// Begin handshakeengine.beginHandshake();SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();// Process handshaking messagewhile (hs != SSLEngineResult.HandshakeStatus.FINISHED &&hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {switch (hs) {case NEED_UNWRAP:// Receive handshaking data from peerif (socketChannel.read(peerNetData) < 0) {// The channel has reached end-of-stream}// Process incoming handshaking datapeerNetData.flip();SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);peerNetData.compact();hs = res.getHandshakeStatus();// Check statusswitch (res.getStatus()) {case OK :// Handle OK statusbreak;// Handle other status: BUFFER_UNDERFLOW, BUFFER_OVERFLOW, CLOSED...}break;case NEED_WRAP :// Empty the local network packet buffer.myNetData.clear();// Generate handshaking datares = engine.wrap(myAppData, myNetData);hs = res.getHandshakeStatus();// Check statusswitch (res.getStatus()) {case OK :myNetData.flip();// Send the handshaking data to peerwhile (myNetData.hasRemaining()) {socketChannel.write(myNetData);}break;// Handle other status:  BUFFER_OVERFLOW, BUFFER_UNDERFLOW, CLOSED...}break;case NEED_TASK :// Handle blocking tasksbreak;// Handle other status:  // FINISHED or NOT_HANDSHAKING...}}// Processes after handshaking...}

SSLEngine for TLS Protocols

This section shows you how to create an SSLEngine object and use it togenerate and process TLS data.

Creating an SSLEngine Object

To create anSSLEngine object, you use theSSLContext.createSSLEngine() method. You mustconfigure the engine to act as a client or a server, and set otherconfiguration parameters, such as which cipher suites to use andwhether to require client authentication. TheSSLContext.createSSLEngine method creates ajavax.net.ssl.SSLEngine object.

The exampleCreating an SSLEngine Client for TLS with JKSas Keystore illustrates how to create anSSLEngine clientfor TLS that uses JKS as keystore.


Note: The server name and port number are notused for communicating with the server (all transport is theresponsibility of the application). They are hints to the JSSEprovider to use for SSL session caching, and for Kerberos-basedcipher suite implementations to determine which server credentialsshould be obtained.


Creating an SSLEngine Client forTLS with JKS as Keystore
import javax.net.ssl.*;import java.security.*;// Create and initialize the SSLContext with key materialchar[] passphrase = "passphrase".toCharArray();// First initialize the key and trust materialKeyStore ksKeys = KeyStore.getInstance("JKS");ksKeys.load(new FileInputStream("testKeys"), passphrase);KeyStore ksTrust = KeyStore.getInstance("JKS");ksTrust.load(new FileInputStream("testTrust"), passphrase);// KeyManagers decide which key material to useKeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");kmf.init(ksKeys, passphrase);// TrustManagers decide whether to allow connectionsTrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");tmf.init(ksTrust);// Get an instance of SSLContext for TLS protocolssslContext = SSLContext.getInstance("TLS");sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);// Create the engineSSLEngine engine = sslContext.createSSLengine(hostname, port);// Use as clientengine.setUseClientMode(true);
Generating and Processing TLS Data

The two mainSSLEngine methods arewrap() andunwrap(). They are responsiblefor generating and consuming network data respectively. Dependingon the state of theSSLEngine object, this data mightbe handshake or application data.

EachSSLEngine object has several phases during itslifetime. Before application data can be sent or received, theSSL/TLS protocol requires a handshake to establish cryptographicparameters. This handshake requires a series of back-and-forthsteps by theSSLEngine object.

During the initial handshaking, thewrap() andunwrap() methods generate and consume handshake data,and the application is responsible for transporting the data. Thewrap() andunwrap() method sequence isrepeated until the handshake is finished. EachSSLEngine operation generates an instance of theSSLEngineResult class, in which theSSLEngineResult.HandshakeStatus field is used todetermine what operation must occur next to move the handshakealong.

The figureState Machineduring TLS Handshake shows the state machine during a typicalTLS handshake, with corresponding messages and statuses:

State Machine during TLSHandshake
The following text describes this image.

The following steps are performed before the status of the handshake isdetermined:

This image illustrates some of the possible handshake statuses.The sectionUnderstanding SSLEngine OperationStatuses describes these statuses in more detail:

When handshaking is complete, further calls towrap() will attempt to consume application data andpackage it for transport. Theunwrap() method willattempt the opposite.

To send data to the peer, the application first supplies thedata that it wants to send viaSSLEngine.wrap() toobtain the corresponding SSL/TLS encoded data. The application thensends the encoded data to the peer using its chosen transportmechanism. When the application receives the SSL/TLS encoded datafrom the peer via the transport mechanism, it supplies this data totheSSLEngine viaSSLEngine.unwrap() toobtain the plaintext data sent by the peer.

The exampleUsing a Nonblocking SocketChannel showsan SSL application that uses a nonblockingSocketChannel tocommunicate with its peer.


Note: The example can be made more robust andscalable by using aSelector with the nonblockingSocketChannel.


In the exampleUsing a Nonblocking SocketChannel,the stringhello is sent to the peer by encoding it using theSSLEngine created in the exampleCreating anSSLEngine Client for TLS with JKS as Keystore. It uses informationfrom theSSLSession to determine how large the byte buffersshould be.

Using a NonblockingSocketChannel
// Create a nonblocking socket channelSocketChannel socketChannel = SocketChannel.open();socketChannel.configureBlocking(false);socketChannel.connect(new InetSocketAddress(hostname, port));// Complete connectionwhile (!socketChannel.finishedConnect()) {// do something until connect completed}// Create byte buffers to use for holding application and encoded dataSSLSession 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());// Do initial handshakedoHandshake(socketChannel, engine, myNetData, peerNetData);myAppData.put("hello".getBytes());myAppData.flip();while (myAppData.hasRemaining()) {// Generate SSL/TLS encoded data (handshake or application data)SSLEngineResult res = engine.wrap(myAppData, myNetData);// Process status of callif (res.getStatus() == SSLEngineResult.Status.OK) {myAppData.compact();// Send SSL/TLS encoded data to peerwhile(myNetData.hasRemaining()) {int num = socketChannel.write(myNetData);if (num == 0) {// no bytes written; try again later}}}// Handle other status:  BUFFER_OVERFLOW, CLOSED...}

The exampleReading Data From NonblockingSocketChannel illustrates how to read data from the same nonblockingSocketChannel and extract the plaintext data from it by usingtheSSLEngine created in the exampleCreatingan SSLEngine Client for TLS with JKS as Keystore. Each iteration ofthis code may or may not produce plaintext data, depending on whetherhandshaking is in progress.

Reading Data From NonblockingSocketChannel
// Read SSL/TLS encoded data from peerint num = socketChannel.read(peerNetData);if (num == -1) {// The channel has reached end-of-stream} else if (num == 0) {// No bytes read; try again ...} else {// Process incoming datapeerNetData.flip();res = engine.unwrap(peerNetData, peerAppData);if (res.getStatus() == SSLEngineResult.Status.OK) {peerNetData.compact();if (peerAppData.hasRemaining()) {// Use peerAppData}}// Handle other status:  BUFFER_OVERFLOW, BUFFER_UNDERFLOW, CLOSED...}

Dealing With Blocking Tasks

During handshaking, anSSLEngine might encountertasks that can block or take a long time. For example, aTrustManager may need to connect to a remotecertificate validation service, or aKeyManager mightneed to prompt a user to determine which certificate to use as partof client authentication. To preserve the nonblocking nature ofSSLEngine, when the engine encounters such a task, itwill returnSSLEngineResult.HandshakeStatus.NEED_TASK.Upon receiving this status, the application should invokeSSLEngine.getDelegatedTask() to get the task, andthen, using the threading model appropriate for its requirements,process the task. The application might, for example, obtainthreads from a thread pool to process the tasks, while the mainthread handles other I/O.

The following code executes each task in a newly createdthread:

if (res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {Runnable task;while ((task = engine.getDelegatedTask()) != null) {new Thread(task).start();}}

TheSSLEngine will block futurewrap()andunwrap() calls until all of the outstanding tasksare completed.

Shutting Down

For an orderly shutdown of an SSL/TLS connection, the SSL/TLSprotocols require transmission of close messages. Therefore, whenan application is done with the SSL/TLS connection, it should firstobtain the close messages from theSSLEngine, thentransmit them to the peer using its transport mechanism, andfinally shut down the transport mechanism.Example6 illustrates this.

Example 6: ShuttingDown an SSL/TLS Connection
// Indicate that application is done with engineengine.closeOutbound();while (!engine.isOutboundDone()) {// Get close messageSSLEngineResult res = engine.wrap(empty, myNetData);// Check res statuses// Send close message to peerwhile(myNetData.hasRemaining()) {int num = socketChannel.write(myNetData);if (num == 0) {// no bytes written; try again later}myNetData().compact();}}// Close transportsocketChannel.close();

In addition to an application explicitly closing theSSLEngine, theSSLEngine might be closedby the peer (via receipt of a close message while it is processinghandshake data), or by theSSLEngine encountering anerror while processing application or handshake data, indicated bythrowing anSSLException. In such cases, theapplication should invokeSSLEngine.wrap() to get theclose message and send it to the peer untilSSLEngine.isOutboundDone() returnstrue(as shown inExample 6), or until theSSLEngineResult.getStatus() returnsCLOSED.

In addition to orderly shutdowns, there can also be unexpectedshutdowns when the transport link is severed before close messagesare exchanged. In the previous examples, the application might get-1 orIOException when trying to read fromthe nonblockingSocketChannel, or getIOException when trying to write to the non-blockingSocketChannel. When you get to the end of your input data,you should callengine.closeInbound(), which willverify with theSSLEngine that the remote peer hasclosed cleanly from the SSL/TLS perspective. Then the applicationshould still try to shut down cleanly by using the procedure inExample 6. Obviously, unlikeSSLSocket, the application usingSSLEngine must deal with more state transitions,statuses, and programming. For more information about writing anSSLEngine-based application, seeSample Code Illustrating the Use of anSSLEngine.

SSLSession and ExtendedSSLSession

Thejavax.net.ssl.SSLSession interface represents asecurity context negotiated between the two peers of anSSLSocket orSSLEngine connection. Aftera session has been arranged, it can be shared by futureSSLSocket orSSLEngine objects connectedbetween the same two peers.

In some cases, parameters negotiated during the handshake areneeded later in the handshake to make decisions about trust. Forexample, the list of valid signature algorithms might restrict thecertificate types that can be used for authentication. TheSSLSession can be retrievedduring thehandshake by callinggetHandshakeSession() on anSSLSocket orSSLEngine. ImplementationsofTrustManager orKeyManager can use thegetHandshakeSession() method to get information aboutsession parameters to help them make decisions.

A fully initializedSSLSession contains the ciphersuite that will be used for communications over a secure socket aswell as a nonauthoritative hint as to the network address of theremote peer, and management information such as the time ofcreation and last use. A session also contains a shared mastersecret negotiated between the peers that is used to createcryptographic keys for encrypting and guaranteeing the integrity ofthe communications over anSSLSocket orSSLEngine connection. The value of this master secretis known only to the underlying secure socket implementation and isnot exposed through theSSLSession API.

In Java SE, a TLS 1.2 session is represented byExtendedSSLSession, an implementation ofSSLSession. TheExtendedSSLSession classadds methods that describe the signature algorithms that aresupported by the local implementation and the peer. ThegetRequestedServerNames() method called on anExtendedSSLSession instance is used to obtain a listofSNIServerName objects in the requestedServer Name Indication (SNI) extension. Theserver should use the requested server names to guide its selectionof an appropriate authentication certificate, and/or other aspectsof the security policy. The client should use the requested servernames to guide its endpoint identification of the peer's identity,and/or other aspects of the security policy.

Calls to thegetPacketBufferSize() andgetApplicationBufferSize() methods onSSLSession are used to determine the appropriatebuffer sizes used bySSLEngine.


Note: The SSL/TLS protocols specify thatimplementations are to produce packets containing at most 16kilobytes (KB) of plain text. However, some implementations violatethe specification and generate large records up to 32 KB. If theSSLEngine.unwrap() code detects large inbound packets,then the buffer sizes returned bySSLSession will beupdated dynamically. Applications should alwayscheck theBUFFER_OVERFLOW andBUFFER_UNDERFLOW statuses and enlarge thecorresponding buffers if necessary.SunJSSE will always sendstandard compliant 16 KB records and allow incoming 32 KB records.For a workaround, see the system propertyjsse.SSLEngine.acceptLargeFragments inCustomizing JSSE.


HttpsURLConnection Class

The HTTPS protocol is similar to HTTP, but HTTPS firstestablishes a secure channel via SSL/TLS sockets and thenverifies the identity of the peer beforerequesting or receiving data. Thejavax.net.ssl.HttpsURLConnection class extends thejava.net.HttpsURLConnection class and adds support forHTTPS-specific features. For more information about how HTTPS URLsare constructed and used, see the API specification sections aboutthejava.net.URL,java.net.URLConnection,java.net.HttpURLConnection,andjavax.net.ssl.HttpURLConnectionclasses.

Upon obtaining anHttpsURLConnection instance, youcan configure a number of HTTP and HTTPS parameters before actuallyinitiating the network connection via theURLConnection.connect() method. Of particular interestare:

Setting the AssignedSSLSocketFactory

In some situations, it is desirable to specify theSSLSocketFactory that anHttpsURLConnection instance uses. For example, youmight want to tunnel through a proxy type that is not supported bythe default implementation. The newSSLSocketFactorycould return sockets that have already performed all necessarytunneling, thus allowingHttpsURLConnection to useadditional proxies.

TheHttpsURLConnection class has a defaultSSLSocketFactory that is assigned when the class isloaded (this is the factory returned by theSSLSocketFactory.getDefault() method). Futureinstances ofHttpsURLConnection will inherit thecurrent defaultSSLSocketFactory until a new defaultSSLSocketFactory is assigned to the class via thestaticHttpsURLConnection.setDefaultSSLSocketFactory()method. Once an instance ofHttpsURLConnection hasbeen created, the inheritedSSLSocketFactory on thisinstance can be overridden with a call to thesetSSLSocketFactory() method.


Note: Changing the default staticSSLSocketFactory has no effect on existing instancesofHttpsURLConnection. A call to thesetSSLSocketFactory() method is necessary to changethe existing instances.


You can obtain the per-instance or per-classSSLSocketFactory by making a call to thegetSSLSocketFactory() orgetDefaultSSLSocketFactory() method, respectively.

Setting the AssignedHostnameVerifier

If the host name of the URL does not match the host name in thecredentials received as part of the SSL/TLS handshake, then it ispossible that URL spoofing has occurred. If the implementationcannot determine a host name match with reasonable certainty, thenthe SSL implementation performs a callback to the instance'sassignedHostnameVerifier for further checking. Thehost name verifier can take whatever steps are necessary to makethe determination, such as performing host name pattern matching orperhaps opening an interactive dialog box. An unsuccessfulverification by the host name verifier closes the connection. Formore information regarding host name verification, seeRFC 2818.

ThesetHostnameVerifier() andsetDefaultHostnameVerifier() methods operate in asimilar manner to thesetSSLSocketFactory() andsetDefaultSSLSocketFactory() methods, in thatHostnameVerifier objects are assigned on aper-instance and per-class basis, and the current values can beobtained by a call to thegetHostnameVerifier() orgetDefaultHostnameVerifier() method.

Support Classesand Interfaces

The classes and interfaces in this section are provided tosupport the creation and initialization ofSSLContextobjects, which are used to createSSLSocketFactory,SSLServerSocketFactory, andSSLEngineobjects. The support classes and interfaces are part of thejavax.net.ssl package.

Three of the classes described in this section (SSLContext,KeyManagerFactory, andTrustManagerFactory) areengine classes. An engine class is an API class forspecific algorithms (or protocols, in the case ofSSLContext), for which implementations may be providedin one or more Cryptographic Service Provider (provider) packages.For more information about providers and engine classes, see the"Design Principles" and "Concepts" sections of theJava Cryptography ArchitectureReference Guide.

TheSunJSSE provider that comes standard with JSSE providesSSLContext,KeyManagerFactory, andTrustManagerFactory implementations, as well asimplementations for engine classes in the standardjava.security API. The following table listsimplementations supplied bySunJSSE.

Implementations Supplied by SunJSEE
Engine Class ImplementedAlgorithm or Protocol
KeyStorePKCS12
KeyManagerFactoryPKIX, SunX509
TrustManagerFactoryPKIX (X509 or SunPKIX), SunX509
SSLContextSSLv3(1), TLSv1, TLSv1.1,TLSv1.2, TLSv1.3 (since JDK 8u261)

The SSLContext Class

Thejavax.net.ssl.SSLContext class is an engineclass for an implementation of a secure socket protocol. Aninstance of this class acts as a factory for SSL socket factoriesand SSL engines. AnSSLContext object holds all of thestate information shared across all objects created under thatcontext. For example, session state is associated with theSSLContext when it is negotiated through the handshakeprotocol by sockets created by socket factories provided by thecontext. These cached sessions can be reused and shared by othersockets created under the same context.

Each instance is configured through itsinit methodwith the keys, certificate chains, and trusted root CA certificatesthat it needs to perform authentication. This configuration isprovided in the form of key and trust managers. These managersprovide support for the authentication and key agreement aspects ofthe cipher suites supported by the context.

Currently, only X.509-based managers are supported.

Obtaining and Initializing the SSLContext Class

There are two ways to obtain and initialize anSSLContext:

Once an SSL connection is established, anSSLSession is created which contains variousinformation, such as identities established and cipher suite used.TheSSLSession is then used to describe an ongoingrelationship and state information between two entities. Each SSLconnection involves one session at a time, but that session may beused on many connections between those entities, simultaneously orsequentially.

Creating an SSLContext Object

Like other JCA provider-based engine classes,SSLContext objects are created using thegetInstance() factory methods of theSSLContext class. These static methods each return aninstance that implementsat least the requested securesocket protocol. The returned instance may implement otherprotocols, too. For example,getInstance("TLSv1.2") mayreturn an instance that implements TLSv1, TLSv1.1, and TLSv1.2. ThegetSupportedProtocols() method returns a list ofsupported protocols when anSSLSocket,SSLServerSocket, orSSLEngine is createdfrom this context. You can control which protocols are actuallyenabled for an SSL connection by using thesetEnabledProtocols(String[] protocols) method.


Note: AnSSLContext object isautomatically created, initialized, and statically assigned to theSSLSocketFactory class when you call theSSLSocketFactory.getDefault() method. Therefore, youdo not have to directly create and initialize anSSLContext object (unless you want to override thedefault behavior).

To create anSSLContext object by calling thegetInstance() factory method, you must specify theprotocol name. You may also specify which provider you want tosupply the implementation of the requested protocol:

If just a protocol name is specified, then the system willdetermine whether an implementation of the requested protocol isavailable in the environment. If there is more than oneimplementation, then it will determine whether there is a preferredone.

If both a protocol name and a provider are specified, then thesystem will determine whether an implementation of the requestedprotocol is in the provider requested. If there is noimplementation, an exception will be thrown.

A protocol is a string (such as"TLS") thatdescribes the secure socket protocol desired. Common protocol namesforSSLContext objects are defined inAppendix A.

AnSSLContext can be obtained as follows:

SSLContext sc = SSLContext.getInstance("TLS");

A newly createdSSLContext should be initialized bycalling theinit method:

public void init(KeyManager[] km, TrustManager[] tm, SecureRandom random);

If theKeyManager[] parameter is null, then anemptyKeyManager will be defined for this context. IftheTrustManager[] parameter is null, then theinstalled security providers will be searched for thehighest-priority implementation of theTrustManagerFactory, fromwhich an appropriateTrustManager will be obtained.Likewise, theSecureRandom parameter may be null, inwhich case a default implementation will be used.

If the internal default context is used, (for example, anSSLContext is created bySSLSocketFactory.getDefault() orSSLServerSocketFactory.getDefault()), then adefaultKeyManager andTrustManager are created. The defaultSecureRandom implementation is also chosen.

The TrustManagerInterface

The primary responsibility of theTrustManager isto determine whether the presented authentication credentialsshould be trusted. If the credentials are not trusted, then theconnection will be terminated. To authenticate the remote identityof a secure socket peer, you must initialize anSSLContext object with one or moreTrustManager objects. You must pass oneTrustManager for each authentication mechanism that issupported. If null is passed into theSSLContextinitialization, then a trust manager will be created for you.Typically, a single trust manager supports authentication based onX.509 public key certificates (for example,X509TrustManager). Some secure socket implementationsmay also support authentication based on shared secret keys,Kerberos, or other mechanisms.

TrustManager objects are created either by aTrustManagerFactory, or by providing a concreteimplementation of the interface.

TheTrustManagerFactory Class

Thejavax.net.ssl.TrustManagerFactory is an engineclass for a provider-based service that acts as a factory for oneor more types ofTrustManager objects. Because it isprovider-based, additional factories can be implemented andconfigured to provide additional or alternative trust managers thatprovide more sophisticated services or that implementinstallation-specific authentication policies.

Creating a TrustManagerFactory

You create an instance of this class in a similar manner toSSLContext, except for passing an algorithm namestring instead of a protocol name to thegetInstance()method:
TrustManagerFactory tmf =TrustManagerFactory.getInstance(String algorithm);TrustManagerFactory tmf =TrustManagerFactory.getInstance(String algorithm, String provider);TrustManagerFactory tmf =TrustManagerFactory.getInstance(String algorithm, Provider provider);

A sample call is as follows:

TrustManagerFactory tmf =TrustManagerFactory.getInstance("PKIX", "SunJSSE");

The preceding call creates an instance of theSunJSSE provider'sPKIX trust manager factory. This factory can be used to createtrust managers that provide X.509 PKIX-based certification pathvalidity checking.

When initializing anSSLContext, you can use trustmanagers created from a trust manager factory, or you can writeyour own trust manager, for example, using theCertPathAPI. For details, see theJava PKI Programmer'sGuide. You do not need to use a trust manager factory if youimplement a trust manager using theX509TrustManagerinterface.

A newly created factory should be initialized by calling one oftheinit() methods:

public void init(KeyStore ks);public void init(ManagerFactoryParameters spec);

Call whicheverinit() method is appropriate for theTrustManagerFactory you are using. If you are notsure, then ask the provider vendor.

For many factories, such as the SunX509TrustManagerFactory from theSunJSSE provider, theKeyStore is the only information required toinitialize theTrustManagerFactory and thus the firstinit method is the appropriate one to call. TheTrustManagerFactory will query theKeyStore for information about which remotecertificates should be trusted during authorization checks.

Sometimes, initialization parameters other than aKeyStore are needed by a provider. Users of thatprovider are expected to pass an implementation of the appropriateManagerFactoryParameters as defined by the provider.The provider can then call the specified methods in theManagerFactoryParameters implementation to obtain theneeded information.

For example, suppose theTrustManagerFactoryprovider requires initialization parameters B, R, and S from anyapplication that wants to use that provider. Like all providersthat require initialization parameters other than aKeyStore, the provider requires the application toprovide an instance of a class that implements a particularManagerFactoryParameters subinterface. In the example,suppose that the provider requires the calling application toimplement and create an instance ofMyTrustManagerFactoryParams and pass it to the secondinit() method. The following example illustrates whatMyTrustManagerFactoryParams can look like:

public interface MyTrustManagerFactoryParams extends ManagerFactoryParameters {public boolean getBValue();public float getRValue();public String getSValue():}

Some trust managers can make trust decisions without beingexplicitly initialized with aKeyStore object or anyother parameters. For example, they may access trust material froma local directory service via LDAP, use a remote online certificatestatus checking server, or access default trust material from astandard local location.

PKIX TrustManagerSupport

The default trust manager algorithm is PKIX. It can be changedby editing thessl.TrustManagerFactory.algorithmproperty in thejava.security file.

The PKIX trust manager factory uses theCertPath PKIXimplementation from an installed security provider. The trustmanager factory can be initialized using the normalinit(KeyStore ks) method, or by passing CertPathparameters to the the PKIX trust manager using thejavax.net.ssl.CertPathTrustManagerParametersclass.

The following example illustrates how to get the trust managerto use a particular LDAP certificate store and enable revocationchecking:

import javax.net.ssl.*;import java.security.cert.*;import java.security.KeyStore;import java.io.FileInputStream;...// Obtain Keystore passwordchar[] pass = System.console().readPassword("Password: ");// Create PKIX parametersKeyStore anchors = KeyStore.getInstance("PKCS12");anchors.load(new FileInputStream(anchorsFile, pass));PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(anchors, new X509CertSelector());// Specify LDAP certificate store to useLDAPCertStoreParameters lcsp = new LDAPCertStoreParameters("ldap.imc.org", 389);pkixParams.addCertStore(CertStore.getInstance("LDAP", lcsp));// Specify that revocation checking is to be enabledpkixParams.setRevocationEnabled(true);// Wrap PKIX parameters as trust manager parametersManagerFactoryParameters trustParams = new CertPathTrustManagerParameters(pkixParams);// Create TrustManagerFactory for PKIX-compliant trust managersTrustManagerFactory factory = TrustManagerFactory.getInstance("PKIX");// Pass parameters to factory to be passed to CertPath implementationfactory.init(trustParams);// Use factorySSLContext ctx = SSLContext.getInstance("TLS");ctx.init(null, factory.getTrustManagers(), null);

If theinit(KeyStore ks) method is used, thendefault PKIX parameters are used with the exception that revocationchecking is disabled. It can be enabled by setting thecom.sun.net.ssl.checkRevocation system property totrue. This setting requires that the CertPathimplementation can locate revocation information by itself. ThePKIX implementation in the provider can do this in many cases butrequires that the system propertycom.sun.security.enableCRLDP be set totrue.

For more information about PKIX and the CertPath API, see theJava PKI Programmer'sGuide.

TheX509TrustManager Interface

Thejavax.net.ssl.X509TrustManager interfaceextends the generalTrustManager interface. It must beimplemented by a trust manager when using X.509-basedauthentication.

To support X.509 authentication of remote socket peers throughJSSE, an instance of this interface must be passed to theinit method of anSSLContext object.

Creating an X509TrustManager

You can either implement this interface directly yourself orobtain one from a provider-basedTrustManagerFactory(such as that supplied by theSunJSSE provider). You could alsoimplement your own interface that delegates to a factory-generatedtrust manager. For example, you might do this to filter theresulting trust decisions and query an end-user through a graphicaluser interface.


Note: If a null KeyStore parameter is passed totheSunJSSE PKIX or SunX509TrustManagerFactory, thenthe factory uses the following process to try to find trustmaterial:


  1. If thejavax.net.ssl.trustStore property isdefined, then theTrustManagerFactory attempts to finda file using the file name specified by that system property, anduses that file for the KeyStore parameter. If thejavax.net.ssl.trustStorePassword system property isalso defined, then its value is used to check the integrity of thedata in the truststore before opening it.

    If thejavax.net.ssl.trustStore property is definedbut the specified file does not exist, then a defaultTrustManager using an empty keystore is created.

  2. If thejavax.net.ssl.trustStore system propertywas not specified, then:
    • if the filejava-home/lib/security/jssecacerts exists,that file is used;
    • if the filejava-home/lib/security/cacerts exists, thatfile is used;
    • if neither of these files exists, then the SSL cipher suite isanonymous, does not perform any authentication, and thus does notneed a truststore.

The factory looks for a file specified via thejavax.net.ssl.trustStore Security Property or for thejssecacerts file before checking for acacerts file.Therefore, you can provide a JSSE-specific set of trusted rootcertificates separate from ones that might be present in cacertsfor code-signing purposes.

Creating Your OwnX509TrustManager

If the suppliedX509TrustManager behavior is notsuitable for your situation, then you can create your ownX509TrustManager by either creating and registeringyour ownTrustManagerFactory or by implementing theX509TrustManager interface directly.

The following example illustrates aMyX509TrustManager class that enhances the defaultSunJSSEX509TrustManager behavior by providingalternative authentication logic when the defaultX509TrustManager fails:

class MyX509TrustManager implements X509TrustManager {/** The default PKIX X509TrustManager9.  Decisions are delegated* to it, and a fall back to the logic in this class is performed* if the default X509TrustManager does not trust it.*/X509TrustManager pkixTrustManager;MyX509TrustManager() throws Exception {// create a "default" JSSE X509TrustManager.KeyStore ks = KeyStore.getInstance("PKCS12");ks.load(new FileInputStream("trustedCerts"), "passphrase".toCharArray());TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");tmf.init(ks);TrustManager tms [] = tmf.getTrustManagers();/** Iterate over the returned trust managers, looking* for an instance of X509TrustManager.  If found,* use that as the default trust manager.*/for (int i = 0; i < tms.length; i++) {if (tms[i] instanceof X509TrustManager) {pkixTrustManager = (X509TrustManager) tms[i];return;}}/** Find some other way to initialize, or else the* constructor fails.*/throw new Exception("Couldn't initialize");}/** Delegate to the default trust manager.*/public void checkClientTrusted(X509Certificate[] chain, String authType)throws CertificateException {try {pkixTrustManager.checkClientTrusted(chain, authType);} catch (CertificateException excep) {// do any special handling here, or rethrow exception.}}/** Delegate to the default trust manager.*/public void checkServerTrusted(X509Certificate[] chain, String authType)throws CertificateException {try {pkixTrustManager.checkServerTrusted(chain, authType);} catch (CertificateException excep) {/** Possibly pop up a dialog box asking whether to trust the* cert chain.*/}}/** Merely pass this through.*/public X509Certificate[] getAcceptedIssuers() {return pkixTrustManager.getAcceptedIssuers();}}

Once you have created such a trust manager, assign it to anSSLContext via theinit() method, as inthe following example. FutureSocketFactories createdfrom thisSSLContext will use your newTrustManager when making trust decisions.

TrustManager[] myTMs = new TrustManager[] { new MyX509TrustManager() };SSLContext ctx = SSLContext.getInstance("TLS");ctx.init(null, myTMs, null);

Updating the Keystore Dynamically

You can enhanceMyX509TrustManager to handledynamic keystore updates. When acheckClientTrusted orcheckServerTrusted test fails and does not establish atrusted certificate chain, you can add the required trustedcertificate to the keystore. You must create a newpkixTrustManager from theTrustManagerFactory initialized with the updatedkeystore. When you establish a new connection (using the previouslyinitializedSSLContext), the newly added certificatewill be used when making trust decisions.

X509ExtendedTrustManager Class

TheX509ExtendedTrustManager class is an abstractimplementation of theX509TrustManager interface. Itadds methods for connection-sensitive trust management. Inaddition, it enables endpoint verification at the TLS layer.

In TLS 1.2 and later, both client and server can specify whichhash and signature algorithms they will accept. To authenticate theremote side, authentication decisions must be based on both X509certificates and the local accepted hash and signature algorithms.The local accepted hash and signature algorithms can be obtainedusing theExtendedSSLSession.getLocalSupportedSignatureAlgorithms()method.

TheExtendedSSLSession object can be retrieved bycalling theSSLSocket.getHandshakeSession() method ortheSSLEngine.getHandshakeSession() method.

TheX509TrustManager interface is notconnection-sensitive. It provides no way to accessSSLSocket orSSLEngine sessionproperties.

Besides TLS 1.2 support, theX509ExtendedTrustManager class also supports algorithmconstraints and SSL layer host name verification. For JSSEproviders and trust manager implementations, theX509ExtendedTrustManager class is highly recommendedover the legacyX509TrustManager interface.

Creating an X509ExtendedTrustManager

You can either create anX509ExtendedTrustManagersubclass yourself (which is outlined in the following section) orobtain one from a provider-basedTrustManagerFactory(such as that supplied by theSunJSSE provider). In Java SE 7, thePKIX or SunX509TrustManagerFactory returns anX509ExtendedTrustManager instance.

Creating Your OwnX509ExtendedTrustManager

This section outlines how to create a subclass ofX509ExtendedTrustManager in nearly the same way asdescribed forX509TrustManager.

The following example illustrates how to create a class thatuses the PKIXTrustManagerFactory to locate a defaultX509ExtendedTrustManager that will be used to makedecisions about trust. If the default trust manager fails for anyreason, then the subclass is can add other behavior. In theexample, these locations are indicated by comments in thecatch clauses.

import java.io.*;import java.net.*;import java.security.*;import java.security.cert.*;import javax.net.ssl.*;public class MyX509ExtendedTrustManager extends X509ExtendedTrustManager {/** The default PKIX X509ExtendedTrustManager.  Decisions are* delegated to it, and a fall back to the logic in this class is* performed if the default X509ExtendedTrustManager does not* trust it.*/X509ExtendedTrustManager pkixTrustManager;MyX509ExtendedTrustManager() throws Exception {// create a "default" JSSE X509ExtendedTrustManager.KeyStore ks = KeyStore.getInstance("JKS");ks.load(new FileInputStream("trustedCerts"), "passphrase".toCharArray());TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");tmf.init(ks);TrustManager tms [] = tmf.getTrustManagers();/** Iterate over the returned trust managers, looking* for an instance of X509ExtendedTrustManager. If found,* use that as the default trust manager.*/for (int i = 0; i < tms.length; i++) {if (tms[i] instanceof X509ExtendedTrustManager) {pkixTrustManager = (X509ExtendedTrustManager) tms[i];return;}}/** Find some other way to initialize, or else we have to fail the* constructor.*/throw new Exception("Couldn't initialize");}/** Delegate to the default trust manager.*/public void checkClientTrusted(X509Certificate[] chain, String authType)throws CertificateException {try {pkixTrustManager.checkClientTrusted(chain, authType);} catch (CertificateException excep) {// do any special handling here, or rethrow exception.}}/** Delegate to the default trust manager.*/public void checkServerTrusted(X509Certificate[] chain, String authType)throws CertificateException {try {pkixTrustManager.checkServerTrusted(chain, authType);} catch (CertificateException excep) {/** Possibly pop up a dialog box asking whether to trust the* cert chain.*/}}/** Connection-sensitive verification.*/public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket)throws CertificateException {try {pkixTrustManager.checkClientTrusted(chain, authType, socket);} catch (CertificateException excep) {// do any special handling here, or rethrow exception.}}public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine)throws CertificateException {try {pkixTrustManager.checkClientTrusted(chain, authType, engine);} catch (CertificateException excep) {// do any special handling here, or rethrow exception.}}public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket)throws CertificateException {try {pkixTrustManager.checkServerTrusted(chain, authType, socket);} catch (CertificateException excep) {// do any special handling here, or rethrow exception.}}public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine)throws CertificateException {try {pkixTrustManager.checkServerTrusted(chain, authType, engine);} catch (CertificateException excep) {// do any special handling here, or rethrow exception.}}/** Merely pass this through.*/public X509Certificate[] getAcceptedIssuers() {return pkixTrustManager.getAcceptedIssuers();}}

The KeyManagerInterface

The primary responsibility of theKeyManager is toselect the authentication credentials that will eventually be sentto the remote host. To authenticate yourself (a local secure socketpeer) to a remote peer, you must initialize anSSLContext object with one or moreKeyManager objects. You must pass oneKeyManager for each different authentication mechanismthat will be supported. If null is passed into theSSLContext initialization, then an emptyKeyManager will be created. If the internal defaultcontext is used (for example, anSSLContext created bySSLSocketFactory.getDefault() orSSLServerSocketFactory.getDefault()), then adefaultKeyManager iscreated. Typically, a single key manager supports authenticationbased on X.509 public key certificates. Some secure socketimplementations may also support authentication based on sharedsecret keys, Kerberos, or other mechanisms.

KeyManager objects are created either by aKeyManagerFactory, or by providing a concreteimplementation of the interface.

TheKeyManagerFactory Class

Thejavax.net.ssl.KeyManagerFactory class is anengine class for a provider-based service that acts as a factoryfor one or more types ofKeyManager objects. TheSunJSSE provider implements a factory that can return a basic X.509key manager. Because it is provider-based, additional factories canbe implemented and configured to provide additional or alternativekey managers.

Creating a KeyManagerFactory

You create an instance of this class in a similar manner toSSLContext, except for passing an algorithm namestring instead of a protocol name to thegetInstance()method:

KeyManagerFactory kmf = getInstance(String algorithm);KeyManagerFactory kmf = getInstance(String algorithm, String provider);KeyManagerFactory kmf = getInstance(String algorithm, Provider provider);

A sample call as follows:

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509", "SunJSSE");

The preceding call creates an instance of theSunJSSE provider'sdefault key manager factory, which provides basic X.509-basedauthentication keys.

A newly created factory should be initialized by calling one oftheinit methods:

public void init(KeyStore ks, char[] password);public void init(ManagerFactoryParameters spec);

Call whicheverinit method is appropriate for theKeyManagerFactory you are using. If you are not sure,then ask the provider vendor.

For many factories, such as the default SunX509KeyManagerFactory from theSunJSSE provider, theKeyStore and password are the only informationrequired to initialize theKeyManagerFactory and thusthe firstinit method is the appropriate one to call.TheKeyManagerFactory will query theKeyStore for information about which private key andmatching public key certificates should be used for authenticatingto a remote socket peer. The password parameter specifies thepassword that will be used with the methods for accessing keys fromtheKeyStore. All keys in theKeyStoremust be protected by the same password.

Sometimes initialization parameters other than aKeyStore and password are needed by a provider. Usersof that provider are expected to pass an implementation of theappropriateManagerFactoryParameters as defined by theprovider. The provider can then call the specified methods in theManagerFactoryParameters implementation to obtain theneeded information.

Some factories can provide access to authentication materialwithout being initialized with aKeyStore object orany other parameters. For example, they may access key material aspart of a login mechanism such as one based on JAAS, the JavaAuthentication and Authorization Service.

As previously indicated, theSunJSSE provider supports a SunX509factory that must be initialized with aKeyStoreparameter.

The X509KeyManagerInterface

Thejavax.net.ssl.X509KeyManager interface extendsthe generalKeyManager interface. It must beimplemented by a key manager for X.509-based authentication. Tosupport X.509 authentication to remote socket peers through JSSE,an instance of this interface must be passed to theinit() method of anSSLContextobject.

Creating an X509KeyManager

You can either implement this interface directly yourself orobtain one from a provider-basedKeyManagerFactory(such as that supplied by theSunJSSE provider). You could alsoimplement your own interface that delegates to a factory-generatedkey manager. For example, you might do this to filter the resultingkeys and query an end-user through a graphical user interface.

Creating Your Own X509KeyManager

If the defaultX509KeyManager behavior is notsuitable for your situation, then you can create your ownX509KeyManager in a way similar to that shown inCreating Your Own X509TrustManager.

The X509ExtendedKeyManager Class

TheX509ExtendedKeyManager abstract class is animplementation of theX509KeyManager interface thatallows for connection-specific key selection. It adds two methodsthat select a key alias for client or server based on the key type,allowed issuers, and currentSSLEngine:

If a key manager is not an instance of theX509ExtendedKeyManager class, then it will not workwith theSSLEngine class.

For JSSE providers and key manager implementations, theX509ExtendedKeyManager class is highly recommendedover the legacyX509KeyManager interface.

In TLS 1.2 and later, both client and server can specify whichhash and signature algorithms they will accept. To pass theauthentication required by the remote side, local key selectiondecisions must be based on both X509 certificates and the remoteaccepted hash and signature algorithms. The remote accepted hashand signature algorithms can be retrieved using theExtendedSSLSession.getPeerSupportedSignatureAlgorithms()method.

You can create your ownX509ExtendedKeyManagersubclass in a way similar to that shown inCreating Your Own X509ExtendedTrustManager.

Support for theServer Name Indication(SNI) extension on the server side enables the key manager tocheck the server name and select the appropriate key accordingly.For example, suppose there are three key entries with certificatesin the keystore:

If the ClientHello message requests to connect towww.example.net in the SNI extension, then the servershould be able to select the certificate with subjectcn=www.example.net.

Relationship Between aTrustManager and a KeyManager

Historically, there has been confusion regarding thefunctionality of aTrustManager and aKeyManager.

ATrustManager determines whether the remoteauthentication credentials (and thus the connection) should betrusted.

AKeyManager determines which authenticationcredentials to send to the remote host.

Secondary Support Classes andInterfaces

These classes are provided as part of the JSSE API to supportthe creation, use, and management of secure sockets. They are lesslikely to be used by secure socket applications than are the coreand support classes. The secondary support classes and interfacesare part of thejavax.net.ssl andjavax.security.cert packages.

The SSLParametersClass

TheSSLParameters class encapsulates the followingparameters that affect a TLS connection:

You can retrieve the currentSSLParameters for anSSLSocket orSSLEngine by using thefollowing methods:

You can assignSSLParameters with thesetSSLParameters() method in anSSLSocket,SSLServerSocket andSSLEngine.

You can explicitly set the server name indication with theSSLParameters.setServerNames() method. The server nameindication in client mode also affects endpoint identification. Inthe implementation ofX509ExtendedTrustManager, ituses the server name indication retrieved by theExtendedSSLSession.getRequestedServerNames() method.The following example illustrates this functionality:

SSLSocketFactory factory = ...SSLSocket sslSocket = factory.createSocket("172.16.10.6", 443);// SSLEngine sslEngine = sslContext.createSSLEngine("172.16.10.6", 443);SNIHostName serverName = new SNIHostName("www.example.com");List<SNIServerName> serverNames = new ArrayList<>(1);serverNames.add(serverName);SSLParameters params = sslSocket.getSSLParameters();params.setServerNames(serverNames);sslSocket.setSSLParameters(params);// sslEngine.setSSLParameters(params);

In the preceding example, the host name in the server nameindication (www.example.com) will be used to makeendpoint identification against the peer's identity presented inthe end-entity's X.509 certificate.

Cipher Suite Preference

During TLS handshaking, the client requests to negotiate acipher suite from a list of cryptographic options that it supports,starting with its first preference. Then, the server selects asingle cipher suite from the list of cipher suites requested by theclient. The selection honors the server's preference by default, which is themost secure setting. However, the server can choose to honor the client'spreference rather than its own preference by invoking the methodSSLParameters.setUseCipherSuitesOrder(false).

TheSSLSessionContext Interface

Thejavax.net.ssl.SSLSessionContext interface is agrouping ofSSLSessionobjects associated with a single entity. For example, it could beassociated with a server or client that participates in manysessions concurrently. The methods in this interface enable theenumeration of all sessions in a context and allow lookup ofspecific sessions via their session IDs.

AnSSLSessionContext may optionally be obtainedfrom anSSLSession by calling the SSLSessiongetSessionContext() method. The context may beunavailable in some environments, in which case thegetSessionContext() method returns null.

The SSLSessionBindingListenerInterface

Thejavax.net.ssl.SSLSessionBindingListenerinterface is implemented by objects that are notified when they arebeing bound or unbound from anSSLSession.

The SSLSessionBindingEvent Class

Thejavax.net.ssl.SSLSessionBindingEvent classdefines the event communicated to anSSLSessionBindingListenerwhen it is bound or unbound from anSSLSession.

The HandShakeCompletedListenerInterface

Thejavax.net.ssl.HandShakeCompletedListenerinterface is an interface implemented by any class that is notifiedof the completion of an SSL protocol handshake on a givenSSLSocket connection.

The HandShakeCompletedEventClass

Thejavax.net.ssl.HandShakeCompletedEvent classdefine the event communicated to aHandShakeCompletedListenerupon completion of an SSL protocol handshake on a givenSSLSocket connection.

TheHostnameVerifier Interface

If the SSL/TLS implementation's standard host name verificationlogic fails, then the implementation calls theverify() method of the class that implements thisinterface and is assigned to thisHttpsURLConnectioninstance. If the callback class can determine that the host name isacceptable given the parameters, it reports that the connectionshould be allowed. An unacceptable response causes the connectionto be terminated.

For example:

public class MyHostnameVerifier implements HostnameVerifier {public boolean verify(String hostname, SSLSession session) {// pop up an interactive dialog box// or insert additional matching logicif (good_address) {return true;} else {return false;}}}//...deleted...HttpsURLConnection urlc = (HttpsURLConnection)(new URL("https://www.example.com/")).openConnection();urlc.setHostnameVerifier(new MyHostnameVerifier());

SeeThe HttpsURLConnectionClass for more information about how to assign theHostnameVerifier to theHttpsURLConnection.

TheX509Certificate Class

Many secure socket protocols perform authentication using publickey certificates, also called X.509 certificates. This is thedefault authentication mechanism for the SSL/TLS protocols.

Thejava.security.cert.X509Certificate abstractclass provides a standard way to access the attributes of X.509certificates.


Note: Thejavax.security.cert.X509Certificate class is supportedonly for backward compatibility with previous (1.0.x and 1.1.x)versions of JSSE. New applications should use thejava.security.cert.X509Certificate class instead.


TheAlgorithmConstraints Interface

Thejava.security.AlgorithmConstraints interface isused for controlling allowed cryptographic algorithms.AlgorithmConstraints defines threepermits() methods. These methods tell whether analgorithm name or a key is permitted for certain cryptographicfunctions. Cryptographic functions are represented by a set ofCryptoPrimitive, which is an enumeration containingfields likeSTREAM_CIPHER,MESSAGE_DIGEST, andSIGNATURE.

Thus, anAlgorithmConstraints implementation cananswer questions like: Can I use this key with this algorithm forthe purpose of a cryptographic operation?

AnAlgorithmConstraints object can be associatedwith anSSLParameters object by using the newsetAlgorithmConstraints() method. The currentAlgorithmConstraints object for anSSLParameters object is retrieved using thegetAlgorithmConstraints() method.

TheStandardConstants Class

TheStandardConstants class is used to representstandard constants definitions in JSSE.

StandardConstants.SNI_HOST_NAME represents a domainname server (DNS) host name in aServerName Indication (SNI) extension, which can be used wheninstantiating anSNIServerName orSNIMatcher object.

The SNIServerNameClass

An instance of the abstractSNIServerName classrepresents a server name in theServer NameIndication (SNI) extension. It is instantiated using the typeand encoded value of the specified server name.

You can use thegetType() andgetEncoded() methods to return the server name typeand a copy of the encoded server name value, respectively. Theequals() method can be used to check if some otherobject is "equal" to this server name. ThehashCode()method returns a hash code value for this server name. To get astring representation of the server name (including the server nametype and encoded server name value), use thetoString() method.

The SNIMatcherClass

An instance of the abstractSNIMatcher classperforms match operations on anSNIServerName object.Servers can use information from theServerName Indication (SNI) extension to decide if a specificSSLSocket orSSLEngine should accept aconnection. For example, when multiple "virtual" or "name-based"servers are hosted on a single underlying network address, theserver application can use SNI information to determine whetherthis server is the exact server that the client wants to access.Instances of this class can be used by a server to verify theacceptable server names of a particular type, such as hostnames.

TheSNIMatcher class is instantiated using thespecified server name type on which match operations will beperformed. To match a givenSNIServerName, use thematches() method. To return the server name type ofthe givenSNIMatcher object, use thegetType() method.

The SNIHostNameClass

An instance of theSNIHostName class (which extendstheSNIServerName class) represents a server name oftype "host_name" (seeTheStandardConstants Class) in theServerName Indication (SNI) extension. To instantiate anSNIHostName, specify the fully qualified DNS host nameof the server (as understood by the client) as aString argument. The argument is illegal in thefollowing cases:

You can also instantiate anSNIHostName byspecifying the encoded host name value as a byte array. This methodis typically used to parse the encoded name value in a requestedSNI extension. Otherwise, use theSNIHostName(Stringhostname) constructor. Theencoded argument isillegal in the following cases:


Note: Theencoded byte arraypassed in as an argument is cloned to protect against subsequentmodification.


To return the host name of anSNIHostName object inUS-ASCII encoding, use thegetAsciiName() method. Tocompare a server name to another object, use theequals() method (comparison isnotcase-sensitive). To return a hash code value of anSNIHostName, use thehashCode() method.To return a string representation of anSNIHostName,including the DNS host name, use thetoString()method.

You can create anSNIMatcher object for anSNIHostName object by passing a regular expressionrepresenting one or more host names to match to thecreateSNIMatcher() method.

Customizing JSSE

JSSE includes a standard implementation that can be customizedby plugging in different implementations or specifying the defaultkeystore, and so on. The following tables summarize whichaspects can be customized, what the defaults are, and whichmechanisms are used to provide customization.

Some of the customizations are done by setting Security Propertyor system property values. Sections following the table explainhow to set such property values.

The following table shows items that are customized by setting ajava.security.Security property:

Security PropertyCustomized ItemDefault ValueNotes
cert.provider.x509v1Customizing the X509Certificate ImplementationX509Certificate implementation from OracleNone
JCE encryption algorithms used by theSunJSSE providerGive alternative JCE algorithm providers a higher preference orderthan the SunJCE provider; seeCustomizing the EncryptionAlgorithm Providers.SunJCE implementationsNone
jdk.certpath.disabledAlgorithms1Disabled certificate verification cryptographic algorithm (seeDisabled and Restricted Cryptographic Algorithms)MD2, MD5, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, include jdk.disabled.namedCurves, SHA1 usage SignedJAR & denyAfter 2019-01-012None
jdk.tls.disabledAlgorithms1Disabled and Restricted Cryptographic AlgorithmsSSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, ECDH, include jdk.disabled.namedCurves2Disables specific algorithms (protocols versions, cipher suites,key exchange mechanisms, etc.) that will not be negotiated forTLS connections, even if they are enabled explicitly in anapplication
jdk.tls.keyLimits1 (since JDK 8u261)Limiting Amount of Data Algorithms May Encrypt with a Set of KeysAES/GCM/NoPadding KeyUpdate 2^37Limits the amount of data an algorithm may encrypt with a specificset of keys; once this limit is reached, a KeyUpdate post-handshakemessage is sent, which requests that the current set of keys beupdated.
jdk.tls.legacyAlgorithms1Legacy Cryptographic AlgorithmsK_NULL, C_NULL, M_NULL, DH_anon, ECDH_anon, RC4_128, RC4_40, DES_CBC, DES40_CBC, 3DES_EDE_CBC2Specifies which algorithms are considered legacy algorithms, whichare not negotiated during TLS security parameters negotiationunless there are no other candidates.
jdk.tls.maxCertificateChainLength1Certificate chain handling10Specifies the maximum allowed length of the certificate chain in TLS handshaking.
jdk.tls.maxHandshakeMessageSize1Certificate chain handling32768 (32 kilobytes)Specifies the maximum allowed size, in bytes, for the handshake message in TLS handshaking.
jdk.tls.server.defaultDHEParameters1Diffie-Hellman groupsSafe prime Diffie-Hellman groups in JDK TLS implementationDefines default finite field Diffie-Hellman ephemeral (DHE)parameters for Transport Layer Security (TLS) processing
ocsp.enable1Client-Driven OCSP and OCSP StaplingfalseEnables client-driven Online Certificate Status Protocol (OCSP).You must also enable revocation checking; seeSetting up a Java Client to use Client-Driven OCSP.
security.provider.nCryptographic service provider; seeCustomizing theProvider Implementation andCustomizing the EncryptionAlgorithm ProvidersDiffers per platform; check thejava.security Security Properties file.Specify the provider in thesecurity.provider.n=line in the Security Properties file, wheren is aninteger whose value is equal or greater than 1.
ssl.KeyManagerFactory.algorithmDefault key manager factory algorithm name(seeCustomizing theDefault Key Managers and Trust Managers)SunX509None
ssl.ServerSocketFactory.provider1DefaultSSLServerSocketFactory implementationSSLServerSocketFactory implementation from OracleNone
ssl.SocketFactory.provider1DefaultSSLSocketFactory implementationSSLSocketFactory implementation from OracleNone
ssl.TrustManagerFactory.algorithmDefault trust manager factory algorithm name(seeCustomizing theDefault Key Managers and Trust Managers)PKIXNone

1This Security Property iscurrently used by the JSSE implementation, but it is not guaranteed to beexamined and used by other implementations. If it is examined by anotherimplementation, then that implementation should handle it in the same manneras the JSSE implementation does. There is no guarantee the property willcontinue to exist or be of the same type (system or Security) in futurereleases.

2The list of restricted,disabled, and legacy algorithms specified in these Security Properties maychange; see thejava.security file in your JDK installationfor the latest values.

The following table shows items that are customized by setting ajava.lang.System property.

System PropertyCustomized ItemDefaultNotes
com.sun.net.ssl.checkRevocation1Revocation checkingfalseYou must enable revocation checking to enable client-driven OCSP;seeClient-Driven OCSP and OCSP Stapling.
Customize via port field in the HTTPS URL*Default HTTPS port443None
https.cipherSuites1Default cipher suites for HTTPS connections1Determined by the socket factory.This contains a comma-separated list of cipher suite namesspecifying which cipher suites to enable for use on thisHttpsURLConnection. See theSSLSocket.setEnabledCipherSuites(String[])method. Note that this method sets the preference order of theClientHello cipher suites directly from the String array passed to it.
https.protocols1Default handshaking protocols for HTTPS connections.Determined by the socket factory.This contains a comma-separated list of protocol suite namesspecifying which protocol suites to enable on thisHttpsURLConnection.SeeSSLSocket.setEnabledProtocols(String[]).
https.proxyHost1Default proxy hostNoneNone
https.proxyPort1Default proxy port80None
java.protocol.handler.pkgsSpecifying an AlternativeHTTPS Protocol ImplementationImplementation from OracleNone
javax.net.ssl.keyStore1Default keystore; seeCustomizingthe Default Keystores and Truststores, Store Types, and StorePasswordsNONEThe valueNONE may be specified. This setting is appropriate ifthe keystore is not file-based (for example, it resides in a hardwaretoken).
javax.net.ssl.keyStorePassword1Default keystore password; seeCustomizingthe Default Keystores and Truststores, Store Types, and StorePasswordsNoneIt is inadvisable to specify the password in a way that exposes itto discovery by other users. For example, specifying the password on thecommand line. To keep the password secure, have the application promptfor the password, or specify the password in a properly protected optionfile.
javax.net.ssl.keyStoreProvider1Default keystore provider; seeCustomizingthe Default Keystores and Truststores, Store Types, and StorePasswordsNoneNone
javax.net.ssl.keyStoreType1Default keystore type; seeCustomizingthe Default Keystores and Truststores, Store Types, and StorePasswordsKeyStore.getDefaultType()None
javax.net.ssl.sessionCacheSize (since JDK 8u261)Default value for the maximum number of entries in the SSL sessioncache20480The session cache size can be set by calling theSSLSessionContext.setSessionCacheSize method or by setting thejavax.net.ssl.sessionCachSize system property. If the cache size isnot set, the default value is used.
javax.net.ssl.trustStore1Default truststore; seeCustomizing the Default Keystores and Truststores, Store Types, and Store Passwordsjssecacerts, if it exists; otherwise,cacertsThe valueNONE may be specified. This setting is appropriate ifthe truststore is not file-based (for example, it resides in ahardware token).
javax.net.ssl.trustStorePassword1Default truststore password; seeCustomizing the Default Keystores and Truststores, Store Types, and Store PasswordsNoneIt is inadvisable to specify the password in a way that exposes itto discovery by other users. For example, specifying the password onthe command line. To keep the password secure, have the applicationprompt for the password, or specify the password in a properlyprotected option file.
javax.net.ssl.trustStoreProvider1Default truststore provider; seeCustomizing the Default Keystores and Truststores, Store Types, and Store PasswordsNoneNone
javax.net.ssl.trustStoreType1Default truststore type; seeCustomizing the Default Keystores and Truststores, Store Types, and Store PasswordsKeyStore.getDefaultType()None
jdk.tls.acknowledgeCloseNotify1 (since JDK 8u261)Specifying that close_notify Alert Is Sent When One Is ReceivedfalseIf the system property is set to true, then when the client orserver receives a close_notify alert, it sends a correspondingclose_notify alert and the connection is duplex closed.
jdk.tls.client.cipherSuites1Client-side default enabled cipher suites; seeSpecifying Default Enabled Cipher Suites.SeeSunJSSE Cipher Suites for a list of currently implementedSunJSSE cipher suites for this JDK release, sorted by order ofpreference.Caution: These system properties can be used to configure weakcipher suites, or the configured cipher suites may be weak in thefuture. It is not recommended that you use these system propertieswithout understanding the risks.
jdk.tls.client.disableExtensions1Configuring Default ExtensionsNoneBlocks extensions used on the client side.
jdk.tls.client.protocols1Default handshaking protocols for TLS clients. SeeThe SunJSSE Provider.NoneTo enable specificSunJSSE protocols on the client, specify themin a comma-separated list within quotation marks; all other supportedprotocols are not enabled on the client. For example,ifjdk.tls.client.protocols="TLSv1,TLSv1.1", then thedefault protocol settings on the client for TLSv1 and TLSv1.1 areenabled, while SSLv3, TLSv1.2, TLSv1.3, and SSLv2Hello are notenabled.
jdk.tls.client.SignatureSchemes1Contains a comma-separated list of supported signature scheme names thatspecifies the signature schemes that could be used for TLS connections onthe client side.NoneUnrecognized or unsupported signature scheme names specified in theproperty are ignored. If this system property is not defined or empty, thenthe provider-specific default is used. The names are not case sensitive. Fora list of signature scheme names, seeAppendix D: Signature Schemes.
jdk.tls.ephemeralDHKeySize1Customizing the Size of Ephemeral Diffie-Hellman Keys2048 bitsNone
jdk.tls.namedGroups1Customizing the supported named groups for TLS key exchangeIf this system property is not defined or the value is empty, thenthe implementation default groups and preferences will be used.This contains a comma-separated list within quotation marks ofenabled named groups in preference order. For example:jdk.tls.namedGroups="secp521r1,secp256r1,ffdhe2048"
jdk.tls.rejectClientInitiatedRenegotiation1Rejects client-initiated renegotiation on the server side. If this systemproperty istrue, then the server will not accept client initiatedrenegotiations and will fail with a fatalhandshake_failure alert.Rejects server-side client-initialized renegotiation.falseNone
jdk.tls.server.cipherSuites1Server-side default enabled cipher suites. SeeSpecifying Default Enabled Cipher SuitesSeeSunJSSE Cipher Suitesto determine which cipher suites areenabled by defaultCaution: These system properties can be used to configure weakcipher suites, or the configured cipher suites may be weak in thefuture. It is not recommended that you use these system propertieswithout understanding the risks.
jdk.tls.server.disableExtensions1Configuring Default ExtensionsNoneBlocks extensions used on the server side.
jdk.tls.server.protocols1 (since JDK 8u261)Default handshaking protocols for TLS servers. SeeThe SunJSSE Provider.NoneTo configure the default enabled protocol suite in the server sideof aSunJSSE provider, specify the protocols in a comma-separated listwithin quotation marks. The protocols in this list are standard SSLprotocol names as described inJava Cryptography Architecture (JCA) Standard Algorithm Name Documentation for JDK 8.Note that this system property impacts only the default protocol suite(SSLContext of the algorithms SSL and TLS). If an applicationuses a version-specificSSLContext (SSLv3, TLSv1, TLSv1.1, TLSv1.2, or TLSv1.3), or sets the enabled protocol versionexplicitly, this system property has no impact.
jdk.tls.server.SignatureSchemes1Contains a comma-separated list of supported signature scheme names thatspecifies the signature schemes that could be used for TLS connections onthe server side.NoneUnrecognized or unsupported signature scheme names specified in theproperty are ignored. If this system property is not defined or empty, thenthe provider-specific default is used. The names are not case sensitive. Fora list of signature scheme names, seeAppendix D: Signature Schemes.
jsse.enableFFDHEExtension1 (since JDK 8u261)Enables or disables Finite Field Diffie-Hellman Ephemeral (FFDHE)parameters for TLS key exchangetrueFFDHE is a TLS extension defined in RFC 7919. It enablesTLS connections to use known finite field Diffie-Hellman groups.Some very old TLS vendors may not be able handle TLS extensions. Inthis case, set this property to false to disable the FFDHE extension.
jsse.enableMFLNExtension1 (since JDK 8u261)Customizing Maximum Fragment Length Negotiation (MFLN) ExtensionfalseNone
jsse.enableSNIExtension1Server Name Indication optiontrueServer Name Indication (SNI) is a TLS extension, defined in RFC6066. It enables TLS connections to virtual servers, in which multipleservers for different network names are hosted at a single underlyingnetwork address. Some very old TLS vendors may not be able handle TLSextensions. In this case, set this property to false to disable theSNI extension
jsse.SSLEngine.acceptLargeFragments1Default sizing buffers for large TLS packetsNoneSetting this system property to true,SSLSession will size buffersto handle large data packets by default (see the note inSSLSession and ExtendedSSLSession.This may cause applicationsto allocate unnecessarily largeSSLEngine buffers. Instead,applications should dynamically check for buffer overflow conditionsand resize buffers as appropriate (seeUnderstanding SSLEngine Operation Statuses).
jdk.tls.client.enableStatusRequestExtension1Setting up a Java Client to use Client-Driven OCSPfalseIf true, then the status_request and status_request_v2 extensionsare enabled, and processing for CertificateStatus messages sent by theserver is enabled.
jdk.tls.server.enableStatusRequestExtension1Setting Up a Java Server to Use OCSP StaplingfalseIf true, then server-side support for OCSP stapling is enabled
sun.security.ssl.allowLegacyHelloMessagesAllow legacy Hello Messages (Renegotiations)trueIf true, then allow the peer to handshake without requiring theproper RFC 5746 messages. SeeDescription of the Phase 2 FixinTransportLayer Security (TLS) Renegotiation Issue for more information.
sun.security.ssl.allowUnsafeRenegotiationAllow unsafe SSL/TLS renegotiationsfalseIf true, then permit full (unsafe) legacy negotiation. SeeDescription of the Phase 2 FixinTransportLayer Security (TLS) Renegotiation Issue for more information.

1This system propertyis currently used by the JSSE implementation, but it is not guaranteed tobe examined and used by other implementations. If it is examined byanother implementation, then that implementation should handle it in thesame manner as the JSSE implementation does. There is no guarantee theproperty will continue to exist or be of the same type (system orSecurity) in future releases.

How to Specify a java.security.Security Property

You can customize some aspects of JSSE by setting securityproperties. You can set a Security Property either statically ordynamically:

How to Specify a java.lang.System Property

You can customize some aspects of JSSE by setting systemproperties. There are several ways to set these properties:

Enabling TLS 1.3

JDK 8u261 and later includes an implementation of the Transport LayerSecurity (TLS) 1.3 specification (RFC 8446).

TLS 1.3 is enabled for the defaultSSLContext (SSLorTLS) at the client endpoint.

TLS 1.3 Not Directly Compatible with Previous Versions

TLS 1.3 is not directly compatible with previous versions. Although TLS 1.3 can be implemented with a backward-compatibility mode, there are still several compatibility risks to consider when upgrading to TLS 1.3:

Customizing the X509Certificate Implementation

The X509Certificate implementation returned by theX509Certificate.getInstance() method is by default theimplementation from the JSSE implementation.

You can optionally cause a different implementation to bereturned. To do so, specify the name (and package) of the otherimplementation's class as the value of aSecurity Property namedcert.provider.x509v1. For example, if the class iscalledMyX509CertificateImpl and it appears in thecom.cryptox package, then you should add the followingline to the Security Properties file:

cert.provider.x509v1=com.cryptox.MyX509CertificateImpl

Specifying Default Enabled Cipher Suites

You can specify the default enabled cipher suites in yourapplication or with the system propertiesjdk.tls.client.cipherSuites andjdk.tls.server.cipherSuites.


Note: The actual use of enabled cipher suites is restricted by algorithm constraints.


The set of cipher suites to enable by default is determined by one of the following ways in this order of preference:

  1. Explicitly set by application
  2. Specified by system property
  3. Specified by JSSE provider defaults

For example, explicitly setting the default enabled cipher suites in your application overrides settings specified injdk.tls.client.cipherSuites orjdk.tls.server.cipherSuites as well as JSSE provider defaults.

Explicitly Set by Application

You can set which cipher suites are enabled with one of the following methods:

Specified by System Property

The system propertyjdk.tls.client.cipherSuitesspecifies the default enabled cipher suites on the client side;jdk.tls.server.cipherSuites specifies those on theserver side.

The syntax of the value of these two system properties is acomma-separated list of supported cipher suite names.Unrecognized or unsupported cipher suite names that are specifiedin these properties are ignored. SeeJava Cryptography Architecture (JCA) Standard Algorithm Name Documentation for JDK 8 forstandard JSSE cipher suite names.


Note: These system properties are currently supported by Oracle JDK. They are not guaranteed to be supported by other JDK implementations.



Caution: These system properties can be used to configure weak cipher suites, or the configured cipher suites may be weak in the future. It is not recommended that you use these system properties without understanding the risks.


Specified by JSSE Provider Defaults

Each JSSE provider has its own default enabled cipher suites.SeeThe SunJSSEProvider inJava Cryptography Architecture OracleProviders Documentation for JDK 8 for the cipher suite namessupported by theSunJSSE provider and which ones that are enabledby default.

Specifying an Alternative HTTPS Protocol Implementation

You can communicate securely with an SSL-enabled web server byusing the HTTPS URL scheme for thejava.net.URL class.The JDK provides a default HTTPS URL implementation.

If you want an alternative HTTPS protocol implementation to beused, set thejava.protocol.handler.pkgs system property toinclude the new class name.This action causes the specified classes to be found and loadedbefore the JDK default classes. See thejava.net.URLclass documentation for details.


Note: In past JSSE releases, you had to set thejava.protocol.handler.pkgs system property during JSSEinstallation. This step is no longer required unless you want toobtain an instance ofcom.sun.net.ssl.HttpsURLConnection. For moreinformation, seeCode Using theHttpsURLConnection Class in the "Troubleshooting" section.


Customizing the Provider Implementation

JDK 1.4 and later releases come standard with a JSSECryptographic Service Provider, orprovider for short, namedSunJSSE. Providers are essentially packages that implement one ormore engine classes for specific cryptographic algorithms. The JSSEengine classes areSSLContext,KeyManagerFactory, andTrustManagerFactory. For more information aboutproviders and engine classes, see theJava Cryptography ArchitectureReference Guide.


Note: The transformation strings used whenSunJSSE callsCipher.getInstance() are"RSA/ECB/PKCS1Padding", "RC4", "DES/CBC/NoPadding", and"DESede/CBC/NoPadding". For further information about theCipher class and transformation strings see theJava Cryptography ArchitectureReference Guide.


Before it can be used, a provider must be registered, eitherstatically or dynamically. You do not need to register the SunJSSEprovider because it is preregistered. If you want to use otherproviders, read the following sections to see how to registerthem.

Registering the Cryptographic Service Provider Statically

You register a provider statically by adding a line of thefollowing form to theSecurity Propertiesfile:

security.provider.n=providerClassName

This declares a provider, and specifies its preference ordern. The preference order is the order in whichproviders are searched for requested algorithms (when no specificprovider is requested). "1" is the most preferred, followed by "2",and so on.

TheproviderClassName is the fully qualified name of theprovider class. You obtain this name from the provider vendor.

The standard security provider and the SunJSSE provider shippedwith JDK 6 are automatically registered for you; the followinglines appear in thejava.security Security Propertiesfile to register theSunJCE security provider withpreference order 5 and the SunJSSE provider with preference order4:

security.provider.1=sun.security.pkcs11.SunPKCS11 \${java.home}/lib/security/sunpkcs11-solaris.cfgsecurity.provider.2=sun.security.provider.Sunsecurity.provider.3=sun.security.rsa.SunRsaSignsecurity.provider.4=com.sun.net.ssl.internal.ssl.Providersecurity.provider.5=com.sun.crypto.provider.SunJCEsecurity.provider.6=sun.security.jgss.SunProvidersecurity.provider.7=com.sun.security.sasl.Provider

To use another JSSE provider, add a line registering the otherprovider, giving it whatever preference order you prefer.

You can have more than one JSSE provider registered at the sametime. The registered providers may include differentimplementations for different algorithms for different engineclasses, or they may have support for some or all of the same typesof algorithms and engine classes. When a particular engine classimplementation for a particular algorithm is searched for, if nospecific provider is specified for the search, then the providersare searched in preference order and the implementation from thefirst provider that supplies an implementation for the specifiedalgorithm is used.

Registering the Cryptographic Service Provider Dynamically

Instead of registering a provider statically, you can add theprovider dynamically at runtime by calling theSecurity.addProvider() method at the beginning of yourprogram. For example, to dynamically add a provider whose providerclass name isMyProvider and whoseMyProvider class resides in thecom.ABCpackage, you would call:

Security.addProvider(new com.ABC.MyProvider());

TheSecurity.addProvider() method adds thespecified provider to the next available preference position.

This type of registration is not persistent and can only be doneby a program with sufficient permissions.

Customizing the Default Keystores and Truststores, Store Types, and Store Passwords

Whenever a defaultSSLSocketFactory orSSLServerSocketFactory is created (via a call toSSLSocketFactory.getDefault orSSLServerSocketFactory.getDefault), and this defaultSSLSocketFactory (orSSLServerSocketFactory) comes from the JSSE referenceimplementation, a defaultSSLContext is associatedwith the socket factory. (The default socket factory will come fromthe JSSE implementation.)

This defaultSSLContext is initialized with adefaultKeyManager and a defaultTrustManager. If a keystore is specified by thejavax.net.ssl.keyStore systemproperty and an appropriatejavax.net.ssl.keyStorePassword system property, then theKeyManager created by the defaultSSLContext will be aKeyManagerimplementation for managing the specified keystore. (The actualimplementation will be as specified inCustomizing the Default Key and TrustManagers.) If no such system property is specified, then thekeystore managed by theKeyManager will be a new emptykeystore.

Generally, the peer acting as the server in the handshake willneed a keystore for its KeyManager in order to obtain credentialsfor authentication to the client. However, if one of the anonymouscipher suites is selected, then the server'sKeyManager keystore is not necessary. And, unless theserver requires client authentication, the peer acting as theclient does not need aKeyManager keystore. Thus, inthese situations it may be OK if nojavax.net.ssl.keyStore system property value isdefined.

Similarly, if a truststore is specified by thejavax.net.ssl.trustStore system property, then theTrustManager created by the defaultSSLContext will be aTrustManagerimplementation for managing the specified truststore. In this case,if such a property exists but the file it specifies does not, thenno truststore is used. If nojavax.net.ssl.trustStoreproperty exists, then a default truststore is searched for. If atruststore namedjava-home/lib/security/jssecacerts isfound, it is used. If not, then a truststore namedjava-home/lib/security/cacerts is searched for and used(if it exists). Finally, ifa truststore is still not found, then the truststore managed by theTrustManager will be a new empty truststore.


Note: The JDK ships with a limited number oftrusted root certificates in thejava-home/lib/security/cacerts file. As documented inkeytool referencepages, it is your responsibility to maintain (that is, add andremove) the certificates contained in this file if you use thisfile as a truststore.

Depending on the certificate configuration of the servers thatyou contact, you may need to add additional root certificates.Obtain the needed specific root certificates from the appropriatevendor.


If thejavax.net.ssl.keyStoreType and/orjavax.net.ssl.keyStorePassword system properties arealso specified, then they are treated as the defaultKeyManager keystore type and password, respectively.If no type is specified, then the default type is that returned bytheKeyStore.getDefaultType() method, which is thevalue of thekeystore.type Security Property, or "jks"if no such Security Property is specified. If no keystore passwordis specified, then it is assumed to be a blank string "".

Similarly, if thejavax.net.ssl.trustStoreTypeand/orjavax.net.ssl.trustStorePassword systemproperties are also specified, then they are treated as the defaulttruststore type and password, respectively. If no type isspecified, then the default type is that returned by theKeyStore.getDefaultType() method. If no truststorepassword is specified, then it is assumed to be a blank string"".


Note: This section describes the current JSSEreference implementation behavior. The system properties describedin this section are not guaranteed to continue to have the samenames and types (system or security) or even to exist at all infuture releases. They are also not guaranteed to be examined andused by any other JSSE implementations. If theyare examinedby an implementation, then that implementation should handle themin the same manner as the JSSE reference implementation does, asdescribed herein.


Customizing the Default Key Managers and Trust Managers

As noted inCustomizing the DefaultKeystores and Truststores, Store Types, and Store Passwords,whenever a defaultSSLSocketFactory orSSLServerSocketFactory is created, and this defaultSSLSocketFactory (orSSLServerSocketFactory) comes from the JSSE referenceimplementation, a defaultSSLContext is associatedwith the socket factory.

This defaultSSLContext is initialized with aKeyManager and aTrustManager. TheKeyManager and/orTrustManager suppliedto the defaultSSLContext will be an implementationfor managing the specified keystore or truststore, as described inthe aforementioned section.

TheKeyManager implementation chosen is determinedby first examining thessl.KeyManagerFactory.algorithmSecurity Property. If such a propertyvalue is specified, then aKeyManagerFactoryimplementation for the specified algorithm is searched for. Theimplementation from the first provider that supplies animplementation is used. ItsgetKeyManagers() method iscalled to determine theKeyManager to supply to thedefaultSSLContext. Technically,getKeyManagers() returns an array ofKeyManager objects, oneKeyManager foreach type of key material. If no such Security Property value isspecified, then the default value of SunX509 is used to perform thesearch.


Note: AKeyManagerFactoryimplementation for the SunX509 algorithm is supplied by the SunJSSEprovider. TheKeyManager that it specifies is ajavax.net.ssl.X509KeyManager implementation.


Similarly, theTrustManager implementation chosenis determined by first examining thessl.TrustManagerFactory.algorithm Security Property.If such a property value is specified, then aTrustManagerFactory implementation for the specifiedalgorithm is searched for. The implementation from the firstprovider that supplies an implementation is used. ItsgetTrustManagers() method is called to determine theTrustManager to supply to the defaultSSLContext. Technically,getTrustManagers() returns an array ofTrustManager objects, oneTrustManagerfor each type of trust material. If no such Security Property valueis specified, then the default value of PKIX is used to perform thesearch.


Note: ATrustManagerFactoryimplementation for the PKIX algorithm is supplied by the SunJSSEprovider. TheTrustManager that it specifies is ajavax.net.ssl.X509TrustManager implementation.



Note: This section describes the current JSSEreference implementation behavior. The system properties describedin this section are not guaranteed to continue to have the samenames and types (system or security) or even to exist at all infuture releases. They are also not guaranteed to be examined andused by any other JSSE implementations. If theyare examinedby an implementation, then that implementation should handle themin the same manner as the JSSE reference implementation does, asdescribed herein.


Disabled and Restricted Cryptographic Algorithms

In some environments, certain algorithms or key lengths may be undesirablewhen using TLS. The Oracle JDK uses thejdk.certpath.disabledAlgorithms andjdk.tls.disabledAlgorithm Security Properties to disable algorithms during TLS protocol negotiation, including version negotiation, cipher suites selection, peer authentication, and key exchange mechanisms. Note that these Security Properties are not guaranteed to be used by other JDK implementations. See the<java-home>/lib/security/java.security file forinformation about the syntax of these Security Properties and their currentactive values.

If you require a particular condition, you can reactivate it by eitherremoving the associated value in the Security Property in thejava.security file or dynamically setting the proper SecurityProperty before JSSE is initialized.

Note that these Security Properties effectively create a third set of cipher suites, Disabled. The following list describes these three sets:

Legacy Cryptographic Algorithms

In some environments, a certain algorithm may be undesirable but it cannot bedisabled because of its use in legacy applications. Legacy algorithms may still be supported, but applications should not use them as the security strength of legacy algorithms is usually not strong enough. During TLS security parameters negotiation, legacy algorithms are not negotiated unless there are no other candidates. The Security Propertyjdk.tls.legacyAlgorithmsspecifies which algorithms the Oracle JDK considers as legacy algorithms. See the<java-home>/lib/security/java.security file for the syntax ofthis Security Property.


Note:


Customizing the Encryption Algorithm Providers

The SunJSSE provider uses the SunJCE implementation for all itscryptographic needs. Although it is recommended that you leave theprovider at its regular position, you can use implementations fromother JCA or JCE providers by registering thembefore theSunJCE provider. Thestandard JCAmechanism can be used to configure providers, either staticallyvia the Security Properties filejava-home/lib/security/java.security, or dynamically viatheaddProvider() orinsertProviderAt()method in thejava.security.Security class.

Customizing the Size of Ephemeral Diffie-Hellman Keys

In TLS connections, ephemeral Diffie-Hellman (DH) keys may be usedinternally during the handshaking. The SunJSSE provider provides a flexibleapproach to customize the strength of the ephemeral DH key size during TLShandshaking.

Diffie-Hellman (DH) keys of sizes less than 2048 bits have been deprecatedbecause of their insufficient strength. You can customize the ephemeral DH keysize with the system propertyjdk.tls.ephemeralDHKeySize. Thissystem property does not impact DH key sizes inServerKeyExchangemessages for exportable cipher suites. It impacts only the DHE_RSA, DHE_DSS, andDH_anon-based cipher suites in the JSSE Oracle provider.

You can specify one of the following values for this property:

The following table summarizes the minimum and maximum acceptable DH keysizes for each of the possible values for the system propertyjdk.tls.ephemeralDHKeySize:

Value ofjdk.tls.ephemeralDHKeySizeUndefinedlegacymatchedInteger value (fixed)
Exportable DH key size512512512512
Non-exportable anonymous cipher suites20487682048A valid integer between 1024 and 8192 in multiples of 64, inclusively: Afixed ephemeral DH key size of the specified value, in bits, will be used fornon-exportable cipher suites.
Authentication certificate2048768The key size is the same as the authentication certificate unless the key isless than 1024 bits or greater than 2048 bits. If the key is less than 1024bits, then a DH key of 1024 bits is used. If the key is greater than 2048 bits,then a DH key of 2048 bits is used.

Consequently, you may use the values 1024 or 2048 only.

The fixed key size is specified by a valid integer property value, whichmust be between 1024 and 8192 in multiples of 64, inclusively.

Customizing Maximum Fragment Length Negotiation (MFLN) Extension

In order to negotiate smaller maximum fragment lengths, clients have anoption to include an extension of type max_fragment_length in theClientHello message. A system property,jsse.enableMFLNExtension,can be used to enable or disable the MFLN extension for TLS.

Maximum Fragment Length Negotiation

It may be desirable for constrained TLS clients to negotiate asmaller maximum fragment length due to memory limitations or bandwidthlimitations. In order to negotiate smaller maximum fragment lengths,clients have an option to include an extension of typemax_fragment_length in the (extended) ClientHello message. See RFC 6066.

Once a maximum fragment length has been successfully negotiated, theTLS client and server can immediately begin fragmenting messages(including handshake messages) to ensure that no fragment larger than thenegotiated length is sent.

System Property jsse.enableMFLNExtension

A system propertyjsse.enableMFLNExtension is defined toenable or disable the MFLN extension. Thejsse.enableMFLNExtensionis disabled by default.

The value of the system property can be set as follows:

System PropertyDescription
jsse.enableMFLNExtension=trueEnable the MFLN extension. If the returned value ofSSLParameters.getMaximumPacketSize()is less than (212 + header-size) the maximum fragment lengthnegotiation extension would be enabled.
jsse.enableMFLNExtension=falseDisable the MFLN extension.

Limiting Amount of Data Algorithms May Encrypt with a Set of Keys

You can specify a limit on the amount of data an algorithm may encrypt witha specific set of keys with thejdk.tls.keyLimits SecurityProperty. Once this limit is reached, a KeyUpdate post-handshake message issent, which requests that the current set of keys be updated. This SecurityProperty is only for symmetrical ciphers with TLS 1.3.

The syntax for this property is as follows:

jdk.tls.keyLimits=KeyLimit { ,KeyLimit }KeyLimit:AlgorithmNameKeyUpdateLength

For example, the following specifies that a KeyUpdate message is sent once the algorithm AES/GCM/NoPadding has encrypted 237 bytes:

jdk.tls.keyLimits=AES/GCM/NoPadding KeyUpdate 2^37

Specifying that close_notify Alert Is Sent When One Is Received

If thejdk.tls.acknowledgeCloseNotify system property isset to true, then when the client or server receives a close_notifyalert, it sends a corresponding close_notify alert and the connection isduplex closed.

TLS 1.2 and earlier versions use a duplex-close policy. However, TLS1.3 uses a half-close policy, which means that the inbound and theoutbound close_notify alerts are independent. When upgrading to TLS 1.3,unexpected behavior can occur if your application shuts down theTLS connection by using only one of theSSLEngine.closeInbound()orSSLEngine.closeOutbound() methods but not both on eachside of the connection. If your application unexpectedly hangs or timesout when the underlying TLS transportation is not duplex closed,you may need to set this property to true.

Note that when a TLS connection is no longer needed, the clientand server applications should each close both sides of their respectiveconnection.

Configuring Default Extensions

Some TLS implementations may not handle unknown extensions properly. As a result, you might encounter unexpected interoperability issues when the JDK introduces new extensions. Two system properties enable you to customize default extensions:

If an extension is disabled, then it won't be produced nor processed in handshake messages.

The value of these system properties is a list of comma-separated standard TLS extension names. SeeTransport Layer Security (TLS) Extensions for a list of these names. Extension names are case-sensitive, and unknown, unsupported misspelled and duplicated names are ignored.


Note: Although system properties exist that enable and disable specific TLS extensions, such asjsse.enableMFLNExtension,jsse.enableSNIExtension, andjsse.enableSNIExtension, an extension won't be enabled if it's disabled throughjdk.tls.client.disableExtensions orjdk.tls.server.disableExtensions, even though it could be enabled though the corresponding system property.


Determine X.509 Certificate Revocation Status with OCSP

Use the Online Certificate Status Protocol (OCSP) to determine theX.509 certificate revocation status during the Transport Layer Security(TLS) handshake. SeeClient-Driven OCSP and OCSP Stapling.

Hardware Acceleration andSmartcard Support

TheJava CryptographyArchitecture (JCA) is a set of packages that provides aframework and implementations for encryption, key generation andkey agreement, and message authentication code (MAC) algorithms.The SunJSSE provider uses JCA exclusively for all of itscryptographic operations and can automatically take advantage ofJCE features and enhancements, including JCA's support for PKCS#11. Thissupport enables the SunJSSE provider to use hardware cryptographicaccelerators for significant performance improvements and to usesmartcards as keystores for greater flexibility in key and trustmanagement.

Use of hardware cryptographic accelerators is automatic if JCAhas been configured to use the Oracle PKCS#11 provider, which inturn has been configured to use the underlying acceleratorhardware. The provider must be configured before any other JCAproviders in the provider list. For details on how to configure theOracle PKCS#11 provider, see thePKCS#11Guide.

Configuring JSSEto Use Smartcards as Keystores and Truststores

Support for PKCS#11 in JCA also enables access to smartcards asa keystore. For details on how to configure the type and locationof the keystores to be used by JSSE, see theCustomizing JSSE section. Touse a smartcard as a keystore or truststore, set thejavax.net.ssl.keyStoreType andjavax.net.ssl.trustStoreType system properties,respectively, topkcs11, and set thejavax.net.ssl.keyStore andjavax.net.ssl.trustStore system properties,respectively, toNONE. To specify the use of aspecific provider, use thejavax.net.ssl.keyStoreProvider andjavax.net.ssl.trustStoreProvider system properties(for example, set them toSunPKCS11-joe). By usingthese properties, you can configure an application that previouslydepended on these properties to access a file-based keystore to usea smartcard keystore with no changes to the application.

Some applications request the use of keystores programmatically.These applications can continue to use the existing APIs toinstantiate aKeystore and pass it to its key managerand trust manager. If theKeystore instance refers toa PKCS#11 keystore backed by a Smartcard, then the JSSE applicationwill have access to the keys on the smartcard.

Multiple and Dynamic Keystores

smartcards (and other removable tokens) have additionalrequirements for anX509KeyManager. Differentsmartcards can be present in a smartcard reader during the lifetimeof a Java application, and they can be protected using differentpasswords.

Thejava.security.KeyStore.Builderclass abstracts the construction and initialization of aKeyStore object. It supports the use ofCallbackHandler for password prompting, and itssubclasses can be used to support additional features as desired byan application. For example, it is possible to implement aBuilder that allows individualKeyStoreentries to be protected with different passwords. Thejavax.net.ssl.KeyStoreBuilderParameters class then canbe used to initialize a KeyManagerFactory using one or more oftheseBuilder objects.

AX509KeyManager implementation in the SunJSSEprovider called NewSunX509 supports these parameters. If multiplecertificates are available, it attempts to pick a certificate withthe appropriate key usage and prefers valid to expiredcertificates.

The following example illustrates how to tell JSSE to use both aPKCS#11 keystore (which might in turn use a smartcard) and aPKCS#12 file-based keystore.

import javax.net.ssl.*;import java.security.KeyStore.*;...// Specify keystore builder parameters for PKCS#11 keystoresBuilder scBuilder = Builder.newInstance("PKCS11", null,new CallbackHandlerProtection(myGuiCallbackHandler));// Specify keystore builder parameters for a specific PKCS#12 keystoreBuilder fsBuilder = Builder.newInstance("PKCS12", null,new File(pkcsFileName), new PasswordProtection(pkcsKsPassword));// Wrap them as key manager parametersManagerFactoryParameters ksParams = new KeyStoreBuilderParameters(Arrays.asList(new Builder[] { scBuilder, fsBuilder }) );// Create KeyManagerFactoryKeyManagerFactory factory = KeyManagerFactory.getInstance("NewSunX509");// Pass builder parameters to factoryfactory.init(ksParams);// Use factorySSLContext ctx = SSLContext.getInstance("TLS");ctx.init(factory.getKeyManagers(), null, null);

Kerberos Cipher Suites

The SunJSSE provider has support for Kerberos cipher suites, asdescribed inRFC2712. The following cipher suites are supported but not enabledby default:

To enable the use of these cipher suites, you must do soexplicitly. For more information, see the API documentation for theSSLEngine.setEnabledCipherSuites() andSSLSocket.setEnabledCipherSuites() methods. Aswith all other SSL/TLS cipher suites, if a cipher suite is notsupported by the peer, then it will not be selected during ciphernegotiation. Furthermore, if the application and/or server cannotacquire the necessary Kerberos credentials, then the Kerberoscipher suites also will not be selected.

The following is an example of a TLS client that will only usetheTLS_KRB5_WITH_DES_CBC_SHA cipher suite:

// Create socketSSLSocketFactory sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault();SSLSocket sslSocket = (SSLSocket) sslsf.createSocket(tlsServer, serverPort);// Enable only one cipher suiteString enabledSuites[] = { "TLS_KRB5_WITH_DES_CBC_SHA" };sslSocket.setEnabledCipherSuites(enabledSuites);

KerberosRequirements

You must have the Kerberos infrastructure set up in yourdeployment environment before you can use the Kerberos ciphersuites with JSSE. In particular, both the TLS client and servermust have accounts set up with the Kerberos Key Distribution Center(KDC). At runtime, if one or more of the Kerberos cipher suiteshave been enabled, then the TLS client and server will acquiretheir Kerberos credentials associated with their respective accountfrom the KDC. For example, a TLS server running on the machinemach1.imc.org in the Kerberos realmIMC.ORG must have an account with the namehost/mach1.imc.org@IMC.ORG and be configured to usethe KDC forIMC.ORG. For information about usingKerberos with Java SE, see theKerberos Requirementsdocument.

An application can acquire its Kerberos credentials by using theJava Authentication andAuthorization Service (JAAS) and a Kerberos login module. TheJDK comes with aKerberos login module. You can use the Kerberos cipher suiteswith JSSE with or without JAAS programming, similar to how you canuse theJava GenericSecurity Services (Java GSS) with or without JAASprogramming.

To use the Kerberos cipher suites with JSSE without JAASprogramming, you must use the index namescom.sun.net.ssl.server orother for theTLS server JAAS configuration entry, andcom.sun.net.ssl.client orother for theTLS client, and set thejavax.security.auth.useSubjectCredsOnly systemproperty to false. For example, a TLS server that is not using JAASprogramming might have the following JAAS configuration file:

com.sun.net.ssl.server {com.sun.security.auth.module.Krb5LoginModule requiredprincipal="host/mach1.imc.org@IMC.ORG"useKeyTab=truekeyTab=mach1.keytabstoreKey=true;};

An example of how to use Java GSS and Kerberos without JAASprogramming is described in theJava GSS Tutorial.You can adapt it to use JSSE by replacing Java GSS calls with JSSEcalls.

To use the Kerberos cipher suites with JAAS programming, you canuse any index name because your application is responsible forcreating the JAASLoginContext using the index name,and then wrapping the JSSE calls inside of aSubject.doAs() orSubject.doAsPrivileged() call. An example of how touse JAAS with Java GSS and Kerberos is described in theJava GSS Tutorial. Youcan adapt it to use JSSE by replacing Java GSS calls with JSSEcalls.

If you have trouble using or configuring the JSSE application touse Kerberos, see theTroubleshootingsection of the Java GSS Tutorial.

Peer IdentityInformation

To determine the identity of the peer of an SSL connection, usethegetPeerPrincipal() method in the followingclasses:

Similarly, to get the identity that was sent to the peer (toidentify the local entity), use thegetLocalPrincipal() method in these classes. ForX509-based cipher suites, these methods will return an instance ofjavax.security.auth.x500.X500Principal; for Kerberoscipher suites, these methods will return an instance ofjavax.security.auth.kerberos.KerberosPrincipal.

JSSE applications usegetPeerCertificates() andsimilar methods injavax.net.ssl.SSLSession,javax.net.ssl.HttpsURLConnection, andjavax.net.HandshakeCompletedEvent classes to obtaininformation about the peer. When the peer does not have anycertificates,SSLPeerUnverifiedException isthrown.

If the application must determine only the identity of the peeror identity sent to the peer, then it should use thegetPeerPrincipal() andgetLocalPrincipal() methods, respectively. It shouldusegetPeerCertificates() andgetLocalCertificates() methods only if it must examinethe contents of those certificates. Furthermore, the applicationmust be prepared to handle the case where an authenticated peermight not have any certificate.

Security Manager

When the security manager has been enabled, in addition to theSocketPermission needed to communicate with the peer,a TLS client application that uses the Kerberos cipher suites alsoneeds the following permission:

javax.security.auth.kerberos.ServicePermission(serverPrincipal, "initiate");

In the preceding code,serverPrincipal is the Kerberosprincipal name of the TLS server that the TLS client will becommunicating with (such ashost/mach1.imc.org@IMC.ORG). A TLS server applicationneeds the following permission:

javax.security.auth.kerberos.ServicePermission(serverPrincipal, "accept");

In the preceding code,serverPrincipal is the Kerberosprincipal name of the TLS server (such ashost/mach1.imc.org@IMC.ORG). If the server or clientmust contact the KDC (for example, if its credentials are notcached locally), then it also needs the following permission:

javax.security.auth.kerberos.ServicePermission(tgtPrincipal, "initiate");
In the preceding code,tgtPrincipal is the principal name ofthe KDC (such askrbtgt/IMC.ORG@IMC.ORG).

AdditionalKeystore Formats (PKCS12)

The PKCS#12 (PersonalInformation Exchange Syntax Standard) specifies a portableformat for storage and/or transport of a user's private keys,certificates, miscellaneous secrets, and other items. The SunJSSEprovider supplies a complete implementation of the PKCS12java.security.KeyStore format for reading and writingPKCS12 files. This format is also supported by other toolkits andapplications for importing and exporting keys and certificates,such as Netscape/Mozilla, Microsoft's Internet Explorer, andOpenSSL. For example, these implementations can export clientcertificates and keys into a file using the.p12 file nameextension.

With the SunJSSE provider, you can access PKCS12 keys throughtheKeyStore API with a keystore type of PKCS12. Inaddition, you can list the installed keys and associatedcertificates by using thekeytool command with the-storetype option set topkcs12. For moreinformation aboutkeytool, seeSecurity Tools.

Note: Unlike the JKS store format, to access a PKCS#12store, you must supply it with a password.

Server Name Indication(SNI) Extension

The SNI extension is a feature that extends the SSL/TLSprotocols to indicate what server name the client is attempting toconnect to during handshaking. Servers can use server nameindication information to decide if specificSSLSocketorSSLEngine instances should accept a connection. Forexample, when multiple virtual or name-based servers are hosted ona single underlying network address, the server application can useSNI information to determine whether this server is the exactserver that the client wants to access. Instances of this class canbe used by a server to verify the acceptable server names of aparticular type, such as host names. For more information, seesection 3 ofTLSExtensions (RFC 6066).

Developers of client applications can explicitly set the servername indication using theSSLParameters.setServerNames(List<SNIServerName>serverNames) method. The following example illustrates thisfunctionality:

SSLSocketFactory factory = ...SSLSocket sslSocket = factory.createSocket("172.16.10.6", 443);// SSLEngine sslEngine = sslContext.createSSLEngine("172.16.10.6", 443);SNIHostName serverName = new SNIHostName("www.example.com");List<SNIServerName> serverNames = new ArrayList<>(1);serverNames.add(serverName);SSLParameters params = sslSocket.getSSLParameters();params.setServerNames(serverNames);sslSocket.setSSLParameters(params);// sslEngine.setSSLParameters(params);

Developers of server applications can use theSNIMatcher class to decide how to recognize servername indication. The following two examples illustrate thisfunctionality:

Example 1

SSLSocket sslSocket = sslServerSocket.accept();SNIMatcher matcher = SNIHostName.createSNIMatcher("www\\.example\\.(com|org)");Collection<SNIMatcher> matchers = new ArrayList<>(1);matchers.add(matcher);SSLParameters params = sslSocket.getSSLParameters();params.setSNIMatchers(matchers);sslSocket.setSSLParameters(params);

Example 2

SSLServerSocket sslServerSocket = ...;SNIMatcher matcher = SNIHostName.createSNIMatcher("www\\.example\\.(com|org)");Collection<SNIMatcher> matchers = new ArrayList<>(1);matchers.add(matcher);SSLParameters params = sslServerSocket.getSSLParameters();params.setSNIMatchers(matchers);sslServerSocket.setSSLParameters(params);SSLSocket sslSocket = sslServerSocket.accept();

The following list provides examples for the behavior of theSNIMatcher when receiving various server nameindication requests in the ClientHello message:

For descriptions of new classes that implement the SNIextension, see:

For examples, seeUsing the Server NameIndication (SNI) Extension.

TLS Application Layer Protocol Negotiation

In JDK 8u251 and later, Application Layer Protocol Negotiation (ALPN) enablesyou to negotiate an application protocol for a TLS connection;see TLS Application Layer Protocol Negotiation.

Troubleshooting

This section contains information for troubleshooting JSSE.First, it provides some commonconfiguration problems and ways to solve them,and then it describes helpfuldebuggingutilities.

ConfigurationProblems

This section describes some common configuration problems thatmight arise when you use JSSE.

CertificateException While Handshaking

Problem: When negotiating an SSL connection, the clientor server throws aCertificateException.

Cause 1: This is generally caused by the remote sidesending a certificate that is unknown to the local side.

Solution 1: The best way to debug this type of problem isto turn on debugging (seeDebugging Utilities)and watch as certificates are loaded and when certificates arereceived via the network connection. Most likely, the receivedcertificate is unknown to the trust mechanism because the wrongtrust file was loaded. Refer to the following sections for moreinformation:

Cause 2: The system clock is not set correctly. In thiscase, the perceived time may be outside the validity period on oneof the certificates, and unless the certificate can be replacedwith a valid one from a truststore, the system must assume that thecertificate is invalid, and therefore throw the exception.

Solution 2: Correct the system clock time.

java.security.KeyStoreException: TrustedCertEntry NotSupported

Problem: Attempt to store trusted certificates in PKCS12keystore throwsjava.security.KeyStoreException:TrustedCertEntry not supported.

Cause: Storing trusted certificates in a PKCS12 keystoreis not supported. PKCS12 is mainly used to deliver private keyswith the associated certificate chains. It does not have any notionof "trusted" certificates. In terms of interoperability, otherPKCS12 vendors have the same restriction. Browsers such as Mozillaand Internet Explorer do not accept a PKCS12 file with only trustedcertificates.

Solution: Use the JKS keystore for storing trustedcertificates.

Runtime Exception: SSL Service Not Available

Problem: When running a program that uses JSSE, anexception occurs indicating that an SSL service is not available.For example, an exception similar to one of the following isthrown:

Exception in thread "main" java.net.SocketException:no SSL Server SocketsException in thread "main":SSL implementation not available

Cause: There was a problem withSSLContextinitialization, for example, due to an incorrect password on akeystore or a corrupted keystore (a JDK vendor once shipped akeystore in an unknown format, and that caused this type oferror).

Solution: Check initialization parameters. Ensure thatany keystores specified are valid and that the passwords specifiedare correct. One way that you can check this is by trying to usethekeytoolcommand-line utility to examine the keystores and the relevantcontents.

Runtime Exception: "Noavailable certificate corresponding to the SSL cipher suites whichare enabled"

Problem: When trying to run a simple SSL server program,the following exception is thrown:

Exception in thread "main" javax.net.ssl.SSLException:No available certificate corresponding to the SSL cipher suites which are enabled...

Cause: Various cipher suites require certain types of keymaterial. For example, if an RSA cipher suite is enabled, then anRSAkeyEntry must be available in the keystore. If nosuch key is available, then this cipher suite cannot be used. Thisexception is thrown if there are no available key entries for allof the cipher suites enabled.

Solution: Create key entries for the various cipher suitetypes, or use an anonymous suite. Anonymous cipher suites areinherently dangerous because they are vulnerable to MITM(man-in-the-middle) attacks. For more information, seeRFC 2246.

Refer to the following sections to learn how to pass the correctkeystore and certificates:

Runtime Exception: No Cipher Suites in Common

Problem 1: When handshaking, the client and/or serverthrow this exception.

Cause 1: Both sides of an SSL connection must agree on acommon cipher suite. If the intersection of the client's ciphersuite set with the server's cipher suite set is empty, then youwill see this exception.

Solution 1: Configure the enabled cipher suites toinclude common cipher suites, and be sure to provide an appropriatekeyEntry for asymmetric cipher suites. Also seeRuntime Exception: "No availablecertificate..." in this section.)

Problem 2: When using Netscape Navigator or MicrosoftInternet Explorer to access files on a server that only hasDSA-based certificates, a runtime exception occurs indicating thatthere are no cipher suites in common.

Cause 2: By default,keyEntries created withkeytool use DSA public keys. If only DSAkeyEntries exist in the keystore, then only DSA-basedcipher suites can be used. By default, Navigator and InternetExplorer send only RSA-based cipher suites. Because theintersection of client and server cipher suite sets is empty, thisexception is thrown.

Solution 2: To interact with Navigator or InternetExplorer, you should create certificates that use RSA-based keys.To do this, specify the-keyalg RSA option when usingkeytool. For example:

keytool -genkeypair -alias duke -keystore testkeys -keyalg rsa

Slowness of the First JSSE Access

Problem: JSSE seems to stall on first access.

Cause: JSSE must have a secure source of random numbers.The initialization takes a while.

Solution: Provide an alternative generator of randomnumbers, or initialize ahead of time when the overhead will not benoticed:

SecureRandom sr = new SecureRandom();sr.nextInt();SSLContext.init(..., ..., sr);

Thejava-home/lib/security/java.security file alsoprovides a way to specify the source of seed data forSecureRandom. See the contents of the file for moreinformation.

CodeUsing HttpsURLConnection Class Throws ClassCastException in JSSE1.0.x

Problem: The following code snippet was written usingcom.sun.net.ssl.HttpsURLConnection in JSSE 1.0.x:

import com.sun.net.ssl.*;...deleted...HttpsURLConnection urlc = new URL("https://example.com/").openConnection();

When running under JSSE 1.0.x, this code returns ajavax.net.ssl.HttpsURLConnection object and throws aClassCastException.

Cause: By default, opening an HTTPS URL will create ajavax.net.ssl.HttpsURLConnection.

Solution: Previous releases of the JDK (release 6 andearlier) did not ship with an HTTPS URL implementation. The JSSE1.0.x implementation did provide such an HTTPS URL handler, and theinstallation guide described how to set the URL handler search pathto obtain a JSSE 1.0.xcom.sun.net.ssl.HttpsURLConnection implementation.

In the JDK, there is an HTTPS handler in the default URL handlersearch path. It returns an instance ofjavax.net.ssl.HttpsURLConnection. By prepending theold JSSE 1.0.x implementation path to the URL search path via thejava.protocol.handler.pkgs variable, you can stillobtain acom.sun.net.ssl.HttpsURLConnection, and thecode will no longer throw cast exceptions.

See the following examples:
% java -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol YourClass
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");

Socket Disconnected After Sending ClientHello Message

Problem: A socket attempts to connect, sends aClientHello message, and is immediately disconnected.

Cause: Some SSL/TLS servers will disconnect if aClientHello message is received in a format they do not understandor with a protocol version number that they do not support.

Solution: Try adjusting the enabled protocolson the client side. This involves modifying or invoking some of thefollowing system properties and methods:

For backwards compatibility, some SSL/TLS implementations (suchasSunJSSE) can send SSL/TLS ClientHello messages encapsulated inthe SSLv2 ClientHello format. TheSunJSSE provider supports thisfeature. If you want to use this feature, add the "SSLv2Hello"protocol to the enabled protocol list, if necessary. (Also see theProtocolssection, which lists the protocols that are enabled by default fortheSunJSSE provider.)

The SSL/TLS RFC standards require that implementations negotiateto the latest version both sides speak, but some non-conformingimplementation simply hang up if presented with a version theydon't understand. For example, some older server implementationsthat speak only SSLv3 will shutdown if TLSv1.2 is requested. Inthis situation, consider using a SSL/TLS version fallbackscheme:

  1. Fall back from TLSv1.2 to TLSv1.1 if the server does notunderstand TLSv1.2.
  2. Fall back from TLSv1.1 to TLSv1.0 if the previous step does notwork.

For example, if the enabled protocol list on the client isTLSv1, TLSv1.1, and TLSv1.2, a typical SSL/TLS version fallbackscheme may look like:

  1. Try to connect to server. If server rejects the SSL/TLSconnection request immediately, go to step 2.
  2. Try the version fallback scheme by removing the highestprotocol version (for example, TLSv1.2 for the first failure) inthe enabled protocol list.
  3. Try to connect to the server again. If server rejects theconnection, go to step 2 unless there is no version to which theserver can fall back.
  4. If the connection fails and SSLv2Hello is not on the enabledprotocol list, restore the enable protocol list and enableSSLv2Hello. (For example, the enable protocol list should beSSLv2Hello, SSLv3, TLSv1, TLSv1.1, and TLSv1.2.) Start again fromstep 1.

Note: A fallback to a previous version normallymeans security strength downgrading to a weaker protocol. It is notsuggested to use a fallback scheme unless it is really necessary,and you clearly know that the server does not support a higherprotocol version.



Note: As part of disabling SSLv3, some servershave also disabled SSLv2Hello, which means communications withSSLv2Hello-active clients (e.g. JDK 1.5/6) will fail. Starting withJDK 7, SSLv2Hello default to disabled on clients, enabled onservers.


SunJSSE Cannot Find a JCA Provider That Supports a RequiredAlgorithm and Causes a NoSuchAlgorithmException

Problem: A handshake is attempted and fails when itcannot find a required algorithm. Examples might include:

Exception in thread ...deleted......deleted...Caused by java.security.NoSuchAlgorithmException: Cannot find anyprovider supporting RSA/ECB/PKCS1Padding
or
Caused by java.security.NoSuchAlgorithmException: Cannot find anyprovider supporting AES/CBC/NoPadding

Cause:SunJSSE uses JCE for all its cryptographicalgorithms. By default, the Oracle JDK will use the StandardExtension ClassLoader to load the SunJCE provider located injava-home/lib/ext/sunjce_provider.jar. If the filecannot be found or loaded, or if the SunJCE provider has beenderegistered from theProvider mechanism and analternative implementation from JCE is not available, then thisexception will be thrown.

Solution: Ensure that the SunJCE is available by checkingthat the file is loadable and that the provider is registered withtheProvider interface. Try to run the following codein the context of your SSL connection:

import javax.crypto.*;System.out.println("=====Where did you get AES=====");Cipher c = Cipher.getInstance("AES/CBC/NoPadding");System.out.println(c.getProvider());

FailedDownloadException Thrown When Trying to ObtainApplication Resources from Web Server over SSL

Problem: If you receive acom.sun.deploy.net.FailedDownloadException when tryingto obtain application resources from your web server over SSL, andyour web server uses the virtual host with Server Name Indication(SNI) extension (such as Apache HTTP Server), then you may have notconfigured your web server correctly.

Cause: Because Java SE 7 supports the SNI extension inthe JSSE client, the requested host name of the virtual server isincluded in the first message sent from the client to the serverduring the SSL handshake. The server may deny the client's requestfor a connection if the requested host name (the server nameindication) does not match the expected server name, which shouldbe specified in the virtual host's configuration. This triggers anSSL handshake unrecognized name alert, which results in aFailedDownloadException being thrown.

Solution: To better diagnose the problem, enable tracingthrough the Java Console. SeeJava Console, Tracing, andLogging for more information. If the cause of the problem isjavax.net.ssl.SSLProtocolException: handshake alert:unrecognized_name, it is likely that the virtual hostconfiguration for SNI is incorrect. If you are using Apache HTTPServer, seeName-basedVirtual Host Support for information about configuring virtualhosts. In particular, ensure that theServerNamedirective is configured properly in a<VirtualHost> block.

For more information, see the following:

Debugging Utilities

JSSE provides dynamic debug tracing support. This is similar tothe support used for debugging access control failures in the JavaSE platform. The generic Java dynamic debug tracing support isaccessed with thejava.security.debug system property,whereas the JSSE-specific dynamic debug tracing support is accessedwith thejavax.net.debug system property.


Note: Thedebug utility is not anofficially supported feature of JSSE.


To view the options of the JSSE dynamic debug utility, use thefollowing command-line option on thejava command:

-Djavax.net.debug=help

Note: If you specify the valuehelp with either dynamic debug utility when running aprogram that does not use any classes that the utility was designedto debug, you will not get the debugging options.


The following complete example shows how to get a list of thedebug options for an application namedMyApp that usessome of the JSSE classes:

java -Djavax.net.debug=help MyApp

TheMyApp application will not run after the debughelp information is printed, as the help code causes theapplication to exit.

Current options are:

The following can be used with thessl option:

Messages generated from thehandshake option can bewidened with these options:

Messages generated from therecord option can bewidened with these options:

Thejavax.net.debug property value must be eitherall orssl, optionally followed by debugspecifiers. You can use one or more options. You donot haveto have a separator between options, although a separator such as acolon (:) or a comma (,) helps readability. It does not matter whatseparators you use, and the ordering of the option keywords is alsonot important.

For an introduction to reading this debug information, see theguide,Debugging TLSConnections.

The following are examples of using thejavax.net.debug property:

Code Examples

The following code examples are included in this section:

Converting anUnsecure Socket to a Secure Socket

This section provides examples of source code that illustratehow to use JSSE to convert an unsecure socket connection to asecure socket connection. The code in this section is excerptedfrom the bookJava SE 6 Network Security by MarcoPistoia, et. al.

First, "Socket Example Without SSL" shows sample code that canbe used to set up communication between a client and a server usingunsecure sockets. This code is then modified in "Socket Examplewith SSL" to use JSSE to set up secure socket communication.

Socket ExampleWithout SSL

The following examples demonstrates server-side and client-sidecode for setting up an unsecure socket connection.

In a Java program that acts as a server and communicates with aclient using sockets, the socket communication is set up with codesimilar to the following:

import java.io.*;import java.net.*;. . .int port = availablePortNumber;ServerSocket s;try {s = new ServerSocket(port);Socket c = s.accept();OutputStream out = c.getOutputStream();InputStream in = c.getInputStream();// Send messages to the client through// the OutputStream// Receive messages from the client// through the InputStream} catch (IOException e) { }

The client code to set up communication with a server usingsockets is similar to the following:

import java.io.*;import java.net.*;. . .int port = availablePortNumber;String host = "hostname";try {s = new Socket(host, port);OutputStream out = s.getOutputStream();InputStream in = s.getInputStream();// Send messages to the server through// the OutputStream// Receive messages from the server// through the InputStream} catch (IOException e) { }

Socket Example withSSL

The following examples demonstrate server-side and client-sidecode for setting up a secure socket connection.

In a Java program that acts as a server and communicates with aclient using secure sockets, the socket communication is set upwith code similar to the following. Differences between thisprogram and the one for communication using unsecure sockets arehighlighted in bold.

import java.io.*;importjavax.net.ssl.*;. . .int port = availablePortNumber;SSLServerSocket s;try {SSLServerSocketFactory sslSrvFact =(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();s = (SSLServerSocket)sslSrvFact.createServerSocket(port);SSLSocket c =(SSLSocket)s.accept();OutputStream out = c.getOutputStream();InputStream in = c.getInputStream();// Send messages to the client through// the OutputStream// Receive messages from the client// through the InputStream}catch (IOException e) {}

The client code to set up communication with a server usingsecure sockets is similar to the following, where differences withthe unsecure version are highlighted in bold:

import java.io.*;importjavax.net.ssl.*;. . .int port = availablePortNumber;String host = "hostname";try {SSLSocketFactory sslFact =(SSLSocketFactory)SSLSocketFactory.getDefault();SSLSocket s = (SSLSocket)sslFact.createSocket(host, port);OutputStream out = s.getOutputStream();InputStream in = s.getInputStream();// Send messages to the server through// the OutputStream// Receive messages from the server// through the InputStream}catch (IOException e) {}

Running the JSSE SampleCode

The JSSE sample programs illustrate how to use JSSE to:

When you use the sample code, be aware that the sample programsare designed to illustrate how to use JSSE. They are not designedto be robust applications.


Note: Setting up secure communications involvescomplex algorithms. The sample programs provide no feedback duringthe setup process. When you run the programs, be patient: you maynot see any output for a while. If you run the programs with thejavax.net.debug system property set toall, you will see more feedback. For an introductionto reading this debug information, see the guide,Debugging TLS Connections.


Where to Find the SampleCode

Most of the sample code is located in thesamples subdirectory of the same directoryas that containing the document you are reading. Follow that linkto see a listing of all the sample code files and text files. Thatpage also provides a link to a ZIP file that you can download toobtain all the sample code files, which is helpful if you areviewing this documentation from the web.

The following sections describe the samples. For moreinformation, seeREADME.txt.

Sample CodeIllustrating a Secure Socket Connection Between a Client and aServer

The sample programs in thesamples/socketsdirectory illustrate how to set up a secure socket connectionbetween a client and a server.

When running the sample client programs, you can communicatewith an existing server, such as a commercial web server, or youcan communicate with the sample server program,ClassFileServer. You can run the sample client and thesample server programs on different machines connected to the samenetwork, or you can run them both on one machine but from differentterminal windows.

All the sampleSSLSocketClient* programs in thesamples/sockets/client directory (andURLReader*programs described inSample CodeIllustrating HTTPS Connections) can be run with theClassFileServer sample server program. An example ofhow to do this is shown inRunningSSLSocketClientWithClientAuth with ClassFileServer. You canmake similar changes to runURLReader,SSLSocketClient, orSSLSocketClientWithTunneling withClassFileServer.

If an authentication error occurs during communication betweenthe client and the server (whether using a web server orClassFileServer), it is most likely because thenecessary keys are not in thetruststore(trust key database). For example, theClassFileServeruses a keystore calledtestkeys containing the privatekey forlocalhost as needed during the SSL handshake.Thetestkeys keystore is included in the samesamples/sockets/server directory as theClassFileServer source. If the client cannot find acertificate for the corresponding public key oflocalhost in the truststore it consults, then anauthentication error will occur. Be sure to use thesamplecacerts truststore (which contains the publickey and certificate of thelocalhost), as described inthe next section.

ConfigurationRequirements

When running the sample programs that create a secure socketconnection between a client and a server, you will need to make theappropriate certificates file (truststore) available. For both theclient and the server programs, you should use the certificatesfilesamplecacerts from thesamplesdirectory. Using this certificates file will allow the client toauthenticate the server. The file contains all the commonCertificate Authority (CA) certificates shipped with the JDK (inthe cacerts file), plus a certificate forlocalhostneeded by the client to authenticatelocalhost whencommunicating with the sample serverClassFileServer.TheClassFileServer uses a keystore containing theprivate key forlocalhost that corresponds to thepublic key insamplecacerts.

To make thesamplecacerts file available to boththe client and the server, you can either copy it to the filejava-home/lib/security/jssecacerts, rename it tocacerts, and use it to replace thejava-home/lib/security/cacerts file, or add thefollowing option to the command line when running thejava command for both the client and the server:

-Djavax.net.ssl.trustStore=path_to_samplecacerts_file

The password for thesamplecacerts truststore ischangeit. You can substitute your own certificates inthe samples by using thekeytool utility.

If you use a browser, such as Netscape Navigator or Microsoft'sInternet Explorer, to access the sample SSL server provided in theClassFileServer example, then a dialog box may pop upwith the message that it does not recognize the certificate. Thisis normal because the certificate used with the sample programs isself-signed and is for testing only. You can accept the certificatefor the current session. After testing the SSL server, you shouldexit the browser, which deletes the test certificate from thebrowser's namespace.

For client authentication, a separatedukecertificate is available in the appropriate directories. The publickey and certificate is also stored in thesamplecacerts file.

Running SSLSocketClient

TheSSLSocketClient.javaprogram demonstrates how to create a client that uses anSSLSocket to send an HTTP request and to get aresponse from an HTTPS server. The output of this program is theHTML source forhttps://www.verisign.com/index.html.

You must not be behind a firewall to run this program asprovided. If you run it from behind a firewall, you will get anUnknownHostException because JSSE cannot find a paththrough your firewall towww.verisign.com. To createan equivalent client that can run from behind a firewall, set upproxy tunneling as illustrated in the sample programSSLSocketClientWithTunneling.

RunningSSLSocketClientWithTunneling

TheSSLSocketClientWithTunneling.javaprogram illustrates how to do proxy tunneling to access a secureweb server from behind a firewall. To run this program, you mustset the following Java system properties to the appropriatevalues:

java -Dhttps.proxyHost=webproxy-Dhttps.proxyPort=ProxyPortNumberSSLSocketClientWithTunneling

Note: Proxy specifications with the-D options are optional. Replacewebproxy withthe name of your proxy host andProxyPortNumber with theappropriate port number.

The program will return the HTML source file fromhttps://www.verisign.com/index.html.

Running SSLSocketClientWithClientAuth

TheSSLSocketClientWithClientAuth.javaprogram shows how to set up a key manager to do clientauthentication if required by a server. This program also assumesthat the client is not outside a firewall. You can modify theprogram to connect from inside a firewall by following the exampleinSSLSocketClientWithTunneling.

To run this program, you must specify three parameters: host,port, and requested file path. To mirror the previous examples, youcan run this program without client authentication by setting thehost towww.verisign.com, the port to443, and the requested file path tohttps://www.verisign.com/. The output when using theseparameters is the HTML for the websitehttps://www.verisign.com/.

To runSSLSocketClientWithClientAuth to do clientauthentication, you must access a server that requests clientauthentication. You can use the sample programClassFileServer as this server. This is described inthe following sections.

RunningClassFileServer

The program referred to herein asClassFileServeris made up of two files:ClassFileServer.javaandClassServer.java.

To execute them, runClassFileServer.class, whichrequires the following parameters:


Note: TheTLS andtrue parameters are optional. If you omit them,indicating that an ordinary (not TLS) file server should be used,without authentication, then nothing happens. This is because oneside (the client) is trying to negotiate with TLS, while the other(the server) is not, so they cannot communicate.



Note: The server expects GET requests in theformGET /path_to_file.


RunningSSLSocketClientWithClientAuth with ClassFileServer

You can use the sample programsSSLSocketClientWithClientAuthandClassFileServer to set up authenticatedcommunication, where the client and server are authenticated toeach other. You can run both sample programs on different machinesconnected to the same network, or you can run them both on onemachine but from different terminal windows or command promptwindows. To set up both the client and the server, do thefollowing:

  1. Run the programClassFileServer from one machineor terminal window, as described inRunningClassFileServer.
  2. Run the programSSLSocketClientWithClientAuth onanother machine or terminal window.SSLSocketClientWithClientAuth requires the followingparameters:
    • host is the host name of the machine that you areusing to runClassFileServer.
    • port is the same port that you specified forClassFileServer.
    • requestedfilepath indicates the path to the filethat you want to retrieve from the server. You must give thisparameter as/filepath. Forward slashes are requiredin the file path because it is used as part of a GET statement,which requires forward slashes regardless of what type of operatingsystem you are running. The statement is formed as follows:

      "GET " + requestedfilepath + " HTTP/1.0"

Note: You can modify the otherSSLClient* applications'GET commands toconnect to a local machine runningClassFileServer.


Sample Code IllustratingHTTPS Connections

There are two primary APIs for accessing secure communicationsthrough JSSE. One way is through a socket-level API that can beused for arbitrary secure communications, as illustrated by theSSLSocketClient,SSLSocketClientWithTunneling, andSSLSocketClientWithClientAuth (with and withoutClassFileServer) sample programs.

A second, and often simpler, way is through the standard JavaURL API. You can communicate securely with an SSL-enabled webserver by using the HTTPS URL protocol or scheme using thejava.net.URL class.

Support for HTTPS URL schemes is implemented in many of thecommon browsers, which allows access to secured communicationswithout requiring the socket-level API provided with JSSE.

An example URL ishttps://www.verisign.com.

The trust and key management for the HTTPS URL implementation isenvironment-specific. The JSSE implementation provides an HTTPS URLimplementation. To use a different HTTPS protocol implementation,set thejava.protocol.handler.pkgs system property to the package name. See thejava.net.URL class documentation for details.

The samples that you can download with JSSE include two sampleprograms that illustrate how to create an HTTPS connection. Both ofthese sample programs (URLReader.java andURLReaderWithOptions.java)are in the samples/urls directory.

Running URLReader

TheURLReader.javaprogram illustrates using the URL class to access a secure site.The output of this program is the HTML source forhttps://www.verisign.com/. By default, the HTTPSprotocol implementation included with JSSE is used. To use adifferent implementation, set the system propertyjava.protocol.handler.pkgs value to be the name of thepackage containing the implementation.

If you are running the sample code behind a firewall, then youmust set thehttps.proxyHost andhttps.proxyPort system properties. For example, to usethe proxy host "webproxy" on port 8080, you can use the followingoptions for thejava command:

-Dhttps.proxyHost=webproxy-Dhttps.proxyPort=8080

Alternatively, you can set the system properties within thesource code with thejava.lang.System methodsetProperty(). For example, instead of using thecommand-line options, you can include the following lines in yourprogram:

System.setProperty("java.protocol.handler.pkgs", "com.ABC.myhttpsprotocol");System.setProperty("https.proxyHost", "webproxy");System.setProperty("https.proxyPort", "8080");

RunningURLReaderWithOptions

TheURLReaderWithOptions.javaprogram is essentially the same as the URLReader.java program,except that it allows you to optionally input any or all of thefollowing system properties as arguments to the program when yourun it:

To runURLReaderWithOptions, enter the followingcommand:

java URLReaderWithOptions [-hproxyhost -pproxyport] [-kprotocolhandlerpkgs] [-cciphersarray]

Note: Multiple protocol handlers can beincluded in theprotocolhandlerpkgs argument as a listwith items separated by vertical bars. Multiple SSL cipher suitenames can be included in theciphersarray argument asa list with items separated by commas. The possible cipher suitenames are the same as those returned by theSSLSocket.getSupportedCipherSuites() method. The suitenames are taken from the SSL and TLS protocol specifications.

You need aprotocolhandlerpkgs argument only if youwant to use an HTTPS protocol handler implementation other than thedefault one provided by Oracle.

If you are running the sample code behind a firewall, then youmust include arguments for the proxy host and the proxy port.Additionally, you can include a list of cipher suites toenable.

Here is an example of runningURLReaderWithOptionsand specifying the proxy host "webproxy" on port 8080:

java URLReaderWithOptions -h webproxy -p 8080

Sample Code Illustrating aSecure RMI Connection

The sample code in the samples/rmi directory illustrates how tocreate a secure Java Remote Method Invocation (RMI) connection. Thesample code is based on anRMI example that isbasically a "Hello World" example modified to install and use acustom RMI socket factory.

For more information about Java RMI, see theJava RMI documentation. This web pagepoints to Java RMI tutorials and other information about JavaRMI.

Sample CodeIllustrating the Use of an SSLEngine

SSLEngine gives application developers flexibilitywhen choosing I/O and compute strategies. Rather than tie theSSL/TLS implementation to a specific I/O abstraction (such assingle-threadedSSLSockets),SSLEngineremoves the I/O and compute constraints from the SSL/TLSimplementation.

As mentioned earlier,SSLEngine is an advanced API,and is not appropriate for casual use. Some introductory samplecode is provided here that helps illustrate its use. The first demoremoves most of the I/O and threading issues, and focuses on manyof the SSLEngine methods. The second demo is a more realisticexample showing howSSLEngine might be combined withJava NIO to create a rudimentary HTTP/HTTPS server.

Running SSLEngineSimpleDemo

TheSSLEngineSimpleDemois a very simple application that focuses on the operation of theSSLEngine while simplifying the I/O and threadingissues. This application creates twoSSLEngine objectsthat exchange SSL/TLS messages via commonByteBufferobjects. A single loop serially performs all of the engineoperations and demonstrates how a secure connection is established(handshaking), how application data is transferred, and how theengine is closed.

TheSSLEngineResult provides a great deal ofinformation about the current state of theSSLEngine.This example does not examine all of the states. It simplifies theI/O and threading issues to the point that this is not a goodexample for a production environment; nonetheless, it is useful todemonstrate the overall function of theSSLEngine.

Creating aKeystore to Use with JSSE

This section demonstrates how you can use thekeytool utility to create a simple JKS keystoresuitable for use with JSSE. First you make akeyEntry(with public and private keys) in the keystore, and then you make acorrespondingtrustedCertEntry (public keys only) in atruststore. For client authentication, you follow a similar processfor the client's certificates.


Note: Storing trust anchors and secret keys inPKCS12 is supported since JDK 8.



Note: It is beyond the scope of this example toexplain each step in detail. For more information, see thekeytool documentation forSolaris, Linux, or macOSorMicrosoftWindows.


User input is shown in bold.

  1. Create a new keystore and self-signed certificate withcorresponding public and private keys.

    %keytool -genkeypair -alias duke -keyalg RSA -validity 7 -keystore keystoreEnter keystore password:passwordWhat is your first and last name?[Unknown]:DukeWhat is the name of your organizational unit?[Unknown]:Java SoftwareWhat is the name of your organization?[Unknown]:Oracle, Inc.What is the name of your City or Locality?[Unknown]:Palo AltoWhat is the name of your State or Province?[Unknown]:CAWhat is the two-letter country code for this unit?[Unknown]:USIs CN=Duke, OU=Java Software, O="Oracle, Inc.",L=Palo Alto, ST=CA, C=US correct?[no]:yesEnter key password for <duke>(RETURN if same as keystore password):<CR>
  2. Examine the keystore. Notice that the entry type iskeyEntry, which means that this entry has a privatekey associated with it).

    %keytool -list -v -keystore keystoreEnter keystore password:passwordKeystore type: jksKeystore provider: SUNYour keystore contains 1 entryAlias name: dukeCreation date: Dec 20, 2001Entry type: keyEntryCertificate chain length: 1Certificate[1]:Owner: CN=Duke, OU=Java Software, O="Oracle, Inc.",L=Palo Alto, ST=CA, C=USIssuer: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=USSerial number: 3c22adc1Valid from: Thu Dec 20 19:34:25 PST 2001 until: Thu Dec 27 19:34:25 PST 2001Certificate fingerprints:MD5: F1:5B:9B:A1:F7:16:CF:25:CF:F4:FF:35:3F:4C:9C:F0SHA1: B2:00:50:DD:B6:CC:35:66:21:45:0F:96:AA:AF:6A:3D:E4:03:7C:74
  3. Export and examine the self-signed certificate.

    %keytool -export -alias duke -keystore keystore -rfc -file duke.cerEnter keystore password:passwordCertificate stored in file <duke.cer>%cat duke.cer-----BEGIN CERTIFICATE-----MIICXjCCAccCBDwircEwDQYJKoZIhvcNAQEEBQAwdjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlQYWxvIEFsdG8xHzAdBgNVBAoTFlN1biBNaWNyb3N5c3RlbXMsIEluYy4xFjAUBgNVBAsTDUphdmEgU29mdHdhcmUxDTALBgNVBAMTBER1a2UwHhcNMDExMjIxMDMzNDI1WhcNMDExMjI4MDMzNDI1WjB2MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0bzEfMB0GA1UEChMWU3VuIE1pY3Jvc3lzdGVtcywgSW5jLjEWMBQGA1UECxMNSmF2YSBTb2Z0d2FyZTENMAsGA1UEAxMERHVrZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1loObJzNXsi5aSr8N4XzDksD6GjTHFeqG9DUFXKEOQetfYXvA8F9uWtz8WInrqskLTNzwXgmNeWkoM7mrPpK6Rf5M3G1NXtYzvxyi473Gh1h9k7tjJvqSVKO7E1oFkQYeUPYifxmjbSMVirWZgvo2UmA1c76oNK+NhoHJ4qjeCUCAwEAATANBgkqhkiG9w0BAQQFAAOBgQCRPoQYw9rWWvfLPQuPXowvFmuebsTc28qI7iFWm6BJTT/qdmzti7B5MHOt9BeVEft3mMeBU0CS2guaBjDpGlf+zsK/UUi1w9C4mnwGDZzqY/NKKWtLxabZ5M+4MAKLZ92ePPKGpobM2CPLfM8ap4IgAzCbBKd8+CMp8yFmifze9Q==-----END CERTIFICATE-----

    Alternatively, you could generate a Certificate Signing Request(CSR) with-certreq and send that to a CertificateAuthority (CA) for signing, See the section "Request a Signed Certificate from aCA" (Solaris, Linux, or macOSorWindows) inthekeytool documentation.

  4. Import the certificate into a new truststore.

    %keytool -import -alias dukecert -file duke.cer -keystore truststoreEnter keystore password:trustwordOwner: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=USIssuer: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=USSerial number: 3c22adc1Valid from: Thu Dec 20 19:34:25 PST 2001 until: Thu Dec 27 19:34:25 PST 2001Certificate fingerprints:MD5: F1:5B:9B:A1:F7:16:CF:25:CF:F4:FF:35:3F:4C:9C:F0SHA1: B2:00:50:DD:B6:CC:35:66:21:45:0F:96:AA:AF:6A:3D:E4:03:7C:74Trust this certificate? [no]:yesCertificate was added to keystore
  5. Examine the truststore. Note that the entry type istrustedCertEntry, which means that a private key isnot available for this entry. It also means that this file is notsuitable as a keystore of theKeyManager.

    %keytool -list -v -keystore truststoreEnter keystore password:trustwordKeystore type: jksKeystore provider: SUNYour keystore contains 1 entryAlias name: dukecertCreation date: Dec 20, 2001Entry type: trustedCertEntryOwner: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=USIssuer: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=USSerial number: 3c22adc1Valid from: Thu Dec 20 19:34:25 PST 2001 until: Thu Dec 27 19:34:25 PST 2001Certificate fingerprints:MD5: F1:5B:9B:A1:F7:16:CF:25:CF:F4:FF:35:3F:4C:9C:F0SHA1: B2:00:50:DD:B6:CC:35:66:21:45:0F:96:AA:AF:6A:3D:E4:03:7C:74
  6. Now run your applications with the appropriate keystores.Because this example assumes that the defaultX509KeyManager andX509TrustManager areused, you select the keystores using the system propertiesdescribed inCustomizingJSSE.

    % java -Djavax.net.ssl.keyStore=keystore -Djavax.net.ssl.keyStorePassword=password Server% java -Djavax.net.ssl.trustStore=truststore -Djavax.net.ssl.trustStorePassword=trustword Client

Note: This example authenticated the serveronly. For client authentication, provide a similar keystore for theclient's keys and an appropriate truststore for the server.


Using the Server NameIndication (SNI) Extension

This section provides code examples that illustrate how you canuse theServer Name Indication (SNI)extension for client-side and server-side applications, and how itcan be applied to a virtual infrastructure.

For all examples in this section, to apply the parameters afteryou set them, call thesetSSLParameters(SSLParameters)method on the correspondingSSLSocket,SSLEngine, orSSLServerSocket object.

TypicalClient-Side Usage Examples

The following is a list of use cases that require understandingof the SNI extension for developing a client application:

TypicalServer-Side Usage Examples

The following is a list of use cases that require understandingof the SNI extension for developing a server application:

Workingwith Virtual Infrastructures

This section describes how to use the Server Name Indication(SNI) extension from within a virtual infrastructure. Itillustrates how to create a parser for ClientHello messages from asocket, provides examples of virtual server dispatchers usingSSLSocket andSSLEngine, describes whathappens when the SNI extension is not available, and demonstrateshow to create a failoverSSLContext.

Preparingthe ClientHello Parser

Applications must implement an API to parse the ClientHellomessages from a socket. The following examples illustrate theSSLCapabilities andSSLExplorer classesthat can perform these functions.

SSLCapabilities.javaencapsulates the SSL/TLS security capabilities during handshaking(that is, the list of cipher suites to be accepted in an SSL/TLShandshake, the record version, the hello version, and the servername indication). It can be retrieved by exploring the network dataof an SSL/TLS connection via theSSLExplorer.explore()method.

SSLExplorer.javaexplores the initial ClientHello message from a TLS client, but itdoes not initiate handshaking or consume network data. TheSSLExplorer.explore() method parses the ClientHellomessage, and retrieves the security parameters intoSSLCapabilities. The method must be called beforehandshaking occurs on any TLS connections.

Virtual Server Dispatcher Based onSSLSocket

This section describes the procedure for using a virtual serverdispatcher based onSSLSocket.

  1. Register the server name handler.

    At this step, the application may create differentSSLContext objects for different server nameindications, or link a certain server name indication to aspecified virtual machine or distributed system.

    For example, if the server name iswww.example.org,then the registered server name handler may be for a local virtualhosting web service. The local virtual hosting web service will usethe specifiedSSLContext. If the server name iswww.example.com, then the registered server namehandler may be for a virtual machine hosting on10.0.0.36. The handler may map this connection to thevirtual machine.

  2. Create aServerSocket and accept the newconnection.

    ServerSocket serverSocket = new ServerSocket(serverPort);Socket socket = serverSocket.accept();
  3. Read and buffer bytes from the socket input stream, and thenexplore the buffered bytes.

    InputStream ins = socket.getInputStream();byte[] buffer = new byte[0xFF];int position = 0;SSLCapabilities capabilities = null;// Read the header of TLS recordwhile (position < SSLExplorer.RECORD_HEADER_SIZE) {int count = SSLExplorer.RECORD_HEADER_SIZE - position;int n = ins.read(buffer, position, count);if (n < 0) {throw new Exception("unexpected end of stream!");}position += n;}// Get the required size to explore the SSL capabilitiesint recordLength = SSLExplorer.getRequiredSize(buffer, 0, position);if (buffer.length < recordLength) {buffer = Arrays.copyOf(buffer, recordLength);}while (position < recordLength) {int count = recordLength - position;int n = ins.read(buffer, position, count);if (n < 0) {throw new Exception("unexpected end of stream!");}position += n;}// Explorecapabilities = SSLExplorer.explore(buffer, 0, recordLength);if (capabilities != null) {System.out.println("Record version: " + capabilities.getRecordVersion());System.out.println("Hello version: " + capabilities.getHelloVersion());}
  4. Get the requested server name from the exploredcapabilities.

    List<SNIServerName> serverNames = capabilities.getServerNames();
  5. Look for the registered server name handler for this servername indication.

    If the service of the host name is resident in a virtual machineor another distributed system, then the application must forwardthe connection to the destination. The application will need toread and write the raw internet data, rather then the SSLapplication from the socket stream.

    Socket destinationSocket = new Socket(serverName, 443);// Forward buffered bytes and network data from the current socket to thedestinationSocket.

    If the service of the host name is resident in the same process,and the host name service can use theSSLSocketdirectly, then the application will need to set theSSLSocket instance to the server:

    // Get service context from registered handler// or create the contextSSLContext serviceContext = ...SSLSocketFactory serviceSocketFac = serviceContext.getSSLSocketFactory();// wrap the buffered bytesByteArrayInputStream bais = new ByteArrayInputStream(buffer, 0, position);SSLSocket serviceSocket = (SSLSocket)serviceSocketFac.createSocket(socket, bais, true);// Now the service can use serviceSocket as usual.

Virtual Server Dispatcher Based onSSLEngine

This section describes the procedure for using a virtual serverdispatcher based onSSLEngine.

  1. Register the server name handler.

    At this step, the application may create differentSSLContext objects for different server nameindications, or link a certain server name indication to aspecified virtual machine or distributed system.

    For example, if the server name iswww.example.org,then the registered server name handler may be for a local virtualhosting web service. The local virtual hosting web service will usethe specifiedSSLContext. If the server name iswww.example.com, then the registered server namehandler may be for a virtual machine hosting on10.0.0.36. The handler may map this connection to thevirtual machine.

  2. Create aServerSocket orServerSocketChannel and accept the newconnection.

    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.bind(...);...SocketChannel socketChannel = serverSocketChannel.accept();
  3. Read and buffer bytes from the socket input stream, and thenexplore the buffered bytes.

    ByteBuffer buffer = ByteBuffer.allocate(0xFF);SSLCapabilities capabilities = null;while (true) {// ensure the capacityif (buffer.remaining() == 0) {ByteBuffer oldBuffer = buffer;buffer = ByteBuffer.allocate(buffer.capacity() + 0xFF);buffer.put(oldBuffer);}int n = sc.read(buffer);if (n < 0) {throw new Exception("unexpected end of stream!");}int position = buffer.position();buffer.flip();capabilities = explorer.explore(buffer);buffer.rewind();buffer.position(position);buffer.limit(buffer.capacity());if (capabilities != null) {System.out.println("Record version: " +capabilities.getRecordVersion());System.out.println("Hello version: " +capabilities.getHelloVersion());break;}}buffer.flip();  // reset the buffer position and limitation
  4. Get the requested server name from the exploredcapabilities.

    List<SNIServerName> serverNames = capabilities.getServerNames();
  5. Look for the registered server name handler for this servername indication.

    If the service of the host name is resident in a virtual machineor another distributed system, then the application must forwardthe connection to the destination. The application will need toread and write the raw internet data, rather then the SSLapplication from the socket stream.

    Socket destinationSocket = new Socket(serverName, 443);// Forward buffered bytes and network data from the current socket to thedestinationSocket.

    If the service of the host name is resident in the same process,and the host name service can use theSSLEnginedirectly, then the application will simply feed the net data to theSSLEngine instance:

    // Get service context from registered handler// or create the contextSSLContext serviceContext = ...SSLEngine serviceEngine = serviceContext.createSSLEngine();// Now the service can use the buffered bytes and other byte buffer as usual.

No SNI Extension Available

If there is no server name indication in a ClientHello message,then there is no way to select the proper service according to SNI.For such cases, the application may need to specify a defaultservice, so that the connection can be delegated to it if there isno server name indication.

FailoverSSLContext

TheSSLExplorer.explore() method does not check thevalidity of SSL/TLS contents. If the record format does not complywith SSL/TLS specification, or theexplore() method isinvoked after handshaking has started, then the method may throw anIOException and be unable to produce network data. Insuch cases, handle the exception thrown bySSLExplorer.explore() by using a failoverSSLContext, which is not used to negotiate an SSL/TLSconnection, but to close the connection with the proper alertmessage. The following example illustrates a failoverSSLContext. You can find an example of theDenialSNIMatcher class in Case 2 of theTypical Server-Side Usage Examples.

byte[] buffer = ...       // buffered network databoolean failed = true;    // SSLExplorer.explore() throws an exceptionSSLContext context = SSLContext.getInstance("TLS");// the failover SSLContextcontext.init(null, null, null);SSLSocketFactory sslsf = context.getSocketFactory();ByteArrayInputStream bais = new ByteArrayInputStream(buffer, 0, position);SSLSocket sslSocket = (SSLSocket)sslsf.createSocket(socket, bais, true);SNIMatcher matcher = new DenialSNIMatcher();Collection<SNIMatcher> matchers = new ArrayList<>(1);matchers.add(matcher);SSLParameters params = sslSocket.getSSLParameters();params.setSNIMatchers(matchers);    // no recognizable server namesslSocket.setSSLParameters(params);try {InputStream sslIS = sslSocket.getInputStream();sslIS.read();} catch (Exception e) {System.out.println("Server exception " + e);} finally {sslSocket.close();}

Appendix A: Standard Names

The JDK Security API requires and uses a set of standard namesfor algorithms, certificates and keystore types. The specificationnames previously found here in Appendix A and in the other securityspecifications (JCA, CertPath) have been combined inJava Cryptography Architecture (JCA) Standard Algorithm Name Documentation for JDK 8. Specificprovider information can be found inJava Cryptography Architecture (JCA) Oracle Providers Documentation for JDK 8.

Appendix B: ProviderPluggability

JSSE is fully pluggable and does not restrict the use ofthird-party JSSE providers in any way.

Appendix C: TLS Renegotiation Issue

In the fall of 2009, a flaw was discovered in the SSL/TLSprotocols. A fix to the protocol was developed by the IETF TLSWorking Group, and current versions of the JDK contain this fix.The pageTransport Layer Security (TLS) Renegotiation Issue describes the situation in much more detail, alongwith interoperability issues when communicating with olderimplementations that do not contain this protocol fix

Appendix D: Signature Schemes

The following table contains the standard signature scheme names, which arethe algorithms used in the digital signatures of TLS connections and are alsodefined in theSignatureScheme sectionof the IANA TLS Registry.

Signature SchemeSpecification
ecdsa_secp256r1_sha256RFC 8446
ecdsa_secp384r1_sha384RFC 8446
ecdsa_secp521r1_sha512RFC 8446
ecdsa_sha1RFC 8446
ed25519RFC 8446
ed448RFC 8446
rsa_pkcs1_sha1RFC 8446
rsa_pkcs1_sha256RFC 8446
rsa_pkcs1_sha384RFC 8446
rsa_pkcs1_sha512RFC 8446
rsa_pss_pss_sha256RFC 8446
rsa_pss_pss_sha384RFC 8446
rsa_pss_pss_sha512RFC 8446
rsa_pss_rsae_sha256RFC 8446
rsa_pss_rsae_sha384RFC 8446
rsa_pss_rsae_sha512RFC 8446

Copyright © 1993, 2025, Oracleand/or its affiliates. All rights reserved.
Contact Us

[8]ページ先頭

©2009-2025 Movatter.jp