Documentation ¶
Index ¶
- Constants
- Variables
- func CryptoKDF(secret []byte) ([]byte, []byte, error)
- func Decrypt(privKey *PrivateKey, in io.Reader, out io.Writer) error
- func DecryptSimple(privKey *PrivateKey, data []byte) ([]byte, error)
- func DecryptStream(in io.Reader, out io.Writer, aesKey, hmacKey []byte) error
- func DecryptStreamSimple(in io.Reader, out io.Writer, secret []byte) error
- func Encrypt(pubKey *PublicKey, in io.Reader, out io.Writer) error
- func EncryptSimple(pubKey *PublicKey, data []byte) ([]byte, error)
- func EncryptStream(in io.Reader, out io.Writer, aesKey, hmacKey []byte) error
- func EncryptStreamSimple(in io.Reader, out io.Writer, secret []byte) error
- func SingleKDF(secret []byte) ([]byte, error)
- type PrivateKey
- type PublicKey
Examples ¶
Constants ¶
const ( // PublicKeyLengthCompressed is the length of the compressed public key when marshalled. // See elliptic.MarshalCompressed. PublicKeyLengthCompressed = 67 // PublicKeyLengthUncompressed is the length of the uncompressed public key when marshalled. // See elliptic.Marshal. PublicKeyLengthUncompressed = 133 )
const StreamBufferSize = 4096
StreamBufferSize is the number of bytes to process at a time.
const StreamHMACLength = sha512.Size
StreamHMACLength is the length of the MAC used in HMAC-SHA512.
const StreamIVLength = 16
StreamIVLength is the length of the IV used in AES-CTR.
Variables ¶
var ErrInvalidMAC = errors.New("invalid mac")
var ErrInvalidPublicKey = errors.New("invalid public key")
Functions ¶
func CryptoKDF ¶
CryptoKDF is used to generate AES and HMAC keys from a secret.
this function is used within the library since two keys are required for stream encryption, but only one secret (the shared ECDH key) exists.
func Decrypt ¶
Decrypt decrypts an input stream with a given private key.
Example ¶
// parse a private key, or use a new // one generated using GenerateKey(). privateKey := ParsePrivateKey(privateKeyBytes) // open file for decryption. input, err := os.Open("secret.txt.enc") if err != nil { log.Fatal(err) } // open file for output. output, err := os.Create("secret.txt") if err != nil { log.Fatal(err) } // decrypt secret.txt.enc into secret.txt using ecc private key. err = Decrypt(privateKey, input, output) if err != nil { log.Fatal(err) }
Output:
func DecryptSimple ¶
func DecryptSimple(privKey *PrivateKey, data []byte) ([]byte, error)
DecryptSimple decrypts a byte slice with a given private key.
Example ¶
// parse a private key, or use a new // one generated using GenerateKey(). privateKey := ParsePrivateKey(publicKeyBytes) // decrypt data using the private key. plaintext, err := DecryptSimple(privateKey, ciphertext) if err != nil { log.Fatal(err) } // send or saveFile the output. fmt.Println(string(plaintext))
Output:
func DecryptStream ¶
DecryptStream decrypts an arbitrary-length input stream using AES-CTR (bit size determined by the passed AES key), and uses HMAC-SHA512 with the passed key for authentication.
func DecryptStreamSimple ¶
DecryptStreamSimple decrypts an arbitrary-length input stream using AES-256-CTR, and uses HMAC-SHA512 for authentication.
The AES and HMAC keys are acquired from a KDF seeded with the provided secret.
func Encrypt ¶
Encrypt encrypts an input stream for a given public key.
Example ¶
// parse a public key, or use a new // one generated using GenerateKey(). publicKey, err := ParsePublicKey(publicKeyBytes) if err != nil { log.Fatal(err) } // open file for encryption. input, err := os.Open("secret.txt") if err != nil { log.Fatal(err) } // open file for output. output, err := os.Create("secret.txt.enc") if err != nil { log.Fatal(err) } // encrypt secret.txt into secret.txt.enc using ecc public key. err = Encrypt(publicKey, input, output) if err != nil { log.Fatal(err) }
Output:
func EncryptSimple ¶
EncryptSimple encrypts a byte slice for a given public key.
Example ¶
// parse a public key, or use a new // one generated using GenerateKey(). publicKey, err := ParsePublicKey(publicKeyBytes) if err != nil { log.Fatal(err) } // encrypt data using the public key. ciphertext, err := EncryptSimple(publicKey, []byte("my secret string")) if err != nil { log.Fatal(err) } // send or store it. hex or base64 are good formats. fmt.Println(hex.EncodeToString(ciphertext))
Output:
func EncryptStream ¶
EncryptStream encrypts an arbitrary-length input stream using AES-CTR (bit size determined by the passed AES key), and uses HMAC-SHA512 with the passed key for authentication.
func EncryptStreamSimple ¶
EncryptStreamSimple encrypts an arbitrary-length input stream using AES-256-CTR, and uses HMAC-SHA512 for authentication.
The AES and HMAC keys are acquired from a KDF seeded with the provided secret.
Types ¶
type PrivateKey ¶
PrivateKey is a P-521 elliptic curve private key implementation with a nested PublicKey.
func GenerateKey ¶
func GenerateKey() (*PrivateKey, error)
GenerateKey generates a P-521 key pair.
Example ¶
privateKey, err := GenerateKey() if err != nil { log.Fatal(err) } _ = privateKey.PublicKey // encapsulated public key
Output:
func ParsePrivateKey ¶
func ParsePrivateKey(data []byte) *PrivateKey
ParsePrivateKey parses a P-521 private key from a byte slice.
Example ¶
privateKey, err := GenerateKey() if err != nil { log.Fatal(err) } // it's a good idea to encrypt this before saving it. bytes := privateKey.Bytes() // exported private key bytes privateKey = ParsePrivateKey(bytes) // same key as before
Output:
func (*PrivateKey) Bytes ¶
func (sk *PrivateKey) Bytes() []byte
Bytes returns the bytes for the D value of this key.
The length of the returned slice will be PrivateKeyLength.
Example ¶
privateKey, err := GenerateKey() if err != nil { log.Fatal(err) } // it's a good idea to encrypt this before saving it. bytes := privateKey.Bytes() saveFile("myKey.sec", bytes)
Output:
func (*PrivateKey) DeriveKey ¶
func (sk *PrivateKey) DeriveKey(pk *PublicKey) ([]byte, error)
DeriveKey passes the result of ECDH through a KDF.
The returned key can be safely used as an encryption key.
Example ¶
// PrivateKey.DeriveKey(*PublicKey) is the same as PublicKey.DeriveKey(*PrivateKey) // this is your key. privateKey1, err := GenerateKey() if err != nil { log.Fatal(err) } // this key belongs to someone else. privateKey2, err := GenerateKey() if err != nil { log.Fatal(err) } // the other person will send you their public key, // which you can use to derive the shared key. sharedKey1, err := privateKey1.DeriveKey(privateKey2.PublicKey) if err != nil { log.Fatal(err) } // likewise, you will send your public key to the other // person, and they'll use it to derive the shared key. sharedKey2, err := privateKey2.DeriveKey(privateKey1.PublicKey) if err != nil { log.Fatal(err) } // these keys are safe to use directly for encryption, // unlike the shared secret returned from ECDH, because // the library passes the shared ECDH secret through a // secure key derivation function (KDF) to make this key. // these shared keys will be the same. fmt.Println(bytes.Equal(sharedKey1, sharedKey2)) // true
Output:
func (*PrivateKey) ECDH ¶
func (sk *PrivateKey) ECDH(pk *PublicKey) []byte
ECDH calculates the shared key for this key and the provided public key.
Use DeriveKey if this shared secret will be used as an encryption key.
Example ¶
// PrivateKey.ECDH(*PublicKey) is the same as PublicKey.ECDH(*PrivateKey) // this is your key. privateKey1, err := GenerateKey() if err != nil { log.Fatal(err) } // this key belongs to someone else. privateKey2, err := GenerateKey() if err != nil { log.Fatal(err) } // the other person will send you their public key, which // you can use to derive the shared secret using ECDH. sharedSecret1 := privateKey1.ECDH(privateKey2.PublicKey) // likewise, you will send your public key to the other // person, and they'll use it to derive the shared secret. sharedSecret2 := privateKey2.ECDH(privateKey1.PublicKey) // important note: you shouldn't use this shared secret // directly as an encryption key. you should first pass // it through a secure key derivation function (KDF). // this library does this for you if you call the DeriveKey // method in place of ECDH. the shared key is passed through // a secure KDF, returning a key safe to use for encryption. // these shared secrets will be the same. fmt.Println(bytes.Equal(sharedSecret1, sharedSecret2)) // true
Output:
func (*PrivateKey) Equals ¶
func (sk *PrivateKey) Equals(privKey *PrivateKey) bool
Equals returns whether the two private keys are identical.
Example ¶
privateKey, err := GenerateKey() if err != nil { log.Fatal(err) } bytes := privateKey.Bytes() // encrypt and store parsed := ParsePrivateKey(bytes) // decrypt and parse fmt.Println(parsed.Equals(privateKey)) // true
Output:
type PublicKey ¶
PublicKey is a P-521 elliptic curve public key implementation.
func ParsePublicKey ¶
ParsePublicKey parses a public key from a byte slice.
Both compressed and uncompressed keys are supported.
See elliptic.Marshal and elliptic.MarshalCompressed.
Example ¶
privateKey, err := GenerateKey() if err != nil { log.Fatal(err) } publicKey := privateKey.PublicKey // see PublicKey.Bytes() for more information. bytes := publicKey.Bytes(true) publicKey, err = ParsePublicKey(bytes) // same key as before if err != nil { log.Fatal(err) }
Output:
func (*PublicKey) Bytes ¶
Bytes marshals this key and returns the associated bytes.
The length of the returned slice will be PublicKeyLengthCompressed if true is passed, or PublicKeyLengthUncompressed if false is passed.
See elliptic.Marshal and elliptic.MarshalCompressed.
Example ¶
privateKey, err := GenerateKey() if err != nil { log.Fatal(err) } publicKey := privateKey.PublicKey // pass true to compress the public key when marshalling. // see ecies.PublicKeyLengthCompressed // and ecies.PublicKeyLengthUncompressed bytes := publicKey.Bytes(true) saveFile("myKey.pub", bytes)
Output:
func (*PublicKey) DeriveKey ¶
func (pk *PublicKey) DeriveKey(sk *PrivateKey) ([]byte, error)
DeriveKey passes the result of ECDH through a KDF.
The returned key can be safely used as an encryption key.
Example ¶
// PublicKey.DeriveKey(*PrivateKey) is the same as PrivateKey.DeriveKey(*PublicKey) // this is your key. privateKey1, err := GenerateKey() if err != nil { log.Fatal(err) } publicKey1 := privateKey1.PublicKey // this key belongs to someone else. privateKey2, err := GenerateKey() if err != nil { log.Fatal(err) } publicKey2 := privateKey2.PublicKey // the other person will send you their public key, // which you can use to derive the shared key. sharedKey1, err := publicKey1.DeriveKey(privateKey2) if err != nil { log.Fatal(err) } // likewise, you will send your public key to the other // person, and they'll use it to derive the shared key. sharedKey2, err := publicKey2.DeriveKey(privateKey1) if err != nil { log.Fatal(err) } // these keys are safe to use directly for encryption, // unlike the shared secret returned from ECDH, because // the library passes the shared ECDH secret through a // secure key derivation function (KDF) to make this key. // these shared keys will be the same. fmt.Println(bytes.Equal(sharedKey1, sharedKey2)) // true
Output:
func (*PublicKey) ECDH ¶
func (pk *PublicKey) ECDH(sk *PrivateKey) []byte
ECDH calculates the shared key for this key and the provided private key.
Use DeriveKey if this shared secret will be used as an encryption key.
Example ¶
// PublicKey.ECDH(*PrivateKey) is the same as PrivateKey.ECDH(*PublicKey) // this is your key. privateKey1, err := GenerateKey() if err != nil { log.Fatal(err) } publicKey1 := privateKey1.PublicKey // this key belongs to someone else. privateKey2, err := GenerateKey() if err != nil { log.Fatal(err) } publicKey2 := privateKey2.PublicKey // the other person will send you their public key, which // you can use to derive the shared secret using ECDH. sharedSecret1 := publicKey1.ECDH(privateKey2) // likewise, you will send your public key to the other // person, and they'll use it to derive the shared secret. sharedSecret2 := publicKey2.ECDH(privateKey1) // important note: you shouldn't use this shared secret // directly as an encryption key. you should first pass // it through a secure key derivation function (KDF). // this library does this for you if you call the DeriveKey // method in place of ECDH. the shared key is passed through // a secure KDF, returning a key safe to use for encryption. // these shared secrets will be the same. fmt.Println(bytes.Equal(sharedSecret1, sharedSecret2)) // true
Output:
func (*PublicKey) Equals ¶
Equals returns whether the two public keys are identical.
Example ¶
privateKey, err := GenerateKey() if err != nil { log.Fatal(err) } publicKey := privateKey.PublicKey // see PublicKey.Bytes() for more information. bytes := publicKey.Bytes(true) // encrypt and store parsed, err := ParsePublicKey(bytes) // decrypt and parse if err != nil { log.Fatal(err) } fmt.Println(parsed.Equals(publicKey)) // true
Output: