常见加解密算法golang版本

MD5

    /**
     * MD5
     * @param str string 需要加密的字符串
     * @param to_upper bool 返回类型 true大写 false小写
     */
    func Md5String(str string, to_upper bool) string {
        if to_upper {
            return fmt.Sprintf("%X", md5.Sum([]byte(str)))
        } else {
            return fmt.Sprintf("%x", md5.Sum([]byte(str)))
        }
    }

RSA

常量/公共方法定义

    //加解密分段
    const ENCRYPT_KEYSIZE, DECRYPT_KEYSIZE = 117, 128 //1024

    //截取byte
    func SubString(array []byte, begin int, length int) []byte {
        lth := len(array)
        // 简单的越界判断
        if begin < 0 {
            begin = 0
        }
        if begin >= lth {
            begin = lth
        }
        end := begin + length
        if end > lth {
            end = lth
        }

        // 返回子串
        return array[begin:end]
    }

    //多个[]byte数组合并成一个[]byte
    func BytesCombine(pBytes ...[]byte) []byte {
        return bytes.Join(pBytes, []byte(""))
    }

解析公私钥

    /**
     * 获取公钥
     * @param file_path string 公钥路径 ex: ./conf/keys/public_key.pem
     */
    func GetPublicKey(file_path string) (*rsa.PublicKey, error){
        var public_key *rsa.PublicKey
        pubData, err := ioutil.ReadFile(file_path)
        //解析证书
        block, _ := pem.Decode([]byte(pubData))
        cert, err := x509.ParsePKIXPublicKey(block.Bytes)
        if err != nil {
            fmt.Println(err.Error())
            return public_key, err
        }
        public_key = cert.(*rsa.PublicKey)
        return public_key, nil
    }

    /**
     * 获取私钥
     * @param file_path string 私钥路径 ex: ./conf/keys/private_key.pem
     */
    func GetPrivateKey(file_path string) (*rsa.PrivateKey, error) {
        pfxData, err := ioutil.ReadFile(file_path)
        if err != nil {
            return nil, err
        }
        //解析证书
        block, _ := pem.Decode(pfxData)
        privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
        if err != nil {
            fmt.Println("解析证书错误" + err.Error())
            return nil, err
        }
        return privateKey, nil
    }

公钥加

    /**
     * 公钥加密
     */
    func PublicEncrypt(pub *rsa.PublicKey, data []byte) ([]byte, error) {
        signData, err := rsa.EncryptPKCS1v15(rand.Reader, pub, data)
        if err != nil {
            return nil, err
        }
        return base64.StdEncoding.EncodeToString(signData), nil
    }

公钥分段加

    /**
     * 公钥分段加密
     */
    func PublicPartEncrypt(pub *rsa.PublicKey, data []byte) ([]byte, error) {
        length := len(data)
        i := 0
        var final_data []byte
        for i < length {
            signData, err := rsa.EncryptPKCS1v15(rand.Reader, pub, SubString(data, i, ENCRYPT_KEYSIZE))
            if err != nil {
                return nil, err
            }
            final_data = BytesCombine(final_data, signData)
            i += ENCRYPT_KEYSIZE
        }
        return base64.StdEncoding.EncodeToString(final_data), nil
    }

公钥验签

    /**
     * 公钥验签
     */
    func PublicVerifySign(pub *rsa.PublicKey, src []byte, sign []byte) (error){
        h := sha1.New()
        h.Write(src)
        hashed := h.Sum(nil)
        return rsa.VerifyPKCS1v15(pub, crypto.SHA1, hashed, sign)
    }

公钥解密

    func publicDecrypt(pub *rsa.PublicKey, data []byte) (out []byte, err error) {
        hashLen, prefix, err := pkcs1v15HashInfo(crypto.Hash(0), 0)
        if err != nil {
            return nil, err
        }

        tLen := len(prefix) + hashLen
        k := (pub.N.BitLen() + 7) / 8
        if k < tLen + 11 {
            return nil, fmt.Errorf("length illegal")
        }
        c := new(big.Int).SetBytes(data)
        m := encrypt(new(big.Int), pub, c)
        em := leftPad(m.Bytes(), k)

        out = unLeftPad(em)
        err = nil
        return
    }

    // copy from crypt/rsa/pkcs1v5.go
    func leftPad(input []byte, size int) (out []byte) {
        n := len(input)
        if n > size {
            n = size
        }
        out = make([]byte, size)
        copy(out[len(out) - n:], input)
        return
    }

    // copy from crypt/rsa/pkcs1v5.go
    func unLeftPad(input []byte) (out []byte) {
        n := len(input)
        t := 2
        for i := 2; i < n; i++ {
            if input[i] == 0xff {
                t = t + 1
                if input[i + 1] == 0 {
                    t += 1
                }
            } else {
                break
            }
        }
        out = make([]byte, n - t)
        copy(out, input[t:])
        return
    }

    // copy from crypt/rsa/pkcs1v5.go
    func encrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
        e := big.NewInt(int64(pub.E))
        c.Exp(m, e, pub.N)
        return c
    }

私钥加密

    /**
     * 私钥加密
     */
    func PrivateEncrypt(privt *rsa.PrivateKey, data []byte) ([]byte, error) {
        signData, err := rsa.SignPKCS1v15(nil, privt, crypto.Hash(0), data)
        if err != nil {
            return nil, err
        }
        return signData, nil
    }

私钥分段加密

    /**
     * 公钥分段加密
     */
    func PublicPartEncrypt(pub *rsa.PublicKey, data []byte) ([]byte, error) {
        length := len(data)
        i := 0
        var final_data []byte
        for i < length {
            signData, err := rsa.SignPKCS1v15(nil, privt, crypto.Hash(0), SubString(data, i, ENCRYPT_KEYSIZE))
            if err != nil {
                return nil, err
            }
            final_data = BytesCombine(final_data, signData)
            i += ENCRYPT_KEYSIZE
        }
        return base64.StdEncoding.EncodeToString(final_data), nil
    }

私钥加签

    /**
     * 私钥加签(SHA1withRSA)
     */
    func PrivateSign(privt *rsa.PrivateKey, data []byte) ([]byte, error) {
        h := sha1.New()
        h.Write(data)
        hashed := h.Sum(nil)
        signData, err := rsa.SignPKCS1v15(rand.Reader, privt, crypto.SHA1, hashed)
        if err != nil {
            return nil, err
        }
        return signData, nil
    }

    /**
     * 私钥加签(MD5withRSA)
     */
    func PrivateEncryptMD5withRSA(privt *rsa.PrivateKey, data []byte) ([]byte, error) {
        h := md5.New()
        h.Write(data)
        hashed := h.Sum(nil)
        signData, err := rsa.SignPKCS1v15(nil, privt, crypto.MD5, hashed)
        if err != nil {
            return nil, err
        }
        return signData, nil
    }

私钥解密

    /**
     * 私钥解密
     */
    func PrivateDecrypt(privt *rsa.PrivateKey, data []byte) ([]byte, error) {
        length := len(data)
        i := 0
        var final_data []byte
        for i < length {
            signData, err := rsa.DecryptPKCS1v15(rand.Reader, privt, SubString(data, i, DECRYPT_KEYSIZE))
            if err != nil {
                return nil, err
            }
            final_data = BytesCombine(final_data, signData)
            i += DECRYPT_KEYSIZE
        }
        return final_data, nil
    }

AES

公共方法

    //PKCS7填充,
    func (a *Aes) PKCS7Padding(ciphertext []byte, blockSize int) []byte {
        padding := blockSize - len(ciphertext) % blockSize
        padtext := bytes.Repeat([]byte{byte(padding)}, padding)
        return append(ciphertext, padtext...)
    }

    //PKCS7反填充,
    func (a *Aes) PKCS7UnPadding(origData []byte) []byte {
        length := len(origData)
        unpadding := int(origData[length-1])
        return origData[:(length - unpadding)]
    }

    //PKCS5填充,
    func (a *Aes) PKCS5Padding(ciphertext []byte, blockSize int) []byte {
        padding := blockSize - len(ciphertext)%blockSize
        padtext := bytes.Repeat([]byte{byte(padding)}, padding)
        return append(ciphertext, padtext...)
    }


    //PKCS5反填充,
    func (a *Aes) PKCS5UnPadding(ciphertext []byte) []byte {
        length := len(ciphertext)
        // 去掉最后一个字节 unpadding 次
        unpadding := int(ciphertext[length-1])
        return ciphertext[:(length - unpadding)]
    }

    //0填充
    func (a *Aes) ZeroPadding(ciphertext []byte, blockSize int) []byte {
        padding := blockSize - len(ciphertext)%blockSize
        padtext := bytes.Repeat([]byte{0}, padding)//用0去填充
        return append(ciphertext, padtext...)
    }

    //反0填充
    func (a *Aes) ZeroUnPadding(origData []byte) []byte {
        return bytes.TrimFunc(origData,
            func(r rune) bool {
                return r == rune(0)
            })
    }

AES/CBC 加解密

  • 加密
    /**
     * AesCBC加密
     * @param str []byte 加密的字符串
     * @param key []byte 密钥
     * @param iv []byte 偏移量
     * @param padding string 填充方式 默认pkcs5填充 如:zero领填充 pkcs7填充 
     */
    func AesCbcEncode(str, key, iv []byte, padding string) (string, error) {
        block, err := aes.NewCipher(key)
        if err != nil {
            return "", err
        }
        blockSize := block.BlockSize()
        if padding == "zero" {
            str = ZeroPadding(str, blockSize)
        } else if padding == "pkcs7" {
            str = PKCS7Padding(str, blockSize)
        } else {
            str = PKCS5Padding(str, blockSize)
        }
        var blockMode cipher.BlockMode
        blockMode = cipher.NewCBCEncrypter(block, iv)
        crypted := make([]byte, len(str))
        blockMode.CryptBlocks(crypted, str)
        return base64.StdEncoding.EncodeToString(crypted), nil
    }
  • 解密
    /**
     * AesCBC解密
     * @param str []byte 解密的字符串
     * @param key []byte 密钥
     * @param iv []byte 偏移量
     * @param padding string 填充方式 默认pkcs5填充 如:zero领填充 pkcs7填充
     */
    func AesCbcDecode(str, key, iv []byte, padding string) (string, error) {
        block, err := aes.NewCipher(key)
        if err != nil {
            return "", err
        }
        var (
            blockMode cipher.BlockMode
        )

        blockMode = cipher.NewCBCDecrypter(block, iv)
        origData := make([]byte, len(str))
        blockMode.CryptBlocks(origData, str)
        if padding == "zero" {
            origData = ZeroUnPadding(origData)
        } else if padding == "pkcs7" {
            origData = PKCS7UnPadding(origData)
        } else {
            origData = PKCS5UnPadding(origData)
        }
        return string(origData), nil
    }

AES/ECB 加解密

  • ECB包源码
    package lib
    import "crypto/cipher"
    type ecb struct {
        b         cipher.Block
        blockSize int
    }
    func newECB(b cipher.Block) *ecb {
        return &ecb{
            b:         b,
            blockSize: b.BlockSize(),
        }
    }
    type ecbEncrypter ecb

    // NewECBEncrypter returns a BlockMode which encrypts in electronic code book
    // mode, using the given Block.
    func NewECBEncrypter(b cipher.Block) cipher.BlockMode {
        return (*ecbEncrypter)(newECB(b))
    }
    func (x *ecbEncrypter) BlockSize() int { return x.blockSize }
    func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
        if len(src)%x.blockSize != 0 {
            panic("crypto/cipher: input not full blocks")
        }
        if len(dst) < len(src) {
            panic("crypto/cipher: output smaller than input")
        }
        for len(src) > 0 {
            x.b.Encrypt(dst, src[:x.blockSize])
            src = src[x.blockSize:]
            dst = dst[x.blockSize:]
        }
    }
    type ecbDecrypter ecb
    // NewECBDecrypter returns a BlockMode which decrypts in electronic code book
    // mode, using the given Block.
    func NewECBDecrypter(b cipher.Block) cipher.BlockMode {
        return (*ecbDecrypter)(newECB(b))
    }
    func (x *ecbDecrypter) BlockSize() int { return x.blockSize }
    func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
        if len(src)%x.blockSize != 0 {
            panic("crypto/cipher: input not full blocks")
        }
        if len(dst) < len(src) {
            panic("crypto/cipher: output smaller than input")
        }
        for len(src) > 0 {
            x.b.Decrypt(dst, src[:x.blockSize])
            src = src[x.blockSize:]
            dst = dst[x.blockSize:]
        }
    }

  • ECB加密
    /**
     * aesecb 加密
     * @param origData []byte 加密的内容
     * @param key []byte 密钥
     * @param padding string 填充 (空pkcs5填充 可选 ZeroPadding)
     */
    func (a *Aes) AesECBEncrypt(origData, key []byte, padding string, mode string) ([]byte, error) {
        block, err := aes.NewCipher(key)
        if err != nil {
            return nil, err
        }
        blockSize := block.BlockSize()
        if padding == "zero" {
            origData = ZeroPadding(origData, blockSize)
        } else if padding == "pkcs7" {
            origData = PKCS7Padding(origData, blockSize)
        } else {
            origData = PKCS5Padding(origData, blockSize)
        }
        var blockMode cipher.BlockMode
        blockMode = NewECBEncrypter(block)
        crypted := make([]byte, len(origData))
        blockMode.CryptBlocks(crypted, origData)
        return crypted, nil
    }
  • ECB解密
    func (a *Aes) AesECBDecrypt(crypted, key []byte, padding string, mode string) ([]byte, error) {
        block, err := aes.NewCipher(key)
        if err != nil {
            return nil, err
        }
        blockSize := block.BlockSize()
        var blockMode cipher.BlockMode
        blockMode = NewECBDecrypter(block)
        origData := make([]byte, len(crypted))
        blockMode.CryptBlocks(origData, crypted)
        if padding == "zero" {
            origData = ZeroUnPadding(origData)
        } else if padding == "pkcs7" {
            origData = PKCS7UnPadding(origData, blockSize)
        } else {
            origData = PKCS5UnPadding(origData)
        }
        return origData, nil
    }

DES

3DES demo

    package main

    import (
        "bytes"
        "crypto/cipher"
        "crypto/des"
        "encoding/base64"
        "encoding/hex"
        "fmt"
        "strings"
    )

    const (
        KEY = "FRNX"
        IV  = "23456789"
    )

    func main() {
        miwen := "7379533330307A63724F554661783369495A653253393533775377426948704A"
        str := decode(miwen)
        str
        fmt.Println(str)
    }

    func genKey(key string) string {
        if len(key) < 32 {
            key += strings.Repeat("0", 32)
        }
        return key[:32]
    }

    func decode(miwen string) string {
        s, _ := hex.DecodeString(miwen)
        x, _ := base64.StdEncoding.DecodeString(string(s))
        k, _ := base64.StdEncoding.DecodeString(genKey(KEY))
        str, _ := tripleDesDecrypt(x, k)
        return string(str)
    }

    // 3DES解密
    func tripleDesDecrypt(crypted, key []byte) ([]byte, error) {
        block, err := des.NewTripleDESCipher(key)
        if err != nil {
            fmt.Println(err.Error())
            return nil, err
        }
        blockMode := cipher.NewCBCDecrypter(block, []byte(IV))
        origData := make([]byte, len(crypted))
        // origData := crypted
        blockMode.CryptBlocks(origData, crypted)
        origData = PKCS5UnPadding(origData)
        // origData = ZeroUnPadding(origData)
        return origData, nil
    }

    // 3DES加密
    func TripleDesEncrypt(origData, key []byte) ([]byte, error) {
        block, err := des.NewTripleDESCipher(key)
        if err != nil {
            return nil, err
        }
        origData = PKCS5Padding(origData, block.BlockSize())
        // origData = ZeroPadding(origData, block.BlockSize())
        blockMode := cipher.NewCBCEncrypter(block, []byte(IV))
        crypted := make([]byte, len(origData))
        blockMode.CryptBlocks(crypted, origData)
        return crypted, nil
    }

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

    func PKCS5UnPadding(origData []byte) []byte {
        length := len(origData)
        // 去掉最后一个字节 unpadding 次
        unpadding := int(origData[length-1])
        return origData[:(length - unpadding)]
    }

其他

随机生成字符串

    /**
     * 生成随机字符串
     * @param length int 生成随机字符串的长度
     */
    func RandomString(length int) string {
        str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        bytes := []byte(str)
        result := []byte{}
        r := rand.New(rand.NewSource(time.Now().UnixNano()))
        for i := 0; i < length; i++ {
            result = append(result, bytes[r.Intn(len(bytes))])
        }
        return string(result)
    }

生成字符串掩码

    /**
     * 字符串掩码处理
     * @param str string 需要处理的字符串
     * @param code string 掩码符号如 (*)
     * @param start int 开始处理位置 (负数表示从尾部开始)
     * @param length int 掩饰长度
     * @return string 处理过后的字符串
     *
     * 示例  str = 18888888888  code = *  start = -4 length = 4  返回  1888888****
     */
    func HideStr(str, code string, start, length int) string {
        l := len(str)
        if start < 0 {
            start = -start
            start = l - start
        }
        var end string
        if length < l-start {
            end = str[start+length : l]
        }
        if l-start < length {
            length = l - start
        }
        hide := strings.Repeat(code, length)
        return str[:start] + hide + end
    }

可逆加密算法demo

    package lib

    import (
        "crypto/md5"
        "fmt"
        "time"
        "encoding/base64"
    )

    type Tool struct {}

    var cipher = "0ca8083685e78d899db664cdb18291d9"
    var h = md5.New()

    func cipherEncode(sourceText string) string {
        h.Write([]byte(cipher))
        cipherHash := fmt.Sprintf("%x", h.Sum(nil))
        h.Reset()
        inputData := []byte(sourceText)
        loopCount := len(inputData)
        outData := make([]byte, loopCount)
        for i := 0; i < loopCount; i++ {
            outData[i] = inputData[i] ^ cipherHash[i%32]
        }
        return fmt.Sprintf("%s", outData)
    }

    func (t *Tool) Encode(sourceText string) string {
        h.Write([]byte(time.Now().Format("2006-01-02 15:04:05")))
        noise := fmt.Sprintf("%x", h.Sum(nil))
        h.Reset()
        inputData := []byte(sourceText)
        loopCount := len(inputData)
        outData := make([]byte, loopCount*2)

        for i, j := 0, 0; i < loopCount; i, j = i+1, j+1 {
            outData[j] = noise[i%32]
            j++
            outData[j] = inputData[i] ^ noise[i%32]
        }
        return base64.StdEncoding.EncodeToString([]byte(cipherEncode(fmt.Sprintf("%s", outData))))
    }

    func (t *Tool) Decode(sourceText string) string {
        buf, err := base64.StdEncoding.DecodeString(sourceText)
        if err != nil {
            fmt.Println("Decode(%q) failed: %v", sourceText, err)
            return ""
        }
        inputData := []byte(cipherEncode(fmt.Sprintf("%s", buf)))
        loopCount := len(inputData)
        outData := make([]byte, loopCount)
        for i, j := 0, 0; i < loopCount; i, j = i+2, j+1 {
            outData[j] = inputData[i] ^ inputData[i+1]
        }
        return fmt.Sprintf("%s", outData)
    }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值