8 "github.com/mjl-/mox/scram"
12 // Prepare credentials.
14 // The client normally remembers the password and uses it during authentication.
16 // The server sets the iteration count, generates a salt and uses the password once
17 // to generate salted password hash. The salted password hash is used to
18 // authenticate the client during authentication.
20 salt := scram.MakeRandom()
21 password := "test1234"
22 saltedPassword := scram.SaltPassword(sha256.New, password, salt, iterations)
24 check := func(err error, msg string) {
26 log.Fatalf("%s: %s", msg, err)
30 // Make a new client for authenticating user mjl with SCRAM-SHA-256.
33 client := scram.NewClient(sha256.New, username, authz, false, nil)
34 clientFirst, err := client.ClientFirst()
35 check(err, "client.ClientFirst")
37 // Instantiate a new server with the initial message from the client.
38 server, err := scram.NewServer(sha256.New, []byte(clientFirst), nil, false)
39 check(err, "NewServer")
41 // Generate first message from server to client, with a challenge.
42 serverFirst, err := server.ServerFirst(iterations, salt)
43 check(err, "server.ServerFirst")
45 // Continue at client with first message from server, resulting in message from
47 clientFinal, err := client.ServerFirst([]byte(serverFirst), password)
48 check(err, "client.ServerFirst")
50 // Continue at server with message from client.
51 // The server authenticates the client in this step.
52 serverFinal, err := server.Finish([]byte(clientFinal), saltedPassword)
54 fmt.Println("server does not accept client credentials")
56 fmt.Println("server has accepted client credentials")
59 // Finally, the client verifies that the server knows the salted password hash.
60 err = client.ServerFinal([]byte(serverFinal))
62 fmt.Println("client does not accept server")
64 fmt.Println("client has accepted server")
68 // server has accepted client credentials
69 // client has accepted server