|
@@ -0,0 +1,86 @@
|
|
|
|
|
+# Go 中的密码学
|
|
|
|
|
+
|
|
|
|
|
+通过网络传输的数据必须加密,以防止被 hacker(黑客)读取或篡改,并且保证发出的数据和收到的数据检验和一致。
|
|
|
|
|
+鉴于 Go 母公司的业务,我们毫不惊讶地看到 Go 的标准库为该领域提供了超过 30 个的包:
|
|
|
|
|
+
|
|
|
|
|
+- `hash` 包:实现了 `adler32`、`crc32`、`crc64` 和 `fnv` 校验;
|
|
|
|
|
+- `crypto` 包:实现了其它的 hash 算法,比如 `md4`、`md5`、`sha1` 等。以及完整地实现了 `aes`、`blowfish`、`rc4`、`rsa`、`xtea` 等加密算法。
|
|
|
|
|
+
|
|
|
|
|
+下面的示例用 `sha1` 和 `md5` 计算并输出了一些校验值。
|
|
|
|
|
+
|
|
|
|
|
+示例 12.20 [hash_sha1.go](examples/chapter_12/hash_sha1.go):
|
|
|
|
|
+
|
|
|
|
|
+```go
|
|
|
|
|
+// hash_sha1.go
|
|
|
|
|
+package main
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "fmt"
|
|
|
|
|
+ "crypto/sha1"
|
|
|
|
|
+ "io"
|
|
|
|
|
+ "log"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+func main() {
|
|
|
|
|
+ hasher := sha1.New()
|
|
|
|
|
+ io.WriteString(hasher, "test")
|
|
|
|
|
+ b := []byte{}
|
|
|
|
|
+ fmt.Printf("Result: %x\n", hasher.Sum(b))
|
|
|
|
|
+ fmt.Printf("Result: %d\n", hasher.Sum(b))
|
|
|
|
|
+ //
|
|
|
|
|
+ hasher.Reset()
|
|
|
|
|
+ data := []byte("We shall overcome!")
|
|
|
|
|
+ n, err := hasher.Write(data)
|
|
|
|
|
+ if n!=len(data) || err!=nil {
|
|
|
|
|
+ log.Printf("Hash write error: %v / %v", n, err)
|
|
|
|
|
+ }
|
|
|
|
|
+ checksum := hasher.Sum(b)
|
|
|
|
|
+ fmt.Printf("Result: %x\n", checksum)
|
|
|
|
|
+}
|
|
|
|
|
+/* Output:
|
|
|
|
|
+Result: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
|
|
|
|
|
+Result: [169 74 143 229 204 177 155 166 28 76 8 115 211 145 233 135 152 47 187 211]
|
|
|
|
|
+Result: e2222bfc59850bbb00a722e764a555603bb59b2a
|
|
|
|
|
+*/
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+通过调用 `sha1.New()` 创建了一个新的 `hash.Hash` 对象,用来计算 SHA1 校验值。`Hash` 类型实际上是一个接口,它实现了 `io.Writer` 接口:
|
|
|
|
|
+
|
|
|
|
|
+```go
|
|
|
|
|
+type Hash interface {
|
|
|
|
|
+ // Write (via the embedded io.Writer interface) adds more data to the running hash.
|
|
|
|
|
+ // It never returns an error.
|
|
|
|
|
+ io.Writer
|
|
|
|
|
+
|
|
|
|
|
+ // Sum appends the current hash to b and returns the resulting slice.
|
|
|
|
|
+ // It does not change the underlying hash state.
|
|
|
|
|
+ Sum(b []byte) []byte
|
|
|
|
|
+
|
|
|
|
|
+ // Reset resets the Hash to its initial state.
|
|
|
|
|
+ Reset()
|
|
|
|
|
+
|
|
|
|
|
+ // Size returns the number of bytes Sum will return.
|
|
|
|
|
+ Size() int
|
|
|
|
|
+
|
|
|
|
|
+ // BlockSize returns the hash's underlying block size.
|
|
|
|
|
+ // The Write method must be able to accept any amount
|
|
|
|
|
+ // of data, but it may operate more efficiently if all writes
|
|
|
|
|
+ // are a multiple of the block size.
|
|
|
|
|
+ BlockSize() int
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+通过 io.WriteString 或 hasher.Write 计算给定字符串的校验值。
|
|
|
|
|
+
|
|
|
|
|
+**练习 12.9**:[hash_md5.go](exercises/chapter_12/hash_md5.go):
|
|
|
|
|
+
|
|
|
|
|
+在示例 12.20 中检验 md5 算法。
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+## 链接
|
|
|
|
|
+
|
|
|
|
|
+- [目录](directory.md)
|
|
|
|
|
+- 上一节:[用 Gob 传输数据](12.11.md)
|
|
|
|
|
+- 下一章:[错误处理与测试](13.0.md)
|