package securityutil import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/sha256" "encoding/base64" "encoding/hex" "fmt" "golang.org/x/crypto/bcrypt" ) func SHA256(data string) string { hash := sha256.New() hash.Write([]byte(data)) return hex.EncodeToString(hash.Sum(nil)) } func HashPassword(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) return string(bytes), err } func CheckPasswordHash(password string, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil } func AES256Encode(plaintext string, key string, iv string, blockSize int) string { bKey := []byte(key) bIV := []byte(iv) bPlaintext := PKCS5Padding([]byte(plaintext), blockSize, len(plaintext)) block, err := aes.NewCipher(bKey) if err != nil { panic(err) } ciphertext := make([]byte, len(bPlaintext)) mode := cipher.NewCBCEncrypter(block, bIV) mode.CryptBlocks(ciphertext, bPlaintext) // return hex.EncodeToString(ciphertext) fmt.Printf("hex.EncodeToString(ciphertext) : %s\n", hex.EncodeToString(ciphertext)) fmt.Printf("base64.StdEncoding.EncodeToString(ciphertext) : %s\n", base64.StdEncoding.EncodeToString(ciphertext)) fmt.Printf("base64.RawStdEncoding.EncodeToString(ciphertext) : %s\n", base64.RawStdEncoding.EncodeToString(ciphertext)) return base64.StdEncoding.EncodeToString(ciphertext) } func AES256Decode(cipherText string, encKey string, iv string) (decryptedString string) { bKey := []byte(encKey) bIV := []byte(iv) // cipherTextDecoded, err := hex.DecodeString(cipherText) cipherTextDecoded, err := base64.StdEncoding.DecodeString(cipherText) if err != nil { panic(err) } block, err := aes.NewCipher(bKey) if err != nil { panic(err) } mode := cipher.NewCBCDecrypter(block, bIV) mode.CryptBlocks([]byte(cipherTextDecoded), []byte(cipherTextDecoded)) return string(cipherTextDecoded) } func PKCS5Padding(ciphertext []byte, blockSize int, after int) []byte { padding := (blockSize - len(ciphertext)%blockSize) padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } // func pkcs7Pad(b []byte, blocksize int) ([]byte, error) { // if blocksize <= 0 { // return nil, ErrInvalidBlockSize // } // if b == nil || len(b) == 0 { // return nil, ErrInvalidPKCS7Data // } // n := blocksize - (len(b) % blocksize) // pb := make([]byte, len(b)+n) // copy(pb, b) // copy(pb[len(b):], bytes.Repeat([]byte{byte(n)}, n)) // return pb, nil // } // // pkcs7Unpad validates and unpads data from the given bytes slice. // // The returned value will be 1 to n bytes smaller depending on the // // amount of padding, where n is the block size. // func pkcs7Unpad(b []byte, blocksize int) ([]byte, error) { // if blocksize <= 0 { // return nil, ErrInvalidBlockSize // } // if b == nil || len(b) == 0 { // return nil, ErrInvalidPKCS7Data // } // if len(b)%blocksize != 0 { // return nil, ErrInvalidPKCS7Padding // } // c := b[len(b)-1] // n := int(c) // if n == 0 || n > len(b) { // return nil, ErrInvalidPKCS7Padding // } // for i := 0; i < n; i++ { // if b[len(b)-n+i] != c { // return nil, ErrInvalidPKCS7Padding // } // } // return b[:len(b)-n], nil // } // // func Encrypt(b cipher.Block, plaintext []byte) []byte { // // if mod := len(plaintext) % aes.BlockSize; mod != 0 { // 블록 크기의 배수가 되어야함 // // padding := make([]byte, aes.BlockSize-mod) // 블록 크기에서 모자라는 부분을 // // plaintext = append(plaintext, padding...) // 채워줌 // // } // // ciphertext := make([]byte, aes.BlockSize+len(plaintext)) // 초기화 벡터 공간(aes.BlockSize)만큼 더 생성 // // // iv := ciphertext[:aes.BlockSize] // 부분 슬라이스로 초기화 벡터 공간을 가져옴 // // // if _, err := io.ReadFull(rand.Reader, iv); err != nil { // 랜덤 값을 초기화 벡터에 넣어줌 // // // fmt.Println(err) // // // return nil // // // } // // iv := []byte("0000000000000000") // // mode := cipher.NewCBCEncrypter(b, iv) // 암호화 블록과 초기화 벡터를 넣어서 암호화 블록 모드 인스턴스 생성 // // mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext) // 암호화 블록 모드 인스턴스로 // // // 암호화 // // return ciphertext // // } // // func Decrypt(b cipher.Block, ciphertext []byte) []byte { // // if len(ciphertext)%aes.BlockSize != 0 { // 블록 크기의 배수가 아니면 리턴 // // fmt.Println("암호화된 데이터의 길이는 블록 크기의 배수가 되어야합니다.") // // return nil // // } // // // iv := ciphertext[:aes.BlockSize] // 부분 슬라이스로 초기화 벡터 공간을 가져옴 // // iv := []byte("0000000000000000") // // ciphertext = ciphertext[aes.BlockSize:] // 부분 슬라이스로 암호화된 데이터를 가져옴 // // plaintext := make([]byte, len(ciphertext)) // 평문 데이터를 저장할 공간 생성 // // mode := cipher.NewCBCDecrypter(b, iv) // 암호화 블록과 초기화 벡터를 넣어서 // // // 복호화 블록 모드 인스턴스 생성 // // mode.CryptBlocks(plaintext, ciphertext) // 복호화 블록 모드 인스턴스로 복호화 // // return plaintext // // }