Class OwlClient
Owl is an augmented password-authenticated key exchange (PAKE) protocol, defined by Feng Hao, Samiran Bag, Liqun Chen, and Paul C. van Oorschot in the paper "Owl: An Augmented Password-Authenticated Key Exchange Scheme". Owl builds on the same idea as J-PAKE (using Schnorr zero-knowledge proofs to enforce participants to follow the protocol specification honestly), but it is augmented to provide additional protection against server compromise. While J-PAKE is symmetric, Owl is asymmetric. Like J-PAKE, Owl can be implemented in either elliptic curve (EC) or finite field (FF) settings. This implementation is done in the elliptic curve setting. Any elliptic curve that is suitable for cryptography can be used for Owl (same for J-PAKE).
Owl is an academic protocol — not (yet) an IETF standard. Callers who need a standardised
PAKE should prefer the existing J-PAKE in org.bouncycastle.crypto.agreement.jpake /
org.bouncycastle.crypto.agreement.ecjpake.
In Owl, there is one client and one server communicating between each other.
An instance of OwlServer represents one server, and
an instance of OwlClient represents one client.
These together make up the main machine through which the protocol is facilitated.
There are two distinct phases that can be taken in Owl: user registration - where the client registers as a new user on the server; login - where an existing user (client) attempts to log in and establish a shared session key with the server based on password authentication. Using the session key, the user (client) can perform further actions (e.g., password update) over a secure channel, but these actions are outside the scope of this key exchange program.
The user registration phase involves only one pass of communication from the client to the server. It's assumed that the following communication is done over a secure channel (e.g., using an out-of-band method).
OwlClientRegistration.initiateUserRegistration()- The client sends payload to the server.
OwlServerRegistration.registerUseronServer(OwlInitialRegistration) to
generate a user credential file OwlFinishRegistration and safely store it on the server.
The login phase involves three passes of communication between the client and the server.
The following communications do not have to be sent via secure channels.
Call the following methods in this order, with the client initiating every key exchange process.
-
authenticationInitiate()- The client sends payload to the server -
OwlServer.authenticationServerResponse(OwlAuthenticationInitiate, OwlFinishRegistration)- The server validates the payload received from the client, retrieves the user credentials stored in the server from user registration, and sends the payload generated to the client. -
authenticationFinish(OwlAuthenticationServerResponse)- The client validates the payload from the server, and sends next payload generated by this function back to the server.
After the third pass, the client has completed client-to-server authentication. At this point, both the client and the server can compute a shared key. They call the following methods to compute a raw keying material and do key confirmation.
-
OwlServer.authenticationServerEnd(OwlAuthenticationFinish)- The server validates the payload from the client in the third pass. -
calculateKeyingMaterial()- Both the client and the server execute this to generate a common key material. initiateKeyConfirmation(BigInteger)- Either the client or the server sends the payload to the other participant for explicit key confirmation in this exchange. This is called by both client and server.validateKeyConfirmation(org.bouncycastle.crypto.agreement.owl.OwlKeyConfirmation,java.math.BigInteger)- Either the client or the server validates the payload received from the other participant to check if the same key has been derived. This is called by both client and server.
Each side should derive a session key from the keying material returned by calculateKeyingMaterial().
The caller is responsible for deriving the session key using a secure key derivation function (KDF).
The explicit key confirmation process is optional but highly recommended. It does not affect the round efficiency and adds a negligible computational cost. The client-to-server key confirmation string
can be piggybacked in the third pass along with OwlAuthenticationFinish. The server-to-client key confirmation string can be sent in the next pass together with encrypted data.
If you do not execute key confirmation, then there is no assurance that both client and server have actually derived the same key, and the ensuing secure communication may fail.
If the key confirmation succeeds, then the keys are guaranteed to be the same on both sides.
The key confirmation process is implemented as specified in NIST SP 800-56A Revision 3, Section 5.9.1 Unilateral Key Confirmation for Key Agreement Schemes.
This class is stateful and NOT threadsafe.
Each instance should only be used for ONE complete Owl key exchange
(i.e. a new OwlServer and OwlClient should be constructed for each new Owl key exchange).
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intstatic final intstatic final intstatic final intstatic final intstatic final int -
Constructor Summary
ConstructorsConstructorDescriptionConvenience constructor for a newOwlClientthat uses theOwlCurves.NIST_P256elliptic curve, a SHA-256 digest, and a defaultSecureRandomimplementation.Convenience constructor for a newOwlClientthat uses a SHA-256 digest and a defaultSecureRandomimplementation.OwlClient(String clientId, char[] password, OwlCurve curve, Digest digest, SecureRandom random) Construct a newOwlClient. -
Method Summary
Modifier and TypeMethodDescriptionauthenticationFinish(OwlAuthenticationServerResponse authenticationServerResponse) Finalises the login authentication protocol by creating and sending the final payload to the server.Creates and returns the payload to send to the server as part of the first pass of the protocol.Calculates and returns the key material.intgetState()Gets the current state of this client.initiateKeyConfirmation(BigInteger keyingMaterial) Creates and returns the payload to send to the server as part of Key Confirmation.voidvalidateKeyConfirmation(OwlKeyConfirmation keyConfirmationPayload, BigInteger keyingMaterial) Validates the key confirmation payload received by the server.
-
Field Details
-
STATE_INITIALISED
public static final int STATE_INITIALISED- See Also:
-
STATE_LOGIN_INITIALISED
public static final int STATE_LOGIN_INITIALISED- See Also:
-
STATE_LOGIN_FINISHED
public static final int STATE_LOGIN_FINISHED- See Also:
-
STATE_KEY_CALCULATED
public static final int STATE_KEY_CALCULATED- See Also:
-
STATE_KC_INITIALISED
public static final int STATE_KC_INITIALISED- See Also:
-
STATE_KC_VALIDATED
public static final int STATE_KC_VALIDATED- See Also:
-
-
Constructor Details
-
OwlClient
Convenience constructor for a newOwlClientthat uses theOwlCurves.NIST_P256elliptic curve, a SHA-256 digest, and a defaultSecureRandomimplementation.After construction, the
statewill beSTATE_INITIALISED.- Parameters:
clientId- unique identifier of this client. The server and client in the exchange must NOT share the same id.password- shared secret. A defensive copy of this array is made (and cleared oncecalculateKeyingMaterial()is called). Caller should clear the input password as soon as possible.- Throws:
NullPointerException- if any argument is nullIllegalArgumentException- if password is empty
-
OwlClient
Convenience constructor for a newOwlClientthat uses a SHA-256 digest and a defaultSecureRandomimplementation.After construction, the
statewill beSTATE_INITIALISED.- Parameters:
clientId- unique identifier of this client. The server and client in the exchange must NOT share the same id.password- shared secret. A defensive copy of this array is made (and cleared oncecalculateKeyingMaterial()is called). Caller should clear the input password as soon as possible.curve- elliptic curve SeeOwlCurvesfor standard curves.- Throws:
NullPointerException- if any argument is nullIllegalArgumentException- if password is empty
-
OwlClient
public OwlClient(String clientId, char[] password, OwlCurve curve, Digest digest, SecureRandom random) Construct a newOwlClient.After construction, the
statewill beSTATE_INITIALISED.- Parameters:
clientId- unique identifier of this client. The server and client in the exchange must NOT share the same id.password- shared secret. A defensive copy of this array is made (and cleared oncecalculateKeyingMaterial()is called). Caller should clear the input password as soon as possible.curve- elliptic curve. SeeOwlCurvesfor standard curvesdigest- digest to use during zero knowledge proofs and key confirmation (SHA-256 or stronger preferred)random- source of secure random data for x1 and x2, and for the zero knowledge proofs- Throws:
NullPointerException- if any argument is nullIllegalArgumentException- if password is empty
-
-
Method Details
-
getState
public int getState()Gets the current state of this client. See theSTATE_*constants for possible values.- Returns:
- the state of the client
-
authenticationInitiate
Creates and returns the payload to send to the server as part of the first pass of the protocol.Must be called prior to
authenticationFinish(OwlAuthenticationServerResponse)After execution, thestatewill beSTATE_LOGIN_INITIALISED.- Returns:
OwlAuthenticationInitiate- Throws:
IllegalStateException- if called multiple times.
-
authenticationFinish
public OwlAuthenticationFinish authenticationFinish(OwlAuthenticationServerResponse authenticationServerResponse) throws CryptoException Finalises the login authentication protocol by creating and sending the final payload to the server. Validates the payload sent by theOwlServer.authenticationServerResponse(OwlAuthenticationInitiate, OwlFinishRegistration)after login initilisation.Must be called prior to
calculateKeyingMaterial().After execution, the
statewill beSTATE_LOGIN_FINISHED.- Parameters:
authenticationServerResponse- The payload sent byOwlServer.authenticationServerResponse(OwlAuthenticationInitiate, OwlFinishRegistration)and to be validated.- Returns:
OwlAuthenticationFinish- Throws:
CryptoException- if validation fails.IllegalStateException- if called prior toauthenticationInitiate()or called multiple times.
-
calculateKeyingMaterial
Calculates and returns the key material. A session key must be derived from this key material using a secure key derivation function (KDF). The KDF used to derive the key is handled externally (i.e. not byOwlClient).The keying material will be identical for client and server if and only if the login password is the same as the password stored by the server. i.e. If the client and server do not share the same password, then each will derive a different key. Therefore, if you immediately start using a key derived from the keying material, then you must handle detection of incorrect keys. If you want to handle this detection explicitly, you can perform explicit key confirmation. See
OwlClientfor details on how to execute key confirmation.If the passwords used for registration and login are different then this will be caught when validating r during
OwlServer.authenticationServerEnd(OwlAuthenticationFinish).authenticationFinish(OwlAuthenticationServerResponse)must be called prior to this method.As a side effect, the internal
passwordarray is cleared, since it is no longer needed.After execution, the
statewill beSTATE_KEY_CALCULATED.- Returns:
- raw key material
- Throws:
IllegalStateException- if called prior toauthenticationFinish(OwlAuthenticationServerResponse), or if called multiple times.
-
initiateKeyConfirmation
Creates and returns the payload to send to the server as part of Key Confirmation.See
OwlClientfor more details on Key Confirmation.After execution, the
statewill beSTATE_KC_INITIALISED.- Parameters:
keyingMaterial- The keying material as returned fromcalculateKeyingMaterial().- Returns:
OwlKeyConfirmation- Throws:
IllegalStateException- if called prior tocalculateKeyingMaterial(), or multiple times
-
validateKeyConfirmation
public void validateKeyConfirmation(OwlKeyConfirmation keyConfirmationPayload, BigInteger keyingMaterial) throws CryptoException Validates the key confirmation payload received by the server.See
OwlClientfor more details on Key Confirmation.After execution, the
statewill beSTATE_KC_VALIDATED.- Parameters:
keyConfirmationPayload- The key confirmation payload received from the other client.keyingMaterial- The keying material as returned fromcalculateKeyingMaterial().- Throws:
CryptoException- if validation fails.IllegalStateException- if called prior tocalculateKeyingMaterial(), or multiple times
-