151 lines
5.2 KiB
Go
151 lines
5.2 KiB
Go
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
|
|
// // }
|