Documentation ¶
Overview ¶
Package stream is a Golang library that transforms any net.Conn or io.ReadWriter stream to an encrypted and/or authenticated stream.
1. The encrypted stream implements net.Conn and io.ReadWriter and can be used as drop-in replacement.
2. Works with any encryption, authentication, or authenticated encryption algorithm or even arbitrary transformation. Only a cipher that implements encrypt/decrypt needs to be provided. XSalsa20-Poly1305 and AES-GCM are provided as reference cipher.
3. The encrypted stream only adds a small constant memory overhead compared to the original stream.
Note: this library does not handle handshake or key exchange. Handshake should be done separately before using this library to compute a shared key.
Example ¶
package main import ( "crypto/rand" "net" stream "github.com/nknorg/encrypted-stream" ) func main() { // We use a net.Conn as an example. conn, err := net.Dial("tcp", "golang.org:80") if err != nil { panic(err) } // In this example we treat key as a prior knowledge. In actual usage you can // do handshake here using the original stream and compute shared key before // creating encrypted stream from it. var key [32]byte _, err = rand.Read(key[:]) if err != nil { panic(err) } config := &stream.Config{ Cipher: stream.NewXSalsa20Poly1305Cipher(&key), SequentialNonce: true, // only when key is unique for every stream Initiator: true, // only on the dialer side } // Create an encrypted stream from a conn. encryptedConn, err := stream.NewEncryptedStream(conn, config) if err != nil { panic(err) } // Now you can use encryptedConn just like a regular conn _, err = encryptedConn.Write([]byte("hello world")) if err != nil { panic(err) } }
Output:
Index ¶
- Variables
- type Cipher
- type Config
- type CryptoAEADCipher
- type Decoder
- type Encoder
- type EncryptedStream
- func (es *EncryptedStream) Close() error
- func (es *EncryptedStream) IsClosed() bool
- func (es *EncryptedStream) LocalAddr() net.Addr
- func (es *EncryptedStream) Read(b []byte) (int, error)
- func (es *EncryptedStream) RemoteAddr() net.Addr
- func (es *EncryptedStream) SetDeadline(t time.Time) error
- func (es *EncryptedStream) SetReadDeadline(t time.Time) error
- func (es *EncryptedStream) SetWriteDeadline(t time.Time) error
- func (es *EncryptedStream) Write(b []byte) (int, error)
- type XSalsa20Poly1305Cipher
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrMaxNonce indicates the max allowed nonce is reach. If this happends, a // new stream with different key should be created. ErrMaxNonce = errors.New("max nonce reached") // ErrWrongNonceInitiator indicates a nonce with the wrong party is received, // i.e. initiator receives a nonce from initiator, or responder receives a // nonce from responder. It is either a configuration error (e.g. both party // set initiator to the same value), or a middle man is performing reflection // attack. ErrWrongNonceInitiator = errors.New("wrong nonce direction") // ErrWrongNonceSequential indicates a nonce with the wrong value is received. // It is either a configuration error (e.g. one side set sequentialNonce to // true, the other side set to false), or a middle man is performing replay, // re-order or packet drop attack. ErrWrongNonceSequential = errors.New("wrong nonce value") )
Functions ¶
This section is empty.
Types ¶
type Cipher ¶
type Cipher interface { // Encrypt encrypts a plaintext to ciphertext. Returns ciphertext slice // whose length should be equal to ciphertext length. Input buffer ciphertext // has enough length for encrypted plaintext, and the length satisfy: // len(ciphertext) == MaxChunkSize + MaxOverheadSize // len(plaintext) <= MaxChunkSize Encrypt(ciphertext, plaintext, nonce []byte) ([]byte, error) // Decrypt decrypts a ciphertext to plaintext. Returns plaintext slice // whose length should be equal to plaintext length. Input buffer plaintext // has enough length for decrypted ciphertext, and the length satisfy: // len(plaintext) == MaxChunkSize // len(ciphertext) <= MaxChunkSize + MaxOverheadSize Decrypt(plaintext, ciphertext, nonce []byte) ([]byte, error) // MaxOverhead is the max number of bytes overhead of ciphertext compared to // plaintext. It is only used to determine internal buffer size, so // overestimate is ok. MaxOverhead() int // NonceSize is the nonce size in bytes. NonceSize() int }
Cipher provides encrypt and decrypt function of a slice data.
type Config ¶
type Config struct { // Cipher is used to encrypt and decrypt data. Cipher Cipher // MaxChunkSize is the max number of bytes that will be encrypted and write to // underlying stream in a single chunk. If zero, default value (65535) will be // used. MaxChunkSize int // Initiator indicates the direction of the stream (initiator or responder). // Two sides of the stream should set this to different value (i.e. one stream // initiator and one stream responder) unless DisableNonceVerification is // true. Initiator bool // Use sequential nonce instead of random nonce to prevent replay, re-order // and packet drop attack. For cipher with short nonce (e.g. AES-GCM), // sequential nonce should be used to prevent nonce reuse if large amount of // data is transmitted in the same stream. Both sides of the stream should set // this to the same value unless DisableNonceVerification is true. IMPORTANT: // Enable sequential nonce only when key is unique for every stream, otherwise // key will be leaked. SequentialNonce bool // Disable nonce verification during decryption. Setting this to true will // make the stream vulnerable to reflection, replay, re-order and packet drop // attack. Do not set it to true unless you have a strong reason. DisableNonceVerification bool }
Config is the configuration for encrypted stream.
func MergeConfig ¶
MergeConfig merges a given config with the default config recursively. Any non zero value fields will override the default config.
type CryptoAEADCipher ¶
type CryptoAEADCipher struct {
// contains filtered or unexported fields
}
CryptoAEADCipher is a wrapper to crypto/cipher AEAD interface and implements Cipher interface.
func NewAESGCMCipher ¶
func NewAESGCMCipher(key []byte) (*CryptoAEADCipher, error)
NewAESGCMCipher creates a 128-bit (16 bytes key) or 256-bit (32 bytes key) AES block cipher wrapped in Galois Counter Mode with the standard nonce length. For best security, every stream should have a unique key.
func NewCryptoAEADCipher ¶
func NewCryptoAEADCipher(aead cipher.AEAD) *CryptoAEADCipher
NewCryptoAEADCipher converts a crypto/cipher AEAD to Cipher.
func (*CryptoAEADCipher) Decrypt ¶
func (c *CryptoAEADCipher) Decrypt(plaintext, ciphertext, nonce []byte) ([]byte, error)
Decrypt implements Cipher.
func (*CryptoAEADCipher) Encrypt ¶
func (c *CryptoAEADCipher) Encrypt(ciphertext, plaintext, nonce []byte) ([]byte, error)
Encrypt implements Cipher.
func (*CryptoAEADCipher) MaxOverhead ¶
func (c *CryptoAEADCipher) MaxOverhead() int
MaxOverhead implements Cipher.
func (*CryptoAEADCipher) NonceSize ¶ added in v1.0.1
func (c *CryptoAEADCipher) NonceSize() int
NonceSize implements Cipher.
type Decoder ¶ added in v1.0.1
type Decoder struct {
// contains filtered or unexported fields
}
Decoder provides decode function of a slice data.
type Encoder ¶ added in v1.0.1
type Encoder struct {
// contains filtered or unexported fields
}
Encoder provides encode function of a slice data.
func NewEncoder ¶ added in v1.0.1
NewEncoder creates a Encoder with given cipher and config.
type EncryptedStream ¶
type EncryptedStream struct {
// contains filtered or unexported fields
}
EncryptedStream is an encrypted stream. Data are encrypted before writing to underlying stream, and are decrypted after reading from underlying stream.
func NewEncryptedStream ¶
func NewEncryptedStream(stream io.ReadWriter, config *Config) (*EncryptedStream, error)
NewEncryptedStream creates an EncryptedStream with a given ReadWriter and config.
func (*EncryptedStream) Close ¶
func (es *EncryptedStream) Close() error
Close implements net.Conn and io.Closer. Will call underlying stream's Close() method if it has one.
func (*EncryptedStream) IsClosed ¶
func (es *EncryptedStream) IsClosed() bool
IsClosed returns whether the EncryptedStream is closed.
func (*EncryptedStream) LocalAddr ¶
func (es *EncryptedStream) LocalAddr() net.Addr
LocalAddr implements net.Conn. Will call underlying stream's LocalAddr() method if it has one, otherwise will return nil.
func (*EncryptedStream) Read ¶
func (es *EncryptedStream) Read(b []byte) (int, error)
Read implements net.Conn and io.Reader
func (*EncryptedStream) RemoteAddr ¶
func (es *EncryptedStream) RemoteAddr() net.Addr
RemoteAddr implements net.Conn. Will call underlying stream's RemoteAddr() method if it has one, otherwise will return nil.
func (*EncryptedStream) SetDeadline ¶
func (es *EncryptedStream) SetDeadline(t time.Time) error
SetDeadline implements net.Conn. Will call underlying stream's SetDeadline() method if it has one, otherwise will return nil.
func (*EncryptedStream) SetReadDeadline ¶
func (es *EncryptedStream) SetReadDeadline(t time.Time) error
SetReadDeadline implements net.Conn. Will call underlying stream's SetReadDeadline() method if it has one, otherwise will return nil.
func (*EncryptedStream) SetWriteDeadline ¶
func (es *EncryptedStream) SetWriteDeadline(t time.Time) error
SetWriteDeadline implements net.Conn. Will call underlying stream's SetWriteDeadline() method if it has one, otherwise will return nil.
type XSalsa20Poly1305Cipher ¶
type XSalsa20Poly1305Cipher struct {
// contains filtered or unexported fields
}
XSalsa20Poly1305Cipher is an AEAD cipher that uses XSalsa20 and Poly1305 to encrypt and authenticate messages. The ciphertext it produces contains 24 bytes of random nonce, followed by n+16 bytes of authenticated encrypted data, where n is the plaintext size.
func NewXSalsa20Poly1305Cipher ¶
func NewXSalsa20Poly1305Cipher(key *[32]byte) *XSalsa20Poly1305Cipher
NewXSalsa20Poly1305Cipher creates a XSalsa20Poly1305Cipher with a given key. For best security, every stream should have a unique key.
func (*XSalsa20Poly1305Cipher) Decrypt ¶
func (c *XSalsa20Poly1305Cipher) Decrypt(plaintext, ciphertext, nonce []byte) ([]byte, error)
Decrypt implements Cipher.
func (*XSalsa20Poly1305Cipher) Encrypt ¶
func (c *XSalsa20Poly1305Cipher) Encrypt(ciphertext, plaintext, nonce []byte) ([]byte, error)
Encrypt implements Cipher.
func (*XSalsa20Poly1305Cipher) MaxOverhead ¶
func (c *XSalsa20Poly1305Cipher) MaxOverhead() int
MaxOverhead implements Cipher.
func (*XSalsa20Poly1305Cipher) NonceSize ¶ added in v1.0.1
func (c *XSalsa20Poly1305Cipher) NonceSize() int
NonceSize implements Cipher.