Documentation ¶
Overview ¶
Package secretbox encrypts and authenticates small messages.
Secretbox uses XSalsa20 and Poly1305 to encrypt and authenticate messages with secret-key cryptography. The length of messages is not hidden.
It is the caller's responsibility to ensure the uniqueness of nonces—for example, by using nonce 1 for the first message, nonce 2 for the second message, etc. Nonces are long enough that randomly generated nonces have negligible risk of collision.
This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
Example ¶
package main import ( "crypto/rand" "encoding/hex" "fmt" "io" "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/crypto/nacl/secretbox" ) func main() { // Load your secret key from a safe place and reuse it across multiple // Seal calls. (Obviously don't use this example key for anything // real.) If you want to convert a passphrase to a key, use a suitable // package like bcrypt or scrypt. secretKeyBytes, err := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574") if err != nil { panic(err) } var secretKey [32]byte copy(secretKey[:], secretKeyBytes) // You must use a different nonce for each message you encrypt with the // same key. Since the nonce here is 192 bits long, a random value // provides a sufficiently small probability of repeats. var nonce [24]byte if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil { panic(err) } // This encrypts "hello world" and appends the result to the nonce. encrypted := secretbox.Seal(nonce[:], []byte("hello world"), &nonce, &secretKey) // When you decrypt, you must use the same nonce and key you used to // encrypt the message. One way to achieve this is to store the nonce // alongside the encrypted message. Above, we stored the nonce in the first // 24 bytes of the encrypted text. var decryptNonce [24]byte copy(decryptNonce[:], encrypted[:24]) decrypted, ok := secretbox.Open(nil, encrypted[24:], &decryptNonce, &secretKey) if !ok { panic("decryption error") } fmt.Println(string(decrypted)) }
Output: hello world
Index ¶
Examples ¶
Constants ¶
const Overhead = poly1305.TagSize
Overhead is the number of bytes of overhead when boxing a message.
Variables ¶
This section is empty.
Functions ¶
func NewOpenReadSeeker ¶
func NewOpenReadSeeker(box io.ReadSeeker, nonce *[24]byte, key *[32]byte) (io.ReadSeeker, error)
NewOpenReadSeeker is a streaming variant of Open.
NewOpenReadSeeker is intended only for use in Psiphon with a payload that is independently authenticated; and consideration has been given only for client-side operation. Non-optimized reference implementation poly1305 and salsa20 code is used.
The box is accessed through an io.ReadSeeker, which allows for an initial poly1305 verification pass followed by a payload decryption pass, both without loading the entire box into memory. As such, this implementation should not be subject to the use-before-authentication or truncation attacks discussed here: https://github.com/golang/crypto/commit/9ba3862cf6a5452ae579de98f9364dd2e544844c#diff-9a969aca62172940631ad143523794ee https://github.com/golang/go/issues/17673#issuecomment-275732868
func Open ¶
Open authenticates and decrypts a box produced by Seal and appends the message to out, which must not overlap box. The output will be Overhead bytes smaller than box.
Types ¶
This section is empty.