CPace — A Balanced Composable PAKE

--

Key exchange happens every single time you connect to the Internet. With this, you and the server need to discuss the type and size of the key that you both want to use and then create it. But Eve may be listening and might steal the key and decipher all of your communications. And, so, we normally use a method where we have a secret and then create a public value. These public values can then be interchanged and reveal a shared secret between two parties (Bob and Alice). The most common method is ECDH (Elliptic Curve Diffie Hellman), where Bob creates a secret of b, and Alice creates a secret of a, and exchange values to reveal the same shared key:

But, what if Bob and Alice want to bind the key to a context, such as related to the network session. They might also have a password that they share. Eve cannot then link the key creation into another session and will, hopefully, not know the shared password. One method of achieving this is to use a PAKE (Password Authentication Key Exchange) method, such as CPace [here][1]:

With this, we have three shared elements on either side: secret; context1; and context2. At least one of these elements must be kept secret:

The following is the Golang code [here]:

package main
import (
"fmt"
"os"
"filippo.io/cpace"
)
func main() {
password := "password"
context := "192.0.2.1:12345"
context2 := "192.0.2.1:443"
argCount := len(os.Args[1:])
if argCount > 0 {
password = os.Args[1]
}
if argCount > 1 {
context = os.Args[2]
}
if argCount > 2 {
context2 = os.Args[3]
}
c := cpace.NewContextInfo(context, context2, nil)
pubA, s, _ := cpace.Start(password, c)
pubB, keyB, _ := cpace.Exchange(password, c, pubA)
keyA, _ := s.Finish(pubB)
fmt.Printf("Password: %s\n", password)
fmt.Printf("Context 1: %s\n", context)
fmt.Printf("Context 2: %s\n", context2)
fmt.Printf("\n== Key Exchange ===\n")
fmt.Printf("Alice public value: %x\n", pubA)
fmt.Printf("Bob public value: %x\n", pubB)
fmt.Printf("\n== Final key ===\n")
fmt.Printf("Alice key:\t%x\n", keyA)
fmt.Printf("Bob key:\t%x\n", keyB)
}

and a sample run is [here]:

Password: Qwerty123
Context 1: 192.168.1.1.:443
Context 2: 192.168.1.10:5432
== Key Exchange ===
Alice public value: 5875ddb47d58a8e2ea6cfbc45e7f44e910675700db6c196632866ad9601c2ee4385c00ecd32e101023282afe31e59407
Bob public value: 86b21599f57295571fc98f7eb8ef27054ecc5924137ade7059825822baaa4734
== Final key ===
Alice key: 00de88c1d61d67e9470dd9660bc58cef81a85f3e2f73ec812a1a9c43ba2bed6f
Bob key: 00de88c1d61d67e9470dd9660bc58cef81a85f3e2f73ec812a1a9c43ba2bed6f

Conclusions

If you are interested in PAKE, try here:

References

[1] Cpace: https://datatracker.ietf.org/doc/draft-irtf-cfrg-cpace/.

--

--

Prof Bill Buchanan OBE FRSE
ASecuritySite: When Bob Met Alice

Professor of Cryptography. Serial innovator. Believer in fairness, justice & freedom. Based in Edinburgh. Old World Breaker. New World Creator. Building trust.