Examples
Public-key cryptography authenticated encryption using nacl::box
package require nacl
nacl::box keypair pub1 sec1
nacl::box keypair pub2 sec2
set nonce [nacl::randombytes box -nonce]
set message {My Secret Message}
if {[nacl::box encrypted $message $nonce $pub2 $sec1] == 0} {
if {[nacl::box open decrypted $encrypted $nonce $pub1 $sec2] == 0} {
puts "message decrypted = '$decrypted'"
}
}
Public-key cryptography signatures using nacl::sign
package require nacl
nacl::sign keypair pub sec
set message {My Message}
if {[nacl::sign encrypted $message $sec] == 0} {
if {[nacl::sign verify decrypted $encrypted $pub] == 0} {
puts "signed message decrypted = '$decrypted'"
}
}
Secret-key cryptography authenticated encryption using nacl::secretbox
package require nacl
set key [nacl::randombytes secretbox -key]
set nonce [nacl::randombytes secretbox -nonce]
set message {My Secret Message}
if {[nacl::secretbox encrypted $message $nonce $key] == 0} {
if {[nacl::secretbox open decrypted $encrypted $nonce $key] == 0} {
puts "message decrypted = '$decrypted'"
}
}
Secret-key cryptography encryption using nacl::stream
package require nacl
set key [nacl::randombytes stream -key]
set nonce [nacl::randombytes stream -nonce]
set message {My Secret Message}
if {[nacl::stream encrypted $message $nonce $key] == 0} {
if {[nacl::stream decrypted $encrypted $nonce $key] == 0} {
puts "message decrypted = '$decrypted'"
}
}
Secret-key cryptography authentication using nacl::auth
package require nacl
set key [nacl::randombytes auth -key]
set message {My Message}
if {[nacl::auth -hmac512256 auth $message $key] == 0} {
if {[nacl::auth verify -hmac512256 $auth $message $key] == 0} {
puts {authentication OK}
}
}
The key may have any length. It is prepared as RFC 2104 section 2 requires, so a secret that comes from somewhere else can be used as it is, without padding or hashing it beforehand.
package require nacl
set secret {a client secret of whatever length the peer chose}
set message {My Message}
nacl::auth -hmac256 auth $message $secret
if {[nacl::auth verify -hmac256 $auth $message $secret] == 0} {
puts {authentication OK}
}
Verifying a JSON Web Token signed with HS256. nacl::auth verify compares in
constant time, which is what a signature check needs.
package require nacl
# base64url of the signature back to binary
proc b64url {s} {
set s [string map {- + _ /} $s]
append s [string repeat = [expr {(4 - [string length $s] % 4) % 4}]]
return [binary decode base64 $s]
}
# the token as received, and the client secret of the provider
set token {eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c}
set secret {your-256-bit-secret}
lassign [split $token .] header payload signature
if {[nacl::auth verify -hmac256 [b64url $signature] $header.$payload $secret] == 0} {
puts {token signature is valid}
}
The secret in that example is 19 bytes long. Before the key preparation was added it would have been rejected, and so would the 64 character secrets that OpenID Connect providers commonly generate.
For HS384 and HS512 the same code works with -hmac384 and -hmac512; only
the expected algorithm and the length of the decoded signature change, 48 and
64 bytes instead of 32. Do not reach for -hmac512256 there: it is the same
computation as -hmac512 cut to 32 bytes, and passing that off as HS512 is a
mismatch no peer will accept.
The five variants of nacl::auth
package require nacl
set key Jefe
set message {My Message}
foreach opt {-hmac224 -hmac256 -hmac384 -hmac512256 -hmac512} {
nacl::auth $opt tag $message $key
puts [format "%-12s %2d bytes %s..." $opt [string length $tag] \
[binary encode hex [string range $tag 0 7]]]
}
-hmac224 28 bytes 22a8f53443cf83e0...
-hmac256 32 bytes e4857e794078df78...
-hmac384 48 bytes 25c707e8e9fded04...
-hmac512256 32 bytes a280f43106a13a67...
-hmac512 64 bytes a280f43106a13a67...
The last two agree in their leading bytes because -hmac512256 is -hmac512
cut to half. -hmac224 and -hmac384 share no such prefix with -hmac256 and
-hmac512.
-hmac224, -hmac256, -hmac384 and -hmac512 are the four HMACs of RFC 4231;
-hmac512256 is NaCl's own crypto_auth, HMAC-SHA-512 cut to 32 bytes. Take the
NaCl one where both ends are yours, and the one that names its algorithm
wherever the tag has to match another implementation.
Secret-key cryptography one-time authentication using nacl::onetimeauth
package require nacl
set key [nacl::randombytes onetimeauth -key]
set message {My Message}
if {[nacl::onetimeauth auth $message $key] == 0} {
if {[nacl::onetimeauth verify $auth $message $key] == 0} {
puts {one-time authentication OK}
}
}
Hashing using nacl::hash
package require nacl
if {[nacl::hash -sha256 hash {NaCl does SHA256}] == 0} {
}
or
package require nacl
if {[nacl::hash -sha512 hash {NaCl does SHA512}] == 0} {
}
Build and version information
package require nacl
puts [nacl::build-info]
puts [nacl::build-info version]
puts [dict get [nacl::manifest] uuid]