0% found this document useful (0 votes)
468 views54 pages

Practical Cryptography With Go

The document appears to be a technical book or guide about practical cryptography using the Go programming language. It includes code examples for generating cryptographic keys and nonces in Go, encrypting and decrypting data using symmetric ciphers like AES-GCM and the NaCl secretbox, and encrypting messages with a prepended sender ID. The code uses common cryptographic primitives and data structures in Go like the cipher and io packages.

Uploaded by

spywang
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
468 views54 pages

Practical Cryptography With Go

The document appears to be a technical book or guide about practical cryptography using the Go programming language. It includes code examples for generating cryptographic keys and nonces in Go, encrypting and decrypting data using symmetric ciphers like AES-GCM and the NaCl secretbox, and encrypting messages with a prepended sender ID. The code uses common cryptographic primitives and data structures in Go like the cipher and io packages.

Uploaded by

spywang
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 54

Read Practical Cryptography With Go | Leanpub https://leanpub.

com/gocrypto/read

第1页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第2页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第3页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第4页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第5页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第6页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第7页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第8页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第9页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第10页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第11页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第12页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第13页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第14页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第15页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第16页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第17页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第18页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第19页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第20页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第21页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第22页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 const (
2 KeySize = 32
3 NonceSize = 24
4 )
5
6 // GenerateKey creates a new random secret key.
7 func GenerateKey() (*[KeySize]byte, error) {
8 key := new([KeySize]byte)
9 _, err := io.ReadFull(rand.Reader, key[:])
10 if err != nil {
11 return nil, err
12 }
13
14 return key, nil
15 }
16
17 // GenerateNonce creates a new random nonce.
18 func GenerateNonce() (*[NonceSize]byte, error) {
19 nonce := new([NonceSize]byte)
20 _, err := io.ReadFull(rand.Reader, nonce[:])
21 if err != nil {
22 return nil, err
23 }
24
25 return nonce, nil
26 }

1 var (

第23页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

2 ErrEncrypt = errors.New("secret: encryption failed")


3 ErrDecrypt = errors.New("secret: decryption failed")
4 )
5
6 // Encrypt generates a random nonce and encrypts the input using
7 // NaCl's secretbox package. The nonce is prepended to the ciphertext.
8 // A sealed message will the same size as the original message plus
9 // secretbox.Overhead bytes long.
10 func Encrypt(key *[KeySize]byte, message []byte) ([]byte, error
11 nonce, err := GenerateNonce()
12 if err != nil {
13 return nil, ErrEncrypt
14 }
15
16 out := make([]byte, len(nonce))
17 copy(out, nonce[:])
18 out = secretbox.Seal(out, message, nonce, key)
19 return out, nil
20 }

1 // Decrypt extracts the nonce from the ciphertext, and attempts to


2 // decrypt with NaCl's secretbox.
3 func Decrypt(key *[KeySize]byte, message []byte) ([]byte, error
4 if len(message) < (NonceSize + secretbox.Overhead) {
5 return nil, ErrDecrypt
6 }
7
8 var nonce [NonceSize]byte
9 copy(nonce[:], message[:NonceSize])
10 out, ok := secretbox.Open(nil, message[NonceSize:], &nonce
11 if !ok {
12 return nil, ErrDecrypt
13 }
14
15 return out, nil
16 }

第24页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 // Encrypt secures a message using AES-GCM.


2 func Encrypt(key, message []byte) ([]byte, error) {
3 c, err := aes.NewCipher(key)
4 if err != nil {
5 return nil, ErrEncrypt
6 }
7
8 gcm, err := cipher.NewGCM(c)
9 if err != nil {
10 return nil, ErrEncrypt
11 }
12
13 nonce, err := GenerateNonce()
14 if err != nil {
15 return nil, ErrEncrypt

第25页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

16 }
17
18 // Seal will append the output to the first argument; the usage
19 // here appends the ciphertext to the nonce. The final parameter
20 // is any additional data to be authenticated.
21 out := gcm.Seal(nonce, nonce, message, nil)
22 return out, nil
23 }

1 // EncryptWithID secures a message and prepends a 4-byte sender ID


2 // to the message.
3 func EncryptWithID(key, message []byte, sender uint32) ([]byte
4 buf := make([]byte, 4)
5 binary.BigEndian.PutUint32(buf, sender)
6
7 c, err := aes.NewCipher(key)
8 if err != nil {
9 return nil, ErrEncrypt
10 }
11
12 gcm, err := cipher.NewGCM(c)
13 if err != nil {
14 return nil, ErrEncrypt
15 }
16
17 nonce, err := GenerateNonce()
18 if err != nil {
19 return nil, ErrEncrypt
20 }
21
22 buf = append(buf, nonce)
23 buf := gcm.Seal(buf, nonce, message, message[:4])
24 return buf, nil
25 }

1 func DecryptWithID(message []byte) ([]byte, error) {


2 if len(message) <= NonceSize+4 {
3 return nil, ErrDecrypt
4 }
5

第26页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

6 // SelectKeyForID is a mock call to a database or key cache.


7 id := binary.BigEndian.Uint32(message[:4])
8 key, ok := SelectKeyForID(id)
9 if !ok {
10 return nil, ErrDecrypt
11 }
12
13 c, err := aes.NewCipher(key)
14 if err != nil {
15 return nil, ErrDecrypt
16 }
17
18 gcm, err := cipher.NewGCM(c)
19 if err != nil {
20 return nil, ErrDecrypt
21 }
22
23 nonce := make([]byte, NonceSize)
24 copy(nonce, message[4:])
25
26 // Decrypt the message, using the sender ID as the additional
27 // data requiring authentication.
28 out, err := gcm.Open(nil, nonce, message[4+NonceSize:],
29 if err != nil {
30 return nil, ErrDecrypt
31 }
32 return out, nil
33 }

第27页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 const (
2 NonceSize = aes.BlockSize
3 MACSize = 32 // Output size of HMAC-SHA-256
4 CKeySize = 32 // Cipher key size - AES-256
5 MKeySize = 32 // HMAC key size - HMAC-SHA-256
6 )
7
8 var KeySize = CKeySize + MKeySize
9
10 func Encrypt(key, message []byte) ([]byte, error) {
11 if len(key) != KeySize {
12 return nil, ErrEncrypt
13 }
14
15 nonce, err := util.RandBytes(NonceSize)
16 if err != nil {
17 return nil, ErrEncrypt
18 }
19
20 ct := make([]byte, len(message))
21
22 // NewCipher only returns an error with an invalid key size,
23 // but the key size was checked at the beginning of the function.
24 c, _ := aes.NewCipher(key[:CKeySize])
25 ctr := cipher.NewCTR(c, nonce)
26 ctr.XORKeyStream(ct, message)
27
28 h := hmac.New(sha256.New, key[CKeySize:])
29 ct = append(nonce, ct...)
30 h.Write(ct)
31 ct = h.Sum(ct)
32 return ct, nil
33 }

1 func Decrypt(key, message []byte) ([]byte, error) {


2 if len(key) != KeySize {

第28页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

3 return nil, ErrDecrypt


4 }
5
6 if len(message) <= (NonceSize + MACSize) {
7 return nil, ErrDecrypt
8 }
9
10 macStart := len(message) - MACSize
11 tag := message[macStart:]
12 out := make([]byte, macStart-NonceSize)
13 message = message[:macStart]
14
15 h := hmac.New(sha256.New, key[CKeySize:])
16 h.Write(message)
17 mac := h.Sum(nil)
18 if !hmac.Equal(mac, tag) {
19 return nil, ErrDecrypt
20 }
21
22 c, _ := aes.NewCipher(key[:CKeySize])
23 ctr := cipher.NewCTR(c, message[:NonceSize])
24 ctr.XORKeyStream(out, message[NonceSize:])
25 return out, nil
26 }

第29页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 func pad(in []byte) []byte {


2 padding := 16 - (len(in) % 16)
3 for i := 0; i < padding; i++ {
4 in = append(in, byte(padding))
5 }
6 return in
7 }

1 func unpad(in []byte) []byte {


2 if len(in) == 0 {
3 return nil
4 }
5
6 padding := in[len(in)-1]
7 if int(padding) > len(in) || padding > aes.BlockSize {
8 return nil
9 } else if padding == 0 {
10 return nil
11 }
12
13 for i := len(in) - 1; i > len(in)-int(padding)-1; i-- {
14 if in[i] != padding {
15 return nil
16 }
17 }
18 return in[:len(in)-int(padding)]
19 }

1 func Encrypt(key, message []byte) ([]byte, error) {


2 if len(key) != KeySize {
3 return nil, ErrEncrypt
4 }
5
6 iv, err := util.RandBytes(NonceSize)
7 if err != nil {
8 return nil, ErrEncrypt
9 }
10
11 pmessage := pad(message)

第30页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

12 ct := make([]byte, len(pmessage))
13
14 // NewCipher only returns an error with an invalid key size,
15 // but the key size was checked at the beginning of the function.
16 c, _ := aes.NewCipher(key[:CKeySize])
17 ctr := cipher.NewCBCEncrypter(c, iv)
18 ctr.CryptBlocks(ct, pmessage)
19
20 h := hmac.New(sha256.New, key[CKeySize:])
21 ct = append(iv, ct...)
22 h.Write(ct)
23 ct = h.Sum(ct)
24 return ct, nil
25 }

1 func Decrypt(key, message []byte) ([]byte, error) {


2 if len(key) != KeySize {
3 return nil, ErrEncrypt
4 }
5
6 // HMAC-SHA-256 returns a MAC that is also a multiple of the
7 // block size.
8 if (len(message) % aes.BlockSize) != 0 {
9 return nil, ErrDecrypt
10 }
11
12 // A message must have at least an IV block, a message block,
13 // and two blocks of HMAC.
14 if len(message) < (4 * aes.BlockSize) {
15 return nil, ErrDecrypt
16 }
17

第31页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

18 macStart := len(message) - MACSize


19 tag := message[macStart:]
20 out := make([]byte, macStart-NonceSize)
21 message = message[:macStart]
22
23 h := hmac.New(sha256.New, key[CKeySize:])
24 h.Write(message)
25 mac := h.Sum(nil)
26 if !hmac.Equal(mac, tag) {
27 return nil, ErrDecrypt
28 }
29
30 // NewCipher only returns an error with an invalid key size,
31 // but the key size was checked at the beginning of the function.
32 c, _ := aes.NewCipher(key[:CKeySize])
33 ctr := cipher.NewCBCDecrypter(c, message[:NonceSize])
34 ctr.CryptBlocks(out, message[NonceSize:])
35
36 pt := unpad(out)
37 if pt == nil {
38 return nil, ErrDecrypt
39 }
40
41 return pt, nil
42 }

第32页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第33页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 type Message struct {


2 Number uint32
3 Contents []byte
4 }

1 func MarshalMessage(m Message) []byte {


2 out := make([]byte, 4, len(m.Contents) + 4)
3 binary.BigEndian.PutUint32(out[:4], m.Number)
4 return append(out, m.Contents...)
5 }

第34页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 func UnmarshalMessage(in []byte) (Message, bool) {


2 m := Message{}
3 if len(in) <= 4 {
4 return m, false
5 }
6
7 m.Number = binary.BigEndian.Uint32(in[:4])
8 m.Contents = in[4:]
9 return m, true
10 }

1 type Channel io.ReadWriter


2
3 type Session struct {
4 lastSent uint32
5 sendKey *[32]byte
6
7 lastRecv uint32
8 recvKey *[32]byte
9
10 Channel Channel
11 }
12
13 func (s *Session) LastSent() uint32 {
14 return s.lastSent
15 }
16
17 func (s *Session) LastRecv() uint32 {
18 return s.lastRecv
19 }

1 func (s *Session) Encrypt(message []byte) ([]byte, error) {


2 if len(message) == 0 {
3 return nil, secret.ErrEncrypt
4 }
5
6 s.lastSent++

第35页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

7 m := MarshalMessage(Message{s.lastSent, message})
8 return secret.Encrypt(s.sendKey, m)
9 }

1 func (s *Session) Decrypt(message []byte) ([]byte, error) {


2 out, err := secret.Decrypt(s.recvKey, message)
3 if err != nil {
4 return nil, err
5 }
6
7 m, ok := UnmarshalMessage(out)
8 if !ok {
9 return nil, secret.ErrDecrypt
10 }
11
12 if m.Number <= s.lastRecv {
13 return nil, secret.ErrDecrypt
14 }
15
16 s.lastRecv = m.Number
17
18 return m.Contents, nil
19 }

第36页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第37页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 // deriveKey generates a new NaCl key from a passphrase and salt.


2 func deriveKey(pass, salt []byte) (*[secret.KeySize]byte, error
3 var naclKey = new([secret.KeySize]byte)
4 key, err := scrypt.Key(pass, salt, 1048576, 8, 1, secret
5 if err != nil {
6 return nil, err
7 }
8
9 copy(naclKey[:], key)
10 util.Zero(key)
11 return naclKey, nil
12 }

1 func Encrypt(pass, message []byte) ([]byte, error) {


2 salt, err := util.RandBytes(SaltSize)
3 if err != nil {
4 return nil, ErrEncrypt
5 }
6
7 key, err := deriveKey(pass, salt)
8 if err != nil {
9 return nil, ErrEncrypt
10 }
11
12 out, err := secret.Encrypt(key, message)
13 util.Zero(key[:]) // Zero key immediately after
14 if err != nil {
15 return nil, ErrEncrypt
16 }
17
18 out = append(salt, out...)
19 return out, nil
20 }

第38页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 const Overhead = SaltSize + secretbox.Overhead + secret.NonceSize


2
3 func Decrypt(pass, message []byte) ([]byte, error) {
4 if len(message) < Overhead {
5 return nil, ErrDecrypt
6 }
7
8 key, err := deriveKey(pass, message[:SaltSize])
9 if err != nil {
10 return nil, ErrDecrypt
11 }
12
13 out, err := secret.Decrypt(key, message[SaltSize:])
14 util.Zero(key[:]) // Zero key immediately after
15 if err != nil {
16 return nil, ErrDecrypt
17 }
18
19 return out, nil
20 }

第39页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第40页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 pub, priv, err := box.GenerateKey(rand.Reader)

1 func NewSession(ch Channel) *Session {


2 return &Session{
3 recvKey: new([32]byte),
4 sendKey: new([32]byte),
5 Channe: ch,
6 }
7 }

1 func keyExchange(shared *[32]byte, priv, pub []byte) {


2 var kexPriv [32]byte
3 copy(kexPriv[:], priv)
4 util.Zero(priv)
5
6 var kexPub [32]byte
7 copy(kexPub[:], pub)
8
9 box.Precompute(shared, &kexPub, &kexPriv)
10 util.Zero(kexPriv[:])
11 }

第41页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 func (s *Session) KeyExchange(priv, peer *[64]byte, dialer bool


2 if dialer {
3 keyExchange(s.sendKey, priv[:32], peer[:32])
4 keyExchange(s.recvKey, priv[32:], peer[32:])
5 } else {
6 keyExchange(s.recvKey, priv[:32], peer[:32])
7 keyExchange(s.sendKey, priv[32:], peer[32:])
8 }
9 s.lastSent = 0
10 s.lastRecv = 0
11 }

1 out := box.Seal(nil, message, nonce, peerPublic, priv)

第42页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)

1 var ErrKeyExchange = errors.New("key exchange failed")


2
3 func ECDH(priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey) ([]byte
4 if prv.PublicKey.Curve != pub.Curve {
5 return nil, ErrKeyExchange
6 } else if !prv.PublicKey.Curve.IsOnCurve(pub.X, pub.Y)
7 return nil, ErrKeyExchange
8 }
9
10 x, _ := pub.Curve.ScalarMult(pub.X, pub.Y, prv.D.Bytes())
11 if x == nil {
12 return nil, ErrKeyExchange
13 }
14
15 shared := sha512.Sum512(x.Bytes())
16 return shared[:secret.KeySize], nil
17 }

第43页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 func ParseECPublicKey(in []byte) (*ecdsa.PublicKey, error) {


2 // UnmarshalPKIXPublicKey returns an interface{}.
3 pub, err := x509.ParsePKIXPublicKey(in)
4 if err != nil {
5 return nil, err
6 }
7
8 ecpub, ok := pub.(*ecdsa.PublicKey)
9 if !ok {
10 return nil, errors.New("invalid EC public key"
11 }
12
13 return ecpub, nil
14 }

第44页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第45页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第46页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第47页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第48页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 pub, priv, err := ed25519.GenerateKey(rand.Reader)n

1 sig, err := ed25519.Sign(priv, message)


2
3 if !ed25519.Verify(pub, message) {
4 // Perform signature verification failure handling.
5 }

第49页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 type ECDSASignature struct {


2 R, S *big.Int
3 }
4
5 func SignMessage(priv *ecdsa.PrivateKey, message []byte) {
6 hashed := sha256.Sum256(message)
7 r, s, err := ecdsa.Sign(rand.Reader, priv, hashed[:])
8 if err != nil {
9 return nil, err
10 }
11
12 return asn1.Marshal(ECDSASignature{r, s})
13 }
14
15 func VerifyMessage(pub *ecdsa.PublicKey, message []byte, signature
16 var rs ECDSASignature
17
18 if _, err := asn.Unmarshal(signature, &rs); err != nil
19 return false
20 }
21
22 hashed := sha256.Sum256(message)
23 return ecdsa.Verify(pub, hashed[:], rs.R, rs.S)
24 }

第50页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

1 var opts = &rsa.PSSOptions{}

1 func SignPKCS1v15(priv *rsa.PrivateKey, message []byte) ([]byte,


2 hashed := sha256.Sum256(message)
3 return rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256
4 }
5
6 func SignPSS(priv *rsa.PrivateKey, message []byte) ([]byte, error
7 hash := sha256.Sum256(message)
8 return rsa.SignPSS(rand.Reader, priv, crypto.SHA256, hashed
9 }

第51页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第52页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第53页 共54页 2016/2/12 18:19


Read Practical Cryptography With Go | Leanpub https://leanpub.com/gocrypto/read

第54页 共54页 2016/2/12 18:19

You might also like