// Write the message (contents of p) to w's underlying data stream. // // The message is first encrypted using a randomly generated nonce // and the SecureWriter's public and private keys. // // The total fields written to the SecureWriter's data stream are: // // - Nonce: randomly generated nonce, nonceSize bytes (in this case, 24) // - Message Length (uint32): length of the encrypted message, in bytes. // - Encrypted Message: the encrypted message itself. // // All values use LittleEndian encoding by convention. // // Returns the length (in bytes) of the box (encrypted message). // This does not include the sizes of the nonce or message length. func (w SecureWriter) Write(p []byte) (n int, err error) { nonce, err := generateNonce() if err != nil { return 0, errors.New("could not generate nonce: " + err.Error()) } // encrypt the message box := box.Seal(nil, p, nonce, w.publicKey, w.privateKey) // write the nonce if err = binary.Write(w.writer, binary.LittleEndian, nonce); err != nil { return 0, errors.New("could not write nonce: " + err.Error()) } // write the encrypted message length boxLen := uint32(len(box)) if err = binary.Write(w.writer, binary.LittleEndian, boxLen); err != nil { return 0, errors.New("could not write box length: " + err.Error()) } // write the message itself if err = binary.Write(w.writer, binary.LittleEndian, box); err != nil { return 0, errors.New("could not write encrypted message: " + err.Error()) } return int(boxLen), nil }
func (sw *SecureWriter) Write(message []byte) (int, error) { // Generate a random nonce nonce, err := randomNonce() if err != nil { log.Println("Error generating nonce", err) return 0, err } // Convert message to encrypted byte slice with nonce encrypted := box.Seal(nonce[:], message, nonce, sw.pub, sw.priv) payloadSize := len(encrypted) // Write payload size to buffer err = binary.Write(sw.w, binary.LittleEndian, uint32(payloadSize)) if err != nil { log.Println("Error writing payloadSize to buffer", err) return 0, err } // Write encrypted message to buffer _, err = sw.w.Write(encrypted) if err != nil { log.Println("Error writing encrypted message to buffer", err) return 0, err } return len(message), nil }
func (sw *SecureWriter) Write(p []byte) (n int, err error) { var out []byte //log.Println("before Seal ", p) encrypted := box.Seal(out, p, sw.getNonce(), sw.pub, sw.priv) //log.Println("after Seal ", encrypted, out) return sw.w.Write(encrypted) }
// Encrypts and writes to the writer outputing the following structure: // The first two bytes are the length(x) of the encrypted message. // The next 24 bytes are a random nonce. // The next x bytes is the encrypted message. func (s *SecureWriter) Write(p []byte) (int, error) { nonce, err := generateNonce() if err != nil { return 0, err } payload := box.Seal(nil, p, nonce, s.pub, s.priv) plen := make([]byte, 2) binary.PutVarint(plen, int64(len(payload))) ew := &errWriter{w: s.writer} ew.write(plen) ew.write(nonce[:]) ew.write(payload) if ew.err != nil { // If an error occurred, bytes may have been written // but they do not correspond to bytes of `p` written, // which is what the io.Writer interface cares about. // SecureWriter is pretty much all or nothing. return 0, ew.err } return len(p), ew.err }
// Write will encrypt p, then write the ciphertext. // Data is in the format: nonce (24 bytes), cipherlength (2 bytes), ciphertext (cipherlength+box.Overhead bytes) func (w SecureWriter) Write(p []byte) (int, error) { var nonce [24]byte rand.Read(nonce[:]) // Write the plaintext nonce to the stream err := binary.Write(w.writer, binary.BigEndian, &nonce) if err != nil { return 0, err } // Write the length of the plaintext message err = binary.Write(w.writer, binary.BigEndian, uint16(len(p))) if err != nil { return 0, err } c := box.Seal(nil, p, &nonce, w.publicKey, w.privateKey) err = binary.Write(w.writer, binary.BigEndian, c) if err != nil { return 0, err } // Return the number of plaintext bytes written, the user is not concerned with the overhead return len(c) - box.Overhead, nil }
// encodeJSONCaveatId creates a JSON encoded third-party caveat. func encodeJSONCaveatId(key *KeyPair, ci caveatInfo) ([]byte, error) { var nonce [NonceLen]byte if _, err := rand.Read(nonce[:]); err != nil { return nil, errgo.Notef(err, "cannot generate random number for nonce") } plain := caveatIdRecord{ RootKey: ci.rootKey, Condition: ci.condition, } plainData, err := json.Marshal(&plain) if err != nil { return nil, errgo.Notef(err, "cannot marshal %#v", &plain) } sealed := box.Seal(nil, plainData, &nonce, ci.peerPublicKey.boxKey(), key.Private.boxKey()) id := caveatId{ ThirdPartyPublicKey: ci.peerPublicKey, FirstPartyPublicKey: &key.Public, Nonce: nonce[:], Id: base64.StdEncoding.EncodeToString(sealed), } data, err := json.Marshal(id) if err != nil { return nil, errgo.Notef(err, "cannot marshal %#v", id) } buf := make([]byte, base64.StdEncoding.EncodedLen(len(data))) base64.StdEncoding.Encode(buf, data) return buf, nil }
// Write writes the NaCl-encrypted data of p to the underlying datastream. // See http://godoc.org/io#Writer for how Write(p []byte) works in general. func (w *SecureWriter) Write(p []byte) (n int, err error) { // First we need to encrypt this, luckily we have a shaker in our toolbox, let's add some salt! var message []byte nonce, err := getNonce() if err != nil { return 0, err } message = box.Seal(nil, p, nonce, w.peersPublicKey, w.privateKey) ms := int64(binary.Size(message)) // Write message length err = binary.Write(w.writer, binary.LittleEndian, ms) if err != nil { return 0, err } // Write nonce err = binary.Write(w.writer, binary.LittleEndian, nonce) if err != nil { return 0, err } // Write message err = binary.Write(w.writer, binary.LittleEndian, message) if err != nil { return 0, err } return int(ms), err }
// Share creates a shared key, which the given key can use to decrypt // the secret. // Requires the master key to be unsealed. func (s *Secret) Share(key *Key) (shared *Secret, err error) { if IsSealed() { err = errors.New("Please unseal first") return } shared = new(Secret) shared.Name = s.Name shared.Key = *key err = s.Key.Decrypt() if err != nil { return } defer s.Key.Zero() if err = shared.newNonce(); err != nil { return } // Generate a public key from the master pub := new([32]byte) curve25519.ScalarBaseMult(pub, master) shared.Pubkey = pub[:] shared.Message = box.Seal( nil, s.Key.raw[:], shared.nonce(), key.pubkey(), master) return }
func Seal(out, message []byte, peersPublicKey *[32]byte) []byte { otk_pub, otk_priv, err := box.GenerateKey(rand.Reader) if err != nil { panic(err) } return box.Seal(append(out, otk_pub[:]...), message, &n, peersPublicKey, otk_priv) }
// Write reads from b and writes it securely into s func (s *SecureWriter) Write(b []byte) (int, error) { if s.closed { return 0, io.EOF } if len(b) == 0 { return 0, fmt.Errorf("No bytes to write") } nonce := newNonce() o := box.Seal(nil, b, nonce, s.pub, s.priv) var length byte = byte(len(o)) if length == 0 { return 0, fmt.Errorf("Error writing secure message with nonce: %v", nonce) } var out []byte // nonce out = append(out, nonce[:]...) // length out = append(out, length) // encrypted bytes out = append(out, o...) return s.Writer.Write(out) }
// Write will encrypt data and then Write it to the underlying // io.Writer. the return value is the size of data, and not the // amount of encrypted data Written. func (sw SecureWriter) Write(data []byte) (int, error) { var boxed []byte var nonce [24]byte var err error var boxedLen int64 // Generate random nonce. Risks of Collision are negligible // The nonce MUST be different for each call to box.Seal err = readBinaryData(rand.Reader, &nonce, err) if err != nil { return 0, err } boxed = box.Seal(boxed, data, &nonce, sw.peerPub, sw.priv) boxedLen = int64(len(boxed)) // A message is, in order: the nonce, the length of the encrypted // data, and finally the encrypted data err = writeBinaryData(sw.w, &nonce, err) err = writeBinaryData(sw.w, &boxedLen, err) err = writeBinaryData(sw.w, boxed, err) if err != nil { return 0, err } return len(data), err }
// CompletePasswordReset encrypts the new password in such a way that // it can only be decrypted by the Server using the generated Token, // and posts everything needed back to the server. func (u *User) CompletePasswordReset(tok *PasswordChangeToken, newPassword string) error { pubKey, privKey, err := box.GenerateKey(rand.Reader) theirPubKey := [32]byte{} nonce := [24]byte{} copy(theirPubKey[:], tok.Token[:]) cnt, err := rand.Read(nonce[:]) if err != nil { return err } if cnt != 24 { return errors.New("Not enough randomness to encrypt the box") } payload := `{"password":"******"}` encPayload := box.Seal(nil, []byte(payload), &nonce, &theirPubKey, privKey) body := fmt.Sprintf(`{"token":"%v","decoder":"%v","nonce":"%v","payload":"%v","digest":true}`, base64.StdEncoding.EncodeToString(theirPubKey[:]), base64.StdEncoding.EncodeToString(pubKey[:]), base64.StdEncoding.EncodeToString(nonce[:]), base64.StdEncoding.EncodeToString(encPayload)) _, err = session.request("POST", urlFor(u, "complete_password_reset"), []byte(body)) if err != nil { return err } return nil }
// Writer implements io.Writer, this function encodes a message using // crypto.nacl.box.Seal, then prepends a random generated nonce to it, // and writes it to s.w encoded using binary.Write func (s SecureWriter) Write(message []byte) (n int, err error) { if len(message) > MAX_BYTE_LENGTH { return 0, errors.New("The data to be encoded is to big") } nonce := GenerateNonce() // Use box.Seal to encode the data var out []byte encText := box.Seal(out, message, &nonce, s.pub, s.priv) // The nonce will be preceding the binary data of the message binaryData := append(nonce[:], encText...) // Encode the nonce + encodedMsg using binary.Write buf := new(bytes.Buffer) err = binary.Write(buf, binary.LittleEndian, binaryData) // Get the size of encoded data and prepend it in format [2]byte size := uint16(buf.Len()) dataSize := make([]byte, 2) binary.LittleEndian.PutUint16(dataSize, size) data := make([]byte, size) n, err = buf.Read(data) data = append(dataSize, data...) // Data will be: // |length [2]byte| binary encoded data [length]byte n, err = s.w.Write(data) return n, err }
// Write encrypts p and writes the contents to the underlying data stream, // returning the number of bytes written from p (either 0 or len(p)), and // any error occurred while writing the data. The encrypted data contains // the nonce (24 bytes), box size (2 bytes), and box (len(p)+box.Overhead). func (w *SecureWriter) Write(p []byte) (n int, err error) { // Generate a random nonce. var nonce [24]byte _, err = rand.Read(nonce[:]) // Encrypt the data, getting a freshly allocated []byte back. box := box.Seal(nil, p, &nonce, w.ppub, w.priv) // A uint16(2 bytes) is enough to handle a maximum size of 32*1024 bytes messages. size := make([]byte, 2) binary.LittleEndian.PutUint16(size, uint16(len(box))) // "Sticky error" write function. write := func(buf []byte) { if err != nil { return } _, err = w.w.Write(buf) } // Write the data: nonce(24 bytes), size(2 bytes), box ('size' bytes). write(nonce[:]) write(size) write(box) if err == nil { n = len(p) } return }
func (h *encodeHeader) encode(encHead []byte) []byte { var err error // Test a recipient has been defined if !h.gotRecipient { err = errors.New("Header encode without defining recipient") panic(err) } // Test passed encHead is the correct length err = lenCheck(len(encHead), encHeadBytes) if err != nil { panic(err) } // Every header has a randomly generated sender PK & SK senderPK, senderSK, err := box.GenerateKey(rand.Reader) if err != nil { panic(err) } var nonce [24]byte copy(nonce[:], randbytes(24)) buf := new(bytes.Buffer) buf.Write(h.recipientKeyID) buf.Write(senderPK[:]) buf.Write(nonce[:]) buf.Write(box.Seal(nil, encHead, &nonce, &h.recipientPK, senderSK)) err = lenCheck(buf.Len(), 248) if err != nil { panic(err) } buf.Write(randbytes(headerBytes - buf.Len())) return buf.Bytes() }
// Write encrypts plaintext msg into w using peers public key and writer's // private key. func (sw *SecureWriter) Write(msg []byte) (n int, err error) { var ( h header encrypted []byte ) // Generate nonce. if _, err = rand.Reader.Read(h.Nonce[:]); err != nil { return } // Encrypt the message. encrypted = box.Seal(encrypted, msg, &h.Nonce, sw.pub, sw.priv) // Length of encrypted message. h.MessageLen = uint16(len(encrypted)) // Encode nonce and encrypted message length message with binary so that // reader know the length of the encrypted message. if err = binary.Write(sw.w, binary.BigEndian, h); err != nil { return } // Write the encrypted message. return sw.w.Write(encrypted) }
func (w SecureWriter) Write(p []byte) (int, error) { nonce := new([24]byte) //Just create random nonces every time ( as stated in NaCl documentation //randomness of 24 bytes provided enough entropy ) _, err := io.ReadFull(rand.Reader, nonce[:]) if err != nil { return 0, err } enc := box.Seal(nil, p, nonce, w.pubKey, w.privKey) m := new(bytes.Buffer) err = binary.Write(m, binary.LittleEndian, nonce) if err != nil { return 0, fmt.Errorf("Writing failed: %s", err) } err = binary.Write(m, binary.LittleEndian, enc) if err != nil { return 0, fmt.Errorf("Writing failed: %s", err) } return w.writer.Write(m.Bytes()) }
func (n naclBoxSecretKey) Box( receiver saltpack.BoxPublicKey, nonce *saltpack.Nonce, msg []byte) []byte { ret := box.Seal([]byte{}, msg, (*[24]byte)(nonce), (*[32]byte)(receiver.ToRawBoxKeyPointer()), (*[32]byte)(n.Private)) return ret }
// Encrypt a message for the given sender. If sender is nil, an ephemeral // keypair will be invented func (k NaclDHKeyPair) Encrypt(msg []byte, sender *NaclDHKeyPair) (*NaclEncryptionInfo, error) { if sender == nil { if tmp, err := GenerateNaclDHKeyPair(); err == nil { sender = &tmp } else { return nil, err } } else if sender.Private == nil { return nil, NoSecretKeyError{} } var nonce [NaclDHNonceSize]byte if nRead, err := rand.Read(nonce[:]); err != nil { return nil, err } else if nRead != NaclDHNonceSize { return nil, fmt.Errorf("Short random read: %d", nRead) } var ctext []byte ctext = box.Seal(ctext, msg, &nonce, ((*[32]byte)(&k.Public)), ((*[32]byte)(sender.Private))) ret := &NaclEncryptionInfo{ Ciphertext: ctext, EncryptionType: KIDNaclDH, Nonce: nonce[:], Receiver: k.GetKID().ToBytes(), Sender: sender.GetKID().ToBytes(), } return ret, nil }
func (sw *SecureWriter) Write(p []byte) (int, error) { var nonce [24]byte sw.entropy.Read(nonce[:]) buf := box.Seal(nil, p, &nonce, sw.Pub, sw.Prv) length := int64(len(buf)) if err := binary.Write(sw.W, binary.LittleEndian, nonce[:]); err != nil { // No bytes from the original datasource have been written at this point return 0, err } if err := binary.Write(sw.W, binary.LittleEndian, length); err != nil { // No bytes from the original datasource have been written at this point return 0, err } if _, err := sw.W.Write(buf); err != nil { // We don't actually know how many bytes were written of the original source // as the encrypted data is larger return 0, err } return len(p), nil }
func (b boxSecretKey) Box(receiver BoxPublicKey, nonce *Nonce, msg []byte) ([]byte, error) { var tmp [32]byte box.Precompute(&tmp, (*[32]byte)(receiver.ToRawBoxKeyPointer()), (*[32]byte)(&b.key)) ret := box.Seal([]byte{}, msg, (*[24]byte)(nonce), (*[32]byte)(receiver.ToRawBoxKeyPointer()), (*[32]byte)(&b.key)) return ret, nil }
// EncryptTLFCryptKeyClientHalf implements the Crypto interface for // CryptoCommon. func (c *CryptoCommon) EncryptTLFCryptKeyClientHalf(privateKey TLFEphemeralPrivateKey, publicKey CryptPublicKey, clientHalf TLFCryptKeyClientHalf) (encryptedClientHalf EncryptedTLFCryptKeyClientHalf, err error) { var nonce [24]byte err = cryptoRandRead(nonce[:]) if err != nil { return } keypair, err := libkb.ImportKeypairFromKID(publicKey.kid) if err != nil { return } dhKeyPair, ok := keypair.(libkb.NaclDHKeyPair) if !ok { err = libkb.KeyCannotEncryptError{} return } encryptedData := box.Seal(nil, clientHalf.data[:], &nonce, (*[32]byte)(&dhKeyPair.Public), (*[32]byte)(&privateKey.data)) encryptedClientHalf = EncryptedTLFCryptKeyClientHalf{ Version: EncryptionSecretbox, Nonce: nonce[:], EncryptedData: encryptedData, } return }
func (c *Conversation) Seal(message []byte, round uint32, role byte) []byte { var nonce [24]byte binary.BigEndian.PutUint32(nonce[:], round) nonce[23] = role ctxt := box.Seal(nil, message, &nonce, c.peerPublicKey.Key(), c.myPrivateKey.Key()) return ctxt }
// Encrypts plaintext and writes cipher text to stream func (sw SecureWriter) Write(b []byte) (n int, err error) { c := box.Seal(nil, b, sw.Nonce, sw.PeerPublicKey, sw.PrivateKey) n, err = (*sw.Writer).Write(c) if err != nil { log.Println(err) } return }
func (self *Keys) Encrypt(plaintext, nonce []byte, to *Keys) (ciphertext []byte, err error) { if len(nonce) != 24 { return nil, NonceLengthError } ciphertext = make([]byte, 0, len(plaintext)+box.Overhead) ciphertext = box.Seal(ciphertext, plaintext, nonceToArray(nonce), to.PublicArray(), self.PrivateArray()) return ciphertext, nil }
// Encrypt encrypts message m and returns encrypted message em if and only if err == nil. func (b Box) Encrypt(m []byte) (em []byte, err error) { var nonce [24]byte _, err = rand.Read(nonce[:]) if err != nil { return nil, err } em = box.Seal(nonce[:], m, &nonce, b.PeersPublicKey, b.privateKey) return em, nil }
// Write() implentation for SecureWriter. // // First this generates a nonce to use for encryption, // then reads the encrypted message. // Finally, the message is encrypted with the keypair and stored into // the return buffer. func (sw *SecureWriter) Write(p []byte) (n int, err error) { // Get a new nonce to send myNonce = getNonce() var out []byte out = box.Seal(out, p, &myNonce, sw.pub, sw.priv) sw.w.Write(myNonce[:]) sw.w.Write(out) return len(out), err }
// Write encrypted mesasge with private and shared key. func (w *SecureWriter) Write(message []byte) (int, error) { var encryptedData []byte nonce, err := GenerateNonce() if err != nil { log.Fatal(err) return -1, err } encryptedData = box.Seal(encryptedData[:0], message, nonce, w.sharedKey, w.privateKey) return w.writer.Write(append(nonce[:], encryptedData...)) }
// TODO: cache the shared key func (id *Identity) Encrypt(plain []byte, publicKey *[gotox.PublicKeySize]byte) (*[gotox.NonceSize]byte, []byte, error) { nonce := [gotox.NonceSize]byte{} // generate and write nonce _, err := rand.Read(nonce[:]) if err != nil { return nil, nil, err } encrypted := box.Seal(nil, plain, &nonce, publicKey, &id.PrivateKey) return &nonce, encrypted, nil }
func BenchmarkSeal(b *testing.B) { _, myPrivate, _ := box.GenerateKey(rand.Reader) theirPublic, _, _ := box.GenerateKey(rand.Reader) message := make([]byte, 256) nonce := new([24]byte) b.ResetTimer() for i := 0; i < b.N; i++ { box.Seal(nil, message, nonce, theirPublic, myPrivate) } }