Skip to content

Instantly share code, notes, and snippets.

@cheerfyt
Last active July 5, 2022 02:44
Show Gist options
  • Save cheerfyt/1b65240ba290e81d3a6b8ecbc6d99085 to your computer and use it in GitHub Desktop.
Save cheerfyt/1b65240ba290e81d3a6b8ecbc6d99085 to your computer and use it in GitHub Desktop.
golang embed spa static
// how to handle spa static like react, vue, svelte
func (h *Handler) handleStatic() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		normalPath := r.URL.Path
		if !strings.HasPrefix(normalPath, "/") {
			normalPath = "/" + normalPath
		}
		normalPath = path.Clean(normalPath)
		fSys := fs.FS(h.webFS)
		contentStatic, _ := fs.Sub(fSys, "web/dist")
		if _, err := contentStatic.Open(strings.TrimLeft(normalPath, "/")); err != nil {
			r.URL.Path = "/"
		}
		http.FileServer(http.FS(contentStatic)).ServeHTTP(w, r)
	}
}
// rsa aes 加解密
func DecryptCipherKey(data string) (string, error) {
	key, err := base64url.Decode(data)
	if err != nil {
		return "", err
	}
	pri, _ := parsePrivatekey()
	if err != nil {
		return "", err
	}
	plaintext, err := rsa.DecryptOAEP(sha1.New(), rand.Reader, pri, key, nil)
	fmt.Println(len(plaintext))
	bytes2string(plaintext)
	return string(plaintext), err
}

// bytes to *rsa.PrivateKey
func parsePrivatekey() (*rsa.PrivateKey, error) {
	block, _ := pem.Decode([]byte(core.RSA_SECRET_PRIVATE_KEY))
  // check is encrypted block before
	// if x509.IsEncryptedPEMBlock(block) {
	// clearText, err := x509.DecryptPEMBlock(block, []byte(core.RSA_SECRET_PASSWORD))
	// }
	clearText, err := x509.DecryptPEMBlock(block, []byte(core.RSA_SECRET_PASSWORD))
	if err != nil {
		fmt.Println("error -> ", err)
		return nil, err
	}
	return x509.ParsePKCS1PrivateKey(clearText)
}

// ============================================================================
// aes 加解密
// ============================================================================
package util

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"encoding/hex"
	"errors"

	"huobi.com/blockchain/gohb/backend/core"
)

var Aes = new(aesTool)

type aesTool struct{}

func (a *aesTool) EncryptWalletTask(task string) string {
	return a.EncryptAES256CBC(task, core.A32, core.B16)
}

func (a *aesTool) DecryptWalletTask(encryptedText string) ([]byte, error) {
	return a.decryptAES256CBC(encryptedText, core.A32, core.B16)
}

func (a *aesTool) EncryptPrivateKeyByPassword(private, password string) (string, error) {
	key := a.Get32ByteKey(password)
	val, err := a.EncryptAES256ECB([]byte(private), key)
	if err != nil {
		return "", err
	}
	return base64.StdEncoding.EncodeToString(val), nil
}

func (a *aesTool) DecryptPrivateKeyByPassword(private, password string) (string, error) {
	key := a.Get32ByteKey(password)
	data := []byte(private)
	cipher, e := aes.NewCipher(key)
	if e != nil {
		return "", e
	}
	decrypted := make([]byte, len(data))
	size := 16
	for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
		cipher.Decrypt(decrypted[bs:be], data[bs:be])
	}
	return hex.EncodeToString(decrypted), nil

}

func (a *aesTool) EncryptAES256CBC(plaintext string, key, iv string) string {
	return a.encryptAES256CBC(plaintext, key, iv)
}

func (a *aesTool) encryptAES256CBC(plaintext, key, iv string) string {
	bKey := []byte(key)
	bIV := []byte(iv)
	bPlaintext := a.pkcs5Padding([]byte(plaintext), aes.BlockSize)
	block, _ := aes.NewCipher(bKey)
	ciphertext := make([]byte, len(bPlaintext))
	mode := cipher.NewCBCEncrypter(block, bIV)
	mode.CryptBlocks(ciphertext, bPlaintext)
	return base64.StdEncoding.EncodeToString(ciphertext)
}

func (a *aesTool) decryptAES256CBC(encryptedText, key, iv string) ([]byte, error) {
	rawText, err := base64.StdEncoding.DecodeString(encryptedText)
	if err != nil {
		return nil, err
	}
	block, err := aes.NewCipher([]byte(key))
	if err != nil {
		return nil, err
	}
	if len(rawText)%aes.BlockSize != 0 {
		return nil, errors.New("encrypt length error")
	}
	mode := cipher.NewCBCDecrypter(block, []byte(iv))
	mode.CryptBlocks(rawText, rawText)
	rawText = a.pkcs5Unpadding(rawText)
	return rawText, nil
}

func (a *aesTool) EncryptAES256ECB(data, key []byte) ([]byte, error) {
	return a.encryptAES256ECB(data, key)
}

func (a *aesTool) encryptAES256ECB(data, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	bs := block.BlockSize()
	data = a.pkcs5Padding(data, bs)
	if len(data)%bs != 0 {
		return nil, errors.New("need a multiple of the blocksize")
	}

	out := make([]byte, len(data))
	dst := out
	for len(data) > 0 {
		//Encrypt encrypts the first block and saves the result to dst
		block.Encrypt(dst, data[:bs])
		data = data[bs:]
		dst = dst[bs:]
	}
	return out, nil
}

func (a *aesTool) pkcs5Padding(ciphertext []byte, blockSize int) []byte {
	padding := (blockSize - len(ciphertext)%blockSize)
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	ciphertext = append(ciphertext, padtext...)
	return ciphertext
}

func (a *aesTool) pkcs5Unpadding(data []byte) []byte {
	if len(data) == 0 {
		return data
	}
	padding := data[len(data)-1]
	return data[:len(data)-int(padding)]
}

func (a *aesTool) Get32ByteKey(key string) []byte {
	b := []byte(key)
	if len(b) < 32 {
		bLen := 32 - len(b)
		zeroByte := bytes.Repeat([]byte{byte(0x0)}, bLen)
		b = append(b, zeroByte...)
	}
	return b[0:32]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment