Files
2019-06-22 23:41:28 +08:00

130 lines
4.0 KiB
Markdown
Raw Permalink 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>)