Files
build-web-application-with-…/zh-tw/09.6.md
2019-02-26 01:40:54 +08:00

128 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 9.6 加密和解密資料
前面小節介紹瞭如何儲存密碼,但是有的時候,我們想把一些敏感資料加密後儲存起來,在將來的某個時候,隨需將它們解密出來,此時我們應該在選用對稱加密演算法來滿足我們的需求。
## base64加解密
如果Web應用足夠簡單資料的安全性沒有那麼嚴格的要求那麼可以採用一種比較簡單的加解密方法是`base64`這種方式實現起來比較簡單Go語言的`base64`套件已經很好的支援了這個,請看下面的例子:
```Go
package main
import (
"encoding/base64"
"fmt"
)
func base64Encode(src []byte) []byte {
return []byte(base64.StdEncoding.EncodeToString(src))
}
func base64Decode(src []byte) ([]byte, error) {
return base64.StdEncoding.DecodeString(string(src))
}
func main() {
// encode
hello := "你好,世界! hello world"
debyte := base64Encode([]byte(hello))
fmt.Println(debyte)
// decode
enbyte, err := base64Decode(debyte)
if err != nil {
fmt.Println(err.Error())
}
if hello != string(enbyte) {
fmt.Println("hello is not equal to enbyte")
}
fmt.Println(string(enbyte))
}
```
## 高階加解密
Go語言的`crypto`裡面支援對稱加密的高階加解密套件有:
- `crypto/aes`套件AES(Advanced Encryption Standard)又稱Rijndael加密法是美國聯邦政府採用的一種區塊加密標準。
- `crypto/des`套件DES(Data Encryption Standard)是一種對稱加密標準是目前使用最廣泛的金鑰系統特別是在保護金融資料的安全中。曾是美國聯邦政府的加密標準但現已被AES所替代。
因為這兩種演算法使用方法類似所以在此我們僅用aes套件為例來講解它們的使用請看下面的例子
```Go
package main
import (
"crypto/aes"
"crypto/cipher"
"fmt"
"os"
)
var commonIV = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}
func main() {
//需要去加密的字串
plaintext := []byte("My name is Astaxie")
//如果傳入加密串的話plaint就是傳入的字串
if len(os.Args) > 1 {
plaintext = []byte(os.Args[1])
}
//aes的加密字串
key_text := "astaxie12798akljzmknm.ahkjkljl;k"
if len(os.Args) > 2 {
key_text = os.Args[2]
}
fmt.Println(len(key_text))
// 建立加密演算法aes
c, err := aes.NewCipher([]byte(key_text))
if err != nil {
fmt.Printf("Error: NewCipher(%d bytes) = %s", len(key_text), err)
os.Exit(-1)
}
//加密字串
cfb := cipher.NewCFBEncrypter(c, commonIV)
ciphertext := make([]byte, len(plaintext))
cfb.XORKeyStream(ciphertext, plaintext)
fmt.Printf("%s=>%x\n", plaintext, ciphertext)
// 解密字串
cfbdec := cipher.NewCFBDecrypter(c, commonIV)
plaintextCopy := make([]byte, len(plaintext))
cfbdec.XORKeyStream(plaintextCopy, ciphertext)
fmt.Printf("%x=>%s\n", ciphertext, plaintextCopy)
}
```
上面透過呼叫函式`aes.NewCipher`(引數key必須是16、24或者32位的[]byte分別對應AES-128, AES-192或AES-256演算法),返回了一個`cipher.Block`介面,這個介面實現了三個功能:
```Go
type Block interface {
// BlockSize returns the cipher's block size.
BlockSize() int
// Encrypt encrypts the first block in src into dst.
// Dst and src may point at the same memory.
Encrypt(dst, src []byte)
// Decrypt decrypts the first block in src into dst.
// Dst and src may point at the same memory.
Decrypt(dst, src []byte)
}
```
這三個函式實現了加解密操作,詳細的操作請看上面的例子。
## 總結
這小節介紹了幾種加解密的演算法在開發Web應用的時候可以根據需求採用不同的方式進行加解密一般的應用可以採用base64演算法更加進階的話可以採用aes或者des演算法。
## links
* [目錄](<preface.md>)
* 上一節: [儲存密碼](<09.5.md>)
* 下一節: [小結](<09.7.md>)