Skip to content
This repository has been archived by the owner on Feb 8, 2023. It is now read-only.

Commit

Permalink
add more tests and documents.
Browse files Browse the repository at this point in the history
  • Loading branch information
zensh committed Mar 15, 2018
1 parent a473ab0 commit 607c06f
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 23 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ go:
- 1.9.2
- 1.9.3
- 1.9.4
- 1.10
before_install:
- go get -v ./...
- go get github.com/stretchr/testify/assert
Expand Down
70 changes: 57 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ https://godoc.org/github.com/teambition/crypto-go

## API

crypto "github.com/teambition/crypto-go":
```go
func Equal(a, b []byte) bool

Expand All @@ -24,18 +25,6 @@ func HmacSum(h func() hash.Hash, key, data []byte) []byte
func SHA256Sum(data []byte) []byte
func SHA256Hmac(key, data []byte) []byte

func AESEncrypt(salt, key, data []byte) ([]byte, error)
func AESDecrypt(salt, key, cipherData []byte) ([]byte, error)

func AESEncryptStr(salt []byte, key, plainText string) (string, error)
func AESDecryptStr(salt []byte, key, cipherText string) (string, error)

func SignPass(salt []byte, id, pass string, args ...int) (checkPass string)
func VerifyPass(salt []byte, id, pass, checkPass string, args ...int) bool

func SignState(key []byte, uid string) string
func VerifyState(key []byte, uid, state string, expire time.Duration) bool

type Rotating []interface{}
func (r Rotating) Verify(fn func(interface{}) bool) (index int)

Expand All @@ -46,7 +35,62 @@ type RotatingBytes [][]byte
func (r RotatingBytes) Verify(fn func([]byte) bool) (index int)
```

state "github.com/teambition/crypto-go/state":
```go
func Sign(key []byte, message string) string
func Verify(key []byte, message, state string, expire ...time.Duration) bool

func New(keys ...[]byte) (*States, error)
func (s *States) Sign(message string) string
func (s *States) Verify(message, state string, expire ...time.Duration) bool
```

signature "github.com/teambition/crypto-go/signature":
```go
func Sign(secretKey, message []byte) (sig []byte)
func Verify(secretKey, message, sig []byte) bool

func SignPrivate(privateKey, message []byte) (sig []byte)
func VerifyPublic(publicKey, message, sig []byte) bool

func GenerateKey() (publicKey, privateKey string)
func KeyPairFrom(publicKey string, privateKey ...string) (*KeyPair, error)

func (k *KeyPair) Sign(message []byte) (sig []byte)
func (k *KeyPair) Verify(message, sig []byte) bool
```

password "github.com/teambition/crypto-go/password":
```go
func Sign(salt []byte, id, pass string, args ...int) (checkPass string)
func Verify(salt []byte, id, pass, checkPass string, args ...int) bool

func New(salt []byte, args ...int) *Password
func (p *Password) Sign(id, pass string) (checkPass string)
func (p *Password) Verify(id, pass, checkPass string) bool
```

cipher "github.com/teambition/crypto-go/cipher":
```go
func GenerateKey() (publicKey, privateKey string)

func NewBox(publicKey, privateKey string) (*Box, error)
func (b *Box) Encrypt(data []byte) ([]byte, error)
func (b *Box) Decrypt(encrypted []byte) ([]byte, error)

func NewSalsa20(key []byte) (*Salsa20, error)
func (s *Salsa20) Encrypt(data []byte) ([]byte, error)
func (s *Salsa20) Decrypt(encrypted []byte) ([]byte, error)

func NewAES(salt, key []byte) (*AES, error)
func (a *AES) Encrypt(data []byte) ([]byte, error)
func (a *AES) Decrypt(encrypted []byte) ([]byte, error)

func EncryptToBase64(c Cipher, msg []byte) (string, error)
func DecryptFromBase64(c Cipher, encrypted string) ([]byte, error)
```

## License

crypto-go is licensed under the [MIT](https://github.com/teambition/crypto-go/blob/master/LICENSE) license.
Copyright © 2016-2017 [Teambition](https://www.teambition.com).
Copyright © 2016-2018 [Teambition](https://www.teambition.com).
11 changes: 11 additions & 0 deletions cipher/cipher.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ func (b *Box) Decrypt(encrypted []byte) ([]byte, error) {
return decrypted, nil
}

// NewSalsa20 -
func NewSalsa20(key []byte) (*Salsa20, error) {
if l := len(key); l != 32 {
return nil, errors.New("crypto-go: bad Salsa20 key length: " + strconv.Itoa(l))
}

secretKey := new([32]byte)
copy(secretKey[:], key)
return &Salsa20{secretKey}, nil
}

// Salsa20 - nacl/secretbox
type Salsa20 struct {
secretKey *[32]byte
Expand Down
19 changes: 10 additions & 9 deletions state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import (

// Sign generates a state string signed with SHA3 256.
// It is useful for OAUTH2 or Web hook callback.
// base64URL(8 bytes time + 8 bytes nonce + 32 bytes sha3 256)
// base64RawURL(8 bytes time + 8 bytes nonce + 32 bytes sha3 256)
//
// fmt.Println(Sign([]byte("my key"), ""))
// // 4oTzpwsAAADLzShVZCoIHspsWHtn1Mk9CPOxHjNnkEoF5w1e43AZWoXINSsMFx7R
// // zILSqgsAAACNRsElhX2IP-HqOmhKKSMJDNv2f7G2ONo-ULM4G4zppTWTiSDKwCjc
// fmt.Println(Sign([]byte("my key"), "some message"))
// // 4oTzpwsAAADBqTpBcbgJp83Jj45xp6KYz-W6aMUfaav25pCTX51ZhGAax0C-y5x9
// // zILSqgsAAAA01z-LM1BfpaW9l7dK9zPUUJZl1P0_Jr4yEgYWHSQ_bFeiGFKA6qq6
//
func Sign(key []byte, message string) string {
nonce := make([]byte, 16)
Expand All @@ -29,7 +29,7 @@ func Sign(key []byte, message string) string {

// Verify Verify state that generated by Sign.
//
// fmt.Println(Verify([]byte("my key"), "", state, 60* time.Second)
// fmt.Println(Verify([]byte("my key"), "", state, 60 * time.Second)
//
func Verify(key []byte, message, state string, expire ...time.Duration) bool {
s, err := base64.RawURLEncoding.DecodeString(state)
Expand All @@ -46,28 +46,29 @@ func Verify(key []byte, message, state string, expire ...time.Duration) bool {
return crypto.Equal(s[16:], sign(key, append([]byte(message), s[:16]...)))
}

// New -
// New creates an instance of States.
func New(keys ...[]byte) (*States, error) {
if len(keys) == 0 || len(keys[0]) == 0 {
return nil, errors.New("invalid keys")
}
return &States{keys: crypto.RotatingBytes(keys)}, nil
}

// States -
// States is a rotating Sign/Verify struct.
type States struct {
keys crypto.RotatingBytes
}

// Sign -
// Sign generates a state string signed with SHA3 256.
// base64RawURL(8 bytes time + 8 bytes nonce + 32 bytes sha3 256)
func (s *States) Sign(message string) string {
return Sign(s.keys[0], message)
}

// Verify -
// Verify Verify state that generated by Sign.
func (s *States) Verify(message, state string, expire ...time.Duration) bool {
val, err := base64.RawURLEncoding.DecodeString(state)
if err != nil || len(val) != 36 {
if err != nil || len(val) != 48 {
return false
}

Expand Down
34 changes: 34 additions & 0 deletions state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,37 @@ func TestCryptoState(t *testing.T) {
assert.False(Verify(key, "cb374f9a1d2c3e8e56fe76c7e0770531eed27c89beae9de4", state, time.Second))
})
}

func TestCryptoStates(t *testing.T) {
ss, err := New()
assert.Nil(t, ss)
assert.NotNil(t, err)

ss, err = New([]byte{})
assert.Nil(t, ss)
assert.NotNil(t, err)

ss, err = New([]byte("my new key"), []byte("my key"))
assert.Nil(t, err)

t.Run("Sign and Verify should work", func(t *testing.T) {
assert := assert.New(t)

assert.False(ss.Verify("some message 1", Sign([]byte("my key"), "some message")))
assert.True(ss.Verify("some message", Sign([]byte("my key"), "some message")))
assert.False(ss.Verify("some message 1", ss.Sign("some message")))
assert.True(ss.Verify("some message", ss.Sign("some message")))
assert.True(ss.Verify("some message", ss.Sign("some message"), time.Second))
assert.Equal(64, len(ss.Sign("some message")))

})

t.Run("should verify failure when expired", func(t *testing.T) {
assert := assert.New(t)

assert.True(ss.Verify("some message", ss.Sign("some message")))
assert.True(ss.Verify("some message", ss.Sign("some message"), time.Second))
time.Sleep(2 * time.Second)
assert.True(ss.Verify("some message", ss.Sign("some message"), time.Second))
})
}

0 comments on commit 607c06f

Please sign in to comment.