保护数据库信息,如何用Go语言+对称密钥做数据加密?
func createData(id, name, nationalID, createTimeUnix string) (err error) {
_, err = DB.Exec(`
INSERT INTO
user (id, name, national_id, create_time_unix)
VALUES
("?", "?", "?", "?")
`, id, name, nationalID, createTimeUnix)
return
}
type User struct {
ID string
Name string
NationalID string
CreateTimeUnix string
}
func readData(id string) (user User, err error) {
row := DB.QueryRow(`
SELECT
id, name, national_id, create_time_unix
FROM
user
WHERE
id = "?"`, id)
err = row.Scan(
&user.ID,
&user.Name,
&user.NationalID,
&user.CreateTimeUnix)
return
}
func encrypt(plaintext, passphrase string) (chipertext string, err error) {
block, _ := aes.NewCipher([]byte(passphrase))
gcm, err := cipher.NewGCM(block)
if err != nil {
return
}
nonce := make([]byte, gcm.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
return
}
ciphertextByte := gcm.Seal(
nonce,
nonce,
[]byte(plaintext),
nil)
chipertext = base64.StdEncoding.EncodeToString(ciphertextByte)
return
}
func decrypt(cipherText, key string) (plainText string, err error) {
// prepare cipher
keyByte := []byte(key)
block, err := aes.NewCipher(keyByte)
if err != nil {
return
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return
}
nonceSize := gcm.NonceSize()
//
// process ciphertext
ciphertextByte, _ := base64.StdEncoding.DecodeString(cipherText)
nonce, ciphertextByteClean := ciphertextByte[:nonceSize], ciphertextByte[nonceSize:]
plaintextByte, err := gcm.Open(
nil,
nonce,
ciphertextByteClean,
nil)
if err != nil {
log.Println(err)
return
}
plainText = string(plaintextByte)
//
return
}
func Test_encrypt(t *testing.T) {
type args struct {
plaintext string
key string
}
tests := []struct {
name string
args args
}{
{
name: "happy test",
args: args{
plaintext: "kingsman",
key: "04076d64bdb6fcf31706eea85ec98431"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// encrypt the plaintext
ciphertext, err := encrypt(tt.args.plaintext, tt.args.key)
if err != nil {
t.Errorf("encrypt() error = %v", err)
return
}
t.Logf("ciphertext = %s", ciphertext)
//
// decrypt the ciphertext from previous encrypt function
plaintext, err := decrypt(ciphertext, tt.args.key)
if err != nil {
t.Errorf("encrypt() error = %v", err)
return
}
t.Logf("plaintext = %s", plaintext)
//
// compare the initial plaintext with output of previous decrypt function
if plaintext != tt.args.plaintext {
t.Errorf("plaintext = %v, want %v", plaintext, tt.args.plaintext)
}
//
})
}
}
db-encryption go test -v -timeout 30s
=== RUN Test_encrypt
=== RUN Test_encrypt/happy_test
--- PASS: Test_encrypt (0.00s)
--- PASS: Test_encrypt/happy_test (0.00s)
main_test.go:78: ciphertext = sLR9ctALjY0rtAi8IvosScCtBE21gyMOBl3xHzi52Hbo+H3O
main_test.go:87: plaintext = kingsman
PASS
ok github.com/purnaresa/secureme/db-encryption 0.005s
func createData(id, name, nationalID, createTimeUnix string) (err error) {
// encryption
nationalID, _ = encrypt(nationalID, masterKey)
//
_, err = DB.Exec(`
INSERT INTO
user (id, name, national_id, create_time_unix)
VALUES
("?", "?", "?", "?")
`, id, name, nationalID, createTimeUnix)
return
}
func readData(id string) (user User, err error) {
row := DB.QueryRow(`
SELECT
id, name, national_id, create_time_unix
FROM
user
WHERE
id = "?"`, id)
err = row.Scan(
&user.ID,
&user.Name,
&user.NationalID,
&user.CreateTimeUnix)
// decryption
user.NationalID, _ = decrypt(user.NationalID, masterKey)
//
return
}
完整代码:
https://github.com/purnaresa/secureme/blob/master/db-encryption/main.go
原文链接:
https://medium.com/swlh/securing-information-in-database-using-data-encryption-written-in-go-4b2754214050
【END】
推荐阅读