2015-10-22

beego Tutorial 10 : 개인정보 양방향암호화(AES256) 하기



  • 이 예제에는 개인정보 데이터가 없긴 하지만, 별명(Nick)을 개인정보라 간주하고 암호화를 진행해보겠습니다.
  • 데이터를 암호화하고 다시 풀려면, Key 가 있어야 합니다. 이 Key 를 xyz/conf/app.conf 에 기록해 놓습니다.
    ...
    
    enckey = oei0oiejhdsa7AS6dkjSk3l5dkwHG659
    
    ...
  • xyz/models/common.go 를 수정합니다.
    package models
     
    import (
        "crypto/aes"
        "crypto/cipher"
        "crypto/rand"
        "encoding/base64"
        "fmt"
        "github.com/astaxie/beego"
        "github.com/astaxie/beego/orm"
        "io"
    )
     
    var key []byte
     
    func init() {
        key = []byte(beego.AppConfig.String("enckey"))
        orm.RegisterModelWithPrefix("tb_", new(Admin))
    }
     
    func encodeBase64(b []byte) []byte {
        return []byte(base64.StdEncoding.EncodeToString(b))
    }
     
    func decodeBase64(b []byte) []byte {
        data, err := base64.StdEncoding.DecodeString(string(b))
        if err != nil {
            fmt.Printf("Error: Bad Key!\n")
            return nil
        }
        return data
    }
     
    func encrypt(text []byte) []byte {
        // The key argument should be the AES key,
        // either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.
        block, err := aes.NewCipher(key)
        if err != nil {
            panic(err)
        }
        b := encodeBase64(text)
        ciphertext := make([]byte, aes.BlockSize+len(b))
        iv := ciphertext[:aes.BlockSize]
        if _, err := io.ReadFull(rand.Reader, iv); err != nil {
            panic(err)
        }
        cfb := cipher.NewCFBEncrypter(block, iv)
        cfb.XORKeyStream(ciphertext[aes.BlockSize:], b)
        return ciphertext
    }
     
    func decrypt(text []byte) []byte {
        block, err := aes.NewCipher(key)
        if err != nil {
            panic(err)
        }
        if len(text) < aes.BlockSize {
            fmt.Printf("Error!\n")
            return nil
        }
        iv := text[:aes.BlockSize]
        text = text[aes.BlockSize:]
        cfb := cipher.NewCFBDecrypter(block, iv)
        cfb.XORKeyStream(text, text)
        return decodeBase64(text)
    }
  • xyz/models/admin.go 에 다음을 추가한다.
    func (this *Admin) SetNick(nick string) {
        ciphertext := encrypt([]byte(nick))
        this.Nick = hex.EncodeToString(ciphertext)
    }
     
    func (this *Admin) GetNick() string {
        ciphertext, _ := hex.DecodeString(this.Nick)
        plaintext := decrypt(ciphertext)
        return string(plaintext)
    }
    Insert()Update() 에서 this.Nick = nick 이라고 되어 있는 부분을 this.SetNick(nick) 으로 변경한다.
  • xyz/views/admin 밑에 있는 index.html 과 update_form.html 파일에서 Nick 이라고 되어 있는 부분을 모두 GetNick 으로 변경한다.
  • DB의 내용을 모두 삭제한 후에, 관리자를 추가해봅니다. 그리고, DB에서 Nick 이 암호화되어 있는지도 봅시다.
    $ sqlite3 xyz.db
    SQLite version 3.7.9 2011-11-01 00:52:41
    Enter ".help" for instructions
    Enter SQL statements terminated with a ";"
    sqlite> select nick from tb_admin;
    2e4cccdfe968a2b127bff7eac978df2354c0bb7c25e8534d
    sqlite> .quit
    제대로 암호화되어서 무슨 내용인지 알아볼 수 없네요. ^^;


댓글 없음:

댓글 쓰기