Documentation
¶
Overview ¶
Package aucpace provides easy to use (strong) AuCPace operations.
Example ¶
package main import ( "bytes" "fmt" "os" Client "github.com/bytemare/pake/AuCPace/client" Server "github.com/bytemare/pake/AuCPace/server" "github.com/bytemare/pake/AuCPace/verifier" "github.com/bytemare/pake/crypto" "github.com/bytemare/pake/crypto/hashing/phf/argon2id" ) var serverID = []byte("server") var ad []byte = nil var username = []byte("user") var password = []byte("password") const ihfKeylen = 64 const ssidLength = 16 func newPasswordVerifierSetup() *verifier.PasswordVerifierRecord { /** Database requirements : - if there's a connection attempt for a user that is not known, the database should still return an entry, but with q = hash(username || seed) and W = map_to_group(w), and the front end should use rate-limiting. Both prevent against user enumeration. */ /* We want to set up a new password for a client that already exists and has authenticated. We dig up the pvr from database given the username, and set q := random scalar, and W = nil. */ pvr := verifier.PvrInit(verifier.SAPVD, argon2id.NewArgon2idSigma(ihfKeylen), username) if err := pvr.Buildq(); err != nil { fmt.Println(err) os.Exit(1) } q := pvr.SaltDerivationQ() sigma, err := pvr.Sigma.Encode() if err != nil { fmt.Println(err) os.Exit(1) } /* The server sends encoded sigma and q to the client. */ client := Client.New(username, password, serverID, nil, ad, crypto.Ristretto255sha512) // The client builds the verifier W from username, password, a q derivation and sigma W, err := client.BuildVerifier(q, sigma) if err != nil { fmt.Println(err) os.Exit(1) } /* Client sends W to server, and server completes password verifier record */ pvr.Finish(W) return pvr } func main() { /* Before the authentication session, a client must have created an account within the server, that holds a PVR for the client. For the demo, we'll set one p. */ pvr := newPasswordVerifierSetup() /* Start AuCPace protocol Step 1 : OPRF Blind Salt exchange */ ssid, err := crypto.RandomBytes(ssidLength) if err != nil { fmt.Println(err) return } client := Client.New(username, password, serverID, ssid, ad, crypto.Ristretto255sha512) // Client calculates a blinder U for the salt U, err := client.Start() if err != nil { fmt.Println(err) return } /* Client sends ssid, U and username to server */ // Server receives username and U, and eventually ssid // Server looks up database to retrieve Password Verifier Record pvr server := Server.New(serverID, username, pvr, ssid, ad, crypto.Ristretto255sha512) /* Step 2 : calculate UQ,X,sigma and Ya Begin CPace sub step */ UQ, X, sigma, Ya, err := server.Start(U) if err != nil { fmt.Println(err) return } /* Server sends (UQ,X,sigma,Ya) and pvr type to client Upon reception, the client : - unblinds the salt if necessary - computes XWs, the password to be used in the CPace sub steps - compute Yb - Derive ISK - if an error is detected at these stages, abort - if not, send Yb to server */ Yb, Tb, err := client.Continue(pvr.PvrType, UQ, X, sigma, Ya) if err != nil { fmt.Println(err) return } /* Client sends Yb to server to complete the CPace sub steps, The Client also sends Tb, its authentication tag */ // Server receives Yb from Client, and calculates the intermediate Shared Secret Session Key // At this point both parties have the same Intermediary Secret Session Key /* CPace sub steps completed and validated Step 3 : Start explicit authentication */ // Server calculates its own authentication tags // If the received authentication tag Tb did not match // the verification value Tb_v A MUST abort. // If the tag is validated, send Ta to client // Server MUST abort if Tb != Tb_v if err := server.Continue(Yb, Tb); err != nil { fmt.Println(err) return } Ta := server.AuthenticationTag() /* Server sends authentication tag Ta to client */ // Client receives T_a from server and compare this to the verification value Ta_v. // Client MUST abort if Ta != Ta_v if err := client.VerifyPeerTag(Ta); err != nil { fmt.Println(err) return } /* End of Explicit Authentication Step Both parties are now mutually authenticated and can derive the AuCPace shared secret session key */ serverSK := server.Finish() clientSK := client.Finish() /* Both keys are identical if and only if : - ssid and ci are the same for both parties - the password verifier in the server database for the user was calculated form the cleartext password used by the user */ if bytes.Equal(clientSK, serverSK) { println("Success ! Both parties share the same secret session key !") } else { println("Failed. Client and server keys are different.") } // Output : Success ! Both parties share the same secret session key ! }
Output:
Directories
¶
Path | Synopsis |
---|---|
Package client provides an implementation of a (strong) AuCPace client.
|
Package client provides an implementation of a (strong) AuCPace client. |
Package server provides an implementation for a (strong) AuCPace server.
|
Package server provides an implementation for a (strong) AuCPace server. |
Package verifier implements an AuCPace Password Verifier Record as per the AuCPace draft
|
Package verifier implements an AuCPace Password Verifier Record as per the AuCPace draft |
Click to show internal directories.
Click to hide internal directories.