Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

SCRAM Client API

Javadocs

For general description, please refer to the main README.md.

How to use the client API

  1. Add Maven (or equivalent) dependencies :
<dependency>
    <groupId>com.ongres.scram</groupId>
    <artifactId>client</artifactId>
    <version>VERSION</version>
</dependency>
  1. Get a ScramClient. A ScramClient can be configured with several parameters, and matches a given server. From the client, several ScramSessions can be created, for potentially different users. Under certain conditions (read Javadoc) it is thread safe.

A simple example could be:

ScramClient scramClient = ScramClient
    .channelBinding(ChannelBinding.NO)
    .stringPreparation(NO_PREPARATION)
    .serverMechanisms("SCRAM-SHA-1")
    .setup();

More configuration methods and options are available, as shown below:

ScramClient scramClient = ScramClient
    .channelBinding(ChannelBinding.YES)
    .stringPreparation(NO_PREPARATION)
    .serverMechanisms("SCRAM-SHA-1", "SCRAM-SHA-1-PLUS", "SCRAM-SHA-256", "SCRAM-SHA-256-PLUS")
    .nonceSupplier(() -> generateNonce())
    .secureRandomAlgorithmProvider("algorithm", "provider")
    .setup();
  1. For each authentication round and/or user, create a ScramSession and get the client-first-message:
ScramSession scramSession = scramClient.scramSession("user");
scramSession.clientFirstMessage()
  1. Receive the server-first-message:
ScramSession.ServerFirstProcessor serverFirst = scramSession.receiveServerFirstMessage(message);
// Read the salt and iterations:
serverFirst.getSalt()
serverFirst.getIteration()
  1. Generate the client-last-message:
ScramSession.ClientFinalProcessor clientFinal = serverFirst.finalMessagesHandler("password");
clientFinal.clientFinalMessage()
  1. Receive the server-last-message, check if is valid or error, etc:
ScramSession.ServerFinalProcessor serverFinal = clientFinal.receiveServerFinalMessage(message);
// Methods to check if it is error, get error, verify signature
serverFinal.isError()
serverFinal.getErrorMessage()
serverFinal.verifyServerSignature()

Example

The following example runs a full SCRAM session, using the RFC's data as an example.

ScramClient scramClient = ScramClient
        .channelBinding(ScramClient.ChannelBinding.NO)
        .stringPreparation(StringPreparations.NO_PREPARATION)
        .selectMechanismBasedOnServerAdvertised("SCRAM-SHA-1")
        .nonceSupplier(() -> "fyko+d2lbbFgONRv9qkxdawL")
        .setup();

ScramSession scramSession = scramClient.scramSession("user");
System.out.println(scramSession.clientFirstMessage());

ScramSession.ServerFirstProcessor serverFirstProcessor = scramSession.receiveServerFirstMessage(
        "r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096"
);
System.out.println("Salt: " + serverFirstProcessor.getSalt() + ", i: " + serverFirstProcessor.getIteration());

ScramSession.ClientFinalProcessor clientFinalProcessor
        = serverFirstProcessor.clientFinalProcessor("pencil");
System.out.println(clientFinalProcessor.clientFinalMessage());

ScramSession.ServerFinalProcessor serverFinalProcessor
        = clientFinalProcessor.receiveServerFinalMessage("v=rmF9pqV8S7suAoZWja4dJRkFsKQ=");
if(serverFinalProcessor.isError()) {
        // throw authentication exception
}

System.out.println(serverFinalProcessor.verifyServerSignature());