java keymanager_PSKKeyManager.java

这篇文章详细介绍了Conscrypt库中PSKKeyManager接口,用于支持TLS-PSK(Pre-shared Key)的密钥交换,包括身份提示、身份选择和密钥获取过程,以及最大支持的键、身份和提示长度。它强调了在实际应用中如何配置SSLContext以启用PSK功能和安全注意事项。
摘要由CSDN通过智能技术生成

/*

* Copyright 2014 The Android Open Source Project

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package org.conscrypt;

import java.net.Socket;

import javax.crypto.SecretKey;

import javax.net.ssl.KeyManager;

import javax.net.ssl.SSLEngine;

/**

* Provider of key material for pre-shared key (PSK) key exchange used in TLS-PSK cipher suites.

*

*

Overview of TLS-PSK

*

*

TLS-PSK is a set of TLS/SSL cipher suites which rely on a symmetric pre-shared key (PSK) to

* secure the TLS/SSL connection and mutually authenticate its peers. These cipher suites may be

* a more natural fit compared to conventional public key based cipher suites in some scenarios

* where communication between peers is bootstrapped via a separate step (for example, a pairing

* step) and requires both peers to authenticate each other. In such scenarios a symmetric key (PSK)

* can be exchanged during the bootstrapping step, removing the need to generate and exchange public

* key pairs and X.509 certificates.

*

*

When a TLS-PSK cipher suite is used, both peers have to use the same key for the TLS/SSL

* handshake to succeed. Thus, both peers are implicitly authenticated by a successful handshake.

* This removes the need to use a {@code TrustManager} in conjunction with this {@code KeyManager}.

*

*

*

Supporting multiple keys

*

*

A peer may have multiple keys to choose from. To help choose the right key, during the

* handshake the server can provide a PSK identity hint to the client, and the client can

* provide a PSK identity to the server. The contents of these two pieces of information

* are specific to application-level protocols.

*

*

NOTE: Both the PSK identity hint and the PSK identity are transmitted in cleartext.

* Moreover, these data are received and processed prior to peer having been authenticated. Thus,

* they must not contain or leak key material or other sensitive information, and should be

* treated (e.g., parsed) with caution, as untrusted data.

*

*

The high-level flow leading to peers choosing a key during TLS/SSL handshake is as follows:

**

Server receives a handshake request from client.

*

Server replies, optionally providing a PSK identity hint to client.

*

Client chooses the key.

*

Client provides a PSK identity of the chosen key to server.

*

Server chooses the key.

*

*

*

In the flow above, either peer can signal that they do not have a suitable key, in which case

* the the handshake will be aborted immediately. This may enable a network attacker who does not

* know the key to learn which PSK identity hints or PSK identities are supported. If this is a

* concern then a randomly generated key should be used in the scenario where no key is available.

* This will lead to the handshake aborting later, due to key mismatch -- same as in the scenario

* where a key is available -- making it appear to the attacker that all PSK identity hints and PSK

* identities are supported.

*

*

Maximum sizes

*

*

The maximum supported sizes are as follows:

**

256 bytes for keys (see {@link #MAX_KEY_LENGTH_BYTES}),

*

128 bytes for PSK identity and PSK identity hint (in modified UTF-8 representation) (see

* {@link #MAX_IDENTITY_LENGTH_BYTES} and {@link #MAX_IDENTITY_HINT_LENGTH_BYTES}).

*

*

*

Example

* The following example illustrates how to create an {@code SSLContext} which enables the use of

* TLS-PSK in {@code SSLSocket}, {@code SSLServerSocket} and {@code SSLEngine} instances obtained

* from it.

* {@code

* PSKKeyManager myPskKeyManager = ...;

*

* SSLContext sslContext = SSLContext.getInstance("TLS");

* sslContext.init(

* new KeyManager[] {myPskKeyManager},

* new TrustManager[0], // No TrustManagers needed for TLS-PSK

* null // Use the default source of entropy

* );

*

* SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(...);

* }

*/

public interface PSKKeyManager extends KeyManager {

/**

* Maximum supported length (in bytes) for PSK identity hint (in modified UTF-8 representation).

*/

int MAX_IDENTITY_HINT_LENGTH_BYTES = 128;

/** Maximum supported length (in bytes) for PSK identity (in modified UTF-8 representation). */

int MAX_IDENTITY_LENGTH_BYTES = 128;

/** Maximum supported length (in bytes) for PSK key. */

int MAX_KEY_LENGTH_BYTES = 256;

/**

* Gets the PSK identity hint to report to the client to help agree on the PSK for the provided

* socket.

*

* @return PSK identity hint to be provided to the client or {@code null} to provide no hint.

*/

String chooseServerKeyIdentityHint(Socket socket);

/**

* Gets the PSK identity hint to report to the client to help agree on the PSK for the provided

* engine.

*

* @return PSK identity hint to be provided to the client or {@code null} to provide no hint.

*/

String chooseServerKeyIdentityHint(SSLEngine engine);

/**

* Gets the PSK identity to report to the server to help agree on the PSK for the provided

* socket.

*

* @param identityHint identity hint provided by the server or {@code null} if none provided.

*

* @return PSK identity to provide to the server. {@code null} is permitted but will be

* converted into an empty string.

*/

String chooseClientKeyIdentity(String identityHint, Socket socket);

/**

* Gets the PSK identity to report to the server to help agree on the PSK for the provided

* engine.

*

* @param identityHint identity hint provided by the server or {@code null} if none provided.

*

* @return PSK identity to provide to the server. {@code null} is permitted but will be

* converted into an empty string.

*/

String chooseClientKeyIdentity(String identityHint, SSLEngine engine);

/**

* Gets the PSK to use for the provided socket.

*

* @param identityHint identity hint provided by the server to help select the key or

* {@code null} if none provided.

* @param identity identity provided by the client to help select the key.

*

* @return key or {@code null} to signal to peer that no suitable key is available and to abort

* the handshake.

*/

SecretKey getKey(String identityHint, String identity, Socket socket);

/**

* Gets the PSK to use for the provided engine.

*

* @param identityHint identity hint provided by the server to help select the key or

* {@code null} if none provided.

* @param identity identity provided by the client to help select the key.

*

* @return key or {@code null} to signal to peer that no suitable key is available and to abort

* the handshake.

*/

SecretKey getKey(String identityHint, String identity, SSLEngine engine);

}

Java程序

|

171行

|

7.4 KB

/*

* Copyright 2014 The Android Open Source Project

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package org.conscrypt;

import java.net.Socket;

import javax.crypto.SecretKey;

import javax.net.ssl.KeyManager;

import javax.net.ssl.SSLEngine;

/**

* Provider of key material for pre-shared key (PSK) key exchange used in TLS-PSK cipher suites.

*

*

Overview of TLS-PSK

*

*

TLS-PSK is a set of TLS/SSL cipher suites which rely on a symmetric pre-shared key (PSK) to

* secure the TLS/SSL connection and mutually authenticate its peers. These cipher suites may be

* a more natural fit compared to conventional public key based cipher suites in some scenarios

* where communication between peers is bootstrapped via a separate step (for example, a pairing

* step) and requires both peers to authenticate each other. In such scenarios a symmetric key (PSK)

* can be exchanged during the bootstrapping step, removing the need to generate and exchange public

* key pairs and X.509 certificates.

*

*

When a TLS-PSK cipher suite is used, both peers have to use the same key for the TLS/SSL

* handshake to succeed. Thus, both peers are implicitly authenticated by a successful handshake.

* This removes the need to use a {@code TrustManager} in conjunction with this {@code KeyManager}.

*

*

*

Supporting multiple keys

*

*

A peer may have multiple keys to choose from. To help choose the right key, during the

* handshake the server can provide a PSK identity hint to the client, and the client can

* provide a PSK identity to the server. The contents of these two pieces of information

* are specific to application-level protocols.

*

*

NOTE: Both the PSK identity hint and the PSK identity are transmitted in cleartext.

* Moreover, these data are received and processed prior to peer having been authenticated. Thus,

* they must not contain or leak key material or other sensitive information, and should be

* treated (e.g., parsed) with caution, as untrusted data.

*

*

The high-level flow leading to peers choosing a key during TLS/SSL handshake is as follows:

*

*

Server receives a handshake request from client.

*

Server replies, optionally providing a PSK identity hint to client.

*

Client chooses the key.

*

Client provides a PSK identity of the chosen key to server.

*

Server chooses the key.

*

*

*

In the flow above, either peer can signal that they do not have a suitable key, in which case

* the the handshake will be aborted immediately. This may enable a network attacker who does not

* know the key to learn which PSK identity hints or PSK identities are supported. If this is a

* concern then a randomly generated key should be used in the scenario where no key is available.

* This will lead to the handshake aborting later, due to key mismatch -- same as in the scenario

* where a key is available -- making it appear to the attacker that all PSK identity hints and PSK

* identities are supported.

*

*

Maximum sizes

*

*

The maximum supported sizes are as follows:

*

*

256 bytes for keys (see {@link #MAX_KEY_LENGTH_BYTES}),

*

128 bytes for PSK identity and PSK identity hint (in modified UTF-8 representation) (see

* {@link #MAX_IDENTITY_LENGTH_BYTES} and {@link #MAX_IDENTITY_HINT_LENGTH_BYTES}).

*

*

*

Example

* The following example illustrates how to create an {@code SSLContext} which enables the use of

* TLS-PSK in {@code SSLSocket}, {@code SSLServerSocket} and {@code SSLEngine} instances obtained

* from it.

*

 {@code

* PSKKeyManager myPskKeyManager = ...;

*

* SSLContext sslContext = SSLContext.getInstance("TLS");

* sslContext.init(

* new KeyManager[] {myPskKeyManager},

* new TrustManager[0], // No TrustManagers needed for TLS-PSK

* null // Use the default source of entropy

* );

*

* SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(...);

* }

*/

public interface PSKKeyManager extends KeyManager {

/**

* Maximum supported length (in bytes) for PSK identity hint (in modified UTF-8 representation).

*/

int MAX_IDENTITY_HINT_LENGTH_BYTES = 128;

/** Maximum supported length (in bytes) for PSK identity (in modified UTF-8 representation). */

int MAX_IDENTITY_LENGTH_BYTES = 128;

/** Maximum supported length (in bytes) for PSK key. */

int MAX_KEY_LENGTH_BYTES = 256;

/**

* Gets the PSK identity hint to report to the client to help agree on the PSK for the provided

* socket.

*

* @return PSK identity hint to be provided to the client or {@code null} to provide no hint.

*/

String chooseServerKeyIdentityHint(Socket socket);

/**

* Gets the PSK identity hint to report to the client to help agree on the PSK for the provided

* engine.

*

* @return PSK identity hint to be provided to the client or {@code null} to provide no hint.

*/

String chooseServerKeyIdentityHint(SSLEngine engine);

/**

* Gets the PSK identity to report to the server to help agree on the PSK for the provided

* socket.

*

* @param identityHint identity hint provided by the server or {@code null} if none provided.

*

* @return PSK identity to provide to the server. {@code null} is permitted but will be

* converted into an empty string.

*/

String chooseClientKeyIdentity(String identityHint, Socket socket);

/**

* Gets the PSK identity to report to the server to help agree on the PSK for the provided

* engine.

*

* @param identityHint identity hint provided by the server or {@code null} if none provided.

*

* @return PSK identity to provide to the server. {@code null} is permitted but will be

* converted into an empty string.

*/

String chooseClientKeyIdentity(String identityHint, SSLEngine engine);

/**

* Gets the PSK to use for the provided socket.

*

* @param identityHint identity hint provided by the server to help select the key or

* {@code null} if none provided.

* @param identity identity provided by the client to help select the key.

*

* @return key or {@code null} to signal to peer that no suitable key is available and to abort

* the handshake.

*/

SecretKey getKey(String identityHint, String identity, Socket socket);

/**

* Gets the PSK to use for the provided engine.

*

* @param identityHint identity hint provided by the server to help select the key or

* {@code null} if none provided.

* @param identity identity provided by the client to help select the key.

*

* @return key or {@code null} to signal to peer that no suitable key is available and to abort

* the handshake.

*/

SecretKey getKey(String identityHint, String identity, SSLEngine engine);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值