mirror of
https://github.com/pomerium/pomerium.git
synced 2025-08-03 08:50:42 +02:00
initial release
This commit is contained in:
commit
d56c889224
62 changed files with 8229 additions and 0 deletions
36
internal/cryptutil/README.md
Normal file
36
internal/cryptutil/README.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
## Generating random seeds
|
||||
In order of preference:
|
||||
- `head -c32 /dev/urandom | base64`
|
||||
- `openssl rand -base64 32 | head -c 32 | base64`
|
||||
## Encrypting data
|
||||
|
||||
TL;DR -- Nonce reuse is a problem. AEAD isn't a clear choice right now.
|
||||
|
||||
[Miscreant](https://github.com/miscreant/miscreant.go)
|
||||
+ AES-GCM-SIV seems to have ideal properties
|
||||
+ random nonces
|
||||
- ~30% slower encryption
|
||||
- [not maintained by a BigCo](https://github.com/miscreant/miscreant.go/graphs/contributors)
|
||||
|
||||
[nacl/secretbot](https://godoc.org/golang.org/x/crypto/nacl/secretbox)
|
||||
+ Fast
|
||||
+ XSalsa20 wutg Poly1305 MAC provides encryption and authentication together
|
||||
+ A newer standard and may not be considered acceptable in environments that require high levels of review.
|
||||
-/+ maintained as an [/x/ package](https://godoc.org/golang.org/x/crypto/nacl/secretbox)
|
||||
- doesn't use the underlying cipher.AEAD api.
|
||||
|
||||
|
||||
GCM with random nonces
|
||||
+ Fastest
|
||||
+ Go standard library, supported by google $
|
||||
- Easy to get wrong
|
||||
- IV reuse is a known weakness so keys must be rotated before birthday attack. [NIST SP 800-38D](http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf) recommends using the same key with random 96-bit nonces (the default nonce length) no more than 2^32 times
|
||||
|
||||
Further reading on tradeoffs:
|
||||
- [Introducing Miscreant](https://tonyarcieri.com/introducing-miscreant-a-multi-language-misuse-resistant-encryption-library)
|
||||
- [agl's post AES-GCM-SIV](https://www.imperialviolet.org/2017/05/14/aesgcmsiv.html)
|
||||
- [x/crypto: add chacha20, xchacha20](https://github.com/golang/go/issues/24485s)
|
||||
- [GCM cannot be used with random nonces](https://github.com/gtank/cryptopasta/issues/14s)
|
||||
- [proposal: x/crypto/chacha20poly1305: add support for XChaCha20](https://github.com/golang/go/issues/23885)
|
||||
- [kubernetes](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#providers)
|
30
internal/cryptutil/hash.go
Normal file
30
internal/cryptutil/hash.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package cryptutil // import "github.com/pomerium/pomerium/internal/cryptutil"
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha512"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// Hash generates a hash of data using HMAC-SHA-512/256. The tag is intended to
|
||||
// be a natural-language string describing the purpose of the hash, such as
|
||||
// "hash file for lookup key" or "master secret to client secret". It serves
|
||||
// as an HMAC "key" and ensures that different purposes will have different
|
||||
// hash output. This function is NOT suitable for hashing passwords.
|
||||
func Hash(tag string, data []byte) []byte {
|
||||
h := hmac.New(sha512.New512_256, []byte(tag))
|
||||
h.Write(data)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
// HashPassword generates a bcrypt hash of the password using work factor 14.
|
||||
func HashPassword(password []byte) ([]byte, error) {
|
||||
return bcrypt.GenerateFromPassword(password, 14)
|
||||
}
|
||||
|
||||
// CheckPasswordHash securely compares a bcrypt hashed password with its possible
|
||||
// plaintext equivalent. Returns nil on success, or an error on failure.
|
||||
func CheckPasswordHash(hash, password []byte) error {
|
||||
return bcrypt.CompareHashAndPassword(hash, password)
|
||||
}
|
80
internal/cryptutil/hash_test.go
Normal file
80
internal/cryptutil/hash_test.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
package cryptutil // import "github.com/pomerium/pomerium/internal/cryptutil"
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPasswordHashing(t *testing.T) {
|
||||
bcryptTests := []struct {
|
||||
plaintext []byte
|
||||
hash []byte
|
||||
}{
|
||||
{
|
||||
plaintext: []byte("password"),
|
||||
hash: []byte("$2a$14$uALAQb/Lwl59oHVbuUa5m.xEFmQBc9ME/IiSgJK/VHtNJJXASCDoS"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range bcryptTests {
|
||||
hashed, err := HashPassword(tt.plaintext)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if err = CheckPasswordHash(hashed, tt.plaintext); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmarks SHA256 on 16K of random data.
|
||||
func BenchmarkSHA256(b *testing.B) {
|
||||
data, err := ioutil.ReadFile("testdata/random")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(len(data)))
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = sha256.Sum256(data)
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmarks SHA512/256 on 16K of random data.
|
||||
func BenchmarkSHA512_256(b *testing.B) {
|
||||
data, err := ioutil.ReadFile("testdata/random")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(len(data)))
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = sha512.Sum512_256(data)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBcrypt(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, err := HashPassword([]byte("thisisareallybadpassword"))
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleHash() {
|
||||
tag := "hashing file for lookup key"
|
||||
contents, err := ioutil.ReadFile("testdata/random")
|
||||
if err != nil {
|
||||
fmt.Printf("could not read file: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
digest := Hash(tag, contents)
|
||||
fmt.Println(hex.EncodeToString(digest))
|
||||
// Output: 9f4c795d8ae5c207f19184ccebee6a606c1fdfe509c793614066d613580f03e1
|
||||
}
|
BIN
internal/cryptutil/testdata/random
vendored
Normal file
BIN
internal/cryptutil/testdata/random
vendored
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue