nacl

examples
Login

examples

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]