From be8a2f84bd231ffbbbaa08ba225c900d519a0a98 Mon Sep 17 00:00:00 2001 From: Yun Date: Wed, 27 Dec 2023 19:00:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aesx/aesx.go | 174 ++++++++++++++++++++++++++++++++++++++++++++ aesx/aesx_test.go | 25 +++++++ base64x/base64x.go | 51 +++++++++++++ go.mod | 5 ++ go.sum | 2 + gpgx/gpgx.go | 41 +++++++++++ md5x/md5x.go | 28 +++++++ rsax/rsax.go | 119 ++++++++++++++++++++++++++++++ rsax/rsax_test.go | 19 +++++ sha1x/sha1x.go | 18 +++++ sha1x/sha1x_test.go | 14 ++++ sha256x/sha256x.go | 14 ++++ 12 files changed, 510 insertions(+) create mode 100644 aesx/aesx.go create mode 100644 aesx/aesx_test.go create mode 100644 base64x/base64x.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 gpgx/gpgx.go create mode 100644 md5x/md5x.go create mode 100644 rsax/rsax.go create mode 100644 rsax/rsax_test.go create mode 100644 sha1x/sha1x.go create mode 100644 sha1x/sha1x_test.go create mode 100644 sha256x/sha256x.go diff --git a/aesx/aesx.go b/aesx/aesx.go new file mode 100644 index 0000000..ac08b94 --- /dev/null +++ b/aesx/aesx.go @@ -0,0 +1,174 @@ +package aesx + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/hex" + "errors" + "fmt" + "io" +) + +func PKCS7Padding(ciphertext []byte, blockSize int) []byte { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(ciphertext, padtext...) +} + +func PKCS7UnPadding(origData []byte) []byte { + length := len(origData) + unpadding := int(origData[length-1]) + return origData[:(length - unpadding)] +} + +// AES加密,CBC +func AesEncrypt(origData, key []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + blockSize := block.BlockSize() + origData = PKCS7Padding(origData, blockSize) + blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) + crypted := make([]byte, len(origData)) + blockMode.CryptBlocks(crypted, origData) + return crypted, nil +} + +// AES解密 +func AesDecrypt(crypted, key []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + blockSize := block.BlockSize() + blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) + origData := make([]byte, len(crypted)) + blockMode.CryptBlocks(origData, crypted) + origData = PKCS7UnPadding(origData) + return origData, nil +} + +/* +AES CBC 加密 +key:加密key +plaintext:加密明文 +ciphertext:解密返回字节字符串[ 整型以十六进制方式显示] +*/ +func AESCBCEncrypt(key, plaintext string) (ciphertext string,err error) { + plainbyte := []byte(plaintext) + keybyte := []byte(key) + if len(plainbyte)%aes.BlockSize != 0 { + return "",errors.New ("plaintext is not a multiple of the block size") + } + block, err := aes.NewCipher(keybyte) + if err != nil { + return "",err + } + + cipherbyte := make([]byte, aes.BlockSize+len(plainbyte)) + iv := cipherbyte[:aes.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return "",err + } + + mode := cipher.NewCBCEncrypter(block, iv) + mode.CryptBlocks(cipherbyte[aes.BlockSize:], plainbyte) + + ciphertext = fmt.Sprintf("%x\n", cipherbyte) + return +} + +/* +AES CBC 解码 +key:解密key +ciphertext:加密返回的串 +plaintext:解密后的字符串 +*/ +func AESCBCDecrypter(key, ciphertext string) (plaintext string,err error) { + cipherbyte, _ := hex.DecodeString(ciphertext) + keybyte := []byte(key) + block, err := aes.NewCipher(keybyte) + if err != nil { + return "",err + } + if len(cipherbyte) < aes.BlockSize { + return "", errors.New("ciphertext too short") + } + + iv := cipherbyte[:aes.BlockSize] + cipherbyte = cipherbyte[aes.BlockSize:] + if len(cipherbyte)%aes.BlockSize != 0 { + return "", errors.New("ciphertext is not a multiple of the block size") + } + + mode := cipher.NewCBCDecrypter(block, iv) + mode.CryptBlocks(cipherbyte, cipherbyte) + + //fmt.Printf("%s\n", ciphertext) + plaintext = string(cipherbyte[:]) + return +} + +/* +AES GCM 加密 +key:加密key +plaintext:加密明文 +ciphertext:解密返回字节字符串[ 整型以十六进制方式显示] +*/ +func AESGCMEncrypt(key, plaintext string) (ciphertext, noncetext string, err error) { + plainbyte := []byte(plaintext) + keybyte := []byte(key) + block, err := aes.NewCipher(keybyte) + if err != nil { + return "", "", err + } + + // 由于存在重复的风险,请勿使用给定密钥使用超过2^32个随机值。 + nonce := make([]byte, 12) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return "", "", err + } + + aesgcm, err := cipher.NewGCM(block) + if err != nil { + return "", "", err + } + + cipherbyte := aesgcm.Seal(nil, nonce, plainbyte, nil) + ciphertext = fmt.Sprintf("%x\n", cipherbyte) + noncetext = fmt.Sprintf("%x\n", nonce) + return +} + +/* +AES CBC 解码 +key:解密key +ciphertext:加密返回的串 +plaintext:解密后的字符串 +*/ +func AESGCMDecrypter(key, ciphertext, noncetext string) (plaintext string, err error) { + cipherbyte, _ := hex.DecodeString(ciphertext) + nonce, _ := hex.DecodeString(noncetext) + keybyte := []byte(key) + block, err := aes.NewCipher(keybyte) + if err != nil { + return "", err + } + + aesgcm, err := cipher.NewGCM(block) + if err != nil { + return "", err + } + + plainbyte, err := aesgcm.Open(nil, nonce, cipherbyte, nil) + if err != nil { + return "", err + } + + //fmt.Printf("%s\n", ciphertext) + plaintext = string(plainbyte[:]) + return +} diff --git a/aesx/aesx_test.go b/aesx/aesx_test.go new file mode 100644 index 0000000..a5bd5f1 --- /dev/null +++ b/aesx/aesx_test.go @@ -0,0 +1,25 @@ +package aesx_test + +import ( + "fmt" + "testing" + + "code.yun.ink/pkg/encryptx/aesx" +) + +func TestAes(t *testing.T) { + key := "example key 1234" + plaintext := "exampleplaintext" + ciphertext, err := aesx.AESCBCEncrypt(key, plaintext) + fmt.Println(ciphertext, err) + + plaintext, err = aesx.AESCBCDecrypter(key, ciphertext) + fmt.Println(plaintext, err) + ///GCM + noncetext := "" + ciphertext, noncetext, err = aesx.AESGCMEncrypt(key, plaintext) + fmt.Println(ciphertext, err) + + plaintext, err = aesx.AESGCMDecrypter(key, ciphertext, noncetext) + fmt.Println(plaintext, err) +} diff --git a/base64x/base64x.go b/base64x/base64x.go new file mode 100644 index 0000000..a987af8 --- /dev/null +++ b/base64x/base64x.go @@ -0,0 +1,51 @@ +package base64x + +import "encoding/base64" + +// 普通的 +func Base64StdEncode(s string) string { + return base64.StdEncoding.EncodeToString([]byte(s)) +} + +func Base64StdDecode(sEnc string) (string, error) { + sDec, err := base64.StdEncoding.DecodeString(sEnc) + if err != nil { + return "", err + } + return string(sDec), nil +} + +// URL和文件名安全的 +func Base64UrlEncode(s string) string { + return base64.URLEncoding.EncodeToString([]byte(s)) +} + +func Base64UrlDecode(sEnc string) (string, error) { + sDec, err := base64.URLEncoding.DecodeString(sEnc) + if err != nil { + return "", err + } + return string(sDec), nil +} + +// 无填充 +func Base64RawEncode(s string) string { + return base64.RawStdEncoding.EncodeToString([]byte(s)) +} + +func Base64RawDecode(sEnc string) (string, error) { + sDec, err := base64.RawStdEncoding.DecodeString(sEnc) + if err != nil { + return "", err + } + return string(sDec), nil +} + +func Base64RawUrlEncode(s string) string { + return base64.RawURLEncoding.EncodeToString([]byte(s)) +} + +func Base64RawUrlDecode(s string) (string, error) { + decoded, err := base64.RawURLEncoding.DecodeString(s) + return string(decoded), err +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..27fdbfd --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module code.yun.ink/pkg/encryptx + +go 1.19 + +require golang.org/x/crypto v0.15.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..fcac726 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= diff --git a/gpgx/gpgx.go b/gpgx/gpgx.go new file mode 100644 index 0000000..f9a698f --- /dev/null +++ b/gpgx/gpgx.go @@ -0,0 +1,41 @@ +package gpgx + +import ( + "fmt" + "os" + + "golang.org/x/crypto/openpgp" +) + +func Demo() { + keyRingReader, err := os.Open("signer-pubkey.asc") + if err != nil { + fmt.Println(err) + return + } + + signature, err := os.Open("signature.asc") + if err != nil { + fmt.Println(err) + return + } + + verification_target, err := os.Open("MysqL-5.7.9-win32.zip") + if err != nil { + fmt.Println(err) + return + } + + keyring, err := openpgp.ReadArmoredKeyRing(keyRingReader) + if err != nil { + fmt.Println("Read Armored Key Ring: " + err.Error()) + return + } + entity, err := openpgp.CheckArmoredDetachedSignature(keyring, verification_target, signature) + if err != nil { + fmt.Println("Check Detached Signature: " + err.Error()) + return + } + + fmt.Println(entity) +} diff --git a/md5x/md5x.go b/md5x/md5x.go new file mode 100644 index 0000000..355e2e9 --- /dev/null +++ b/md5x/md5x.go @@ -0,0 +1,28 @@ +package md5x + +import ( + "crypto/md5" + "encoding/hex" + "io" + "os" +) + +// 字符串的md5 +func Md5String(value string) string { + m := md5.New() + m.Write([]byte(value)) + return hex.EncodeToString(m.Sum(nil)) +} + +// 文件的md5 +func Md5File(path string) (string, error) { + file, err := os.Open(path) + if err != nil { + return "", err + } + defer file.Close() + + hash := md5.New() + io.Copy(hash, file) + return hex.EncodeToString(hash.Sum(nil)), nil +} diff --git a/rsax/rsax.go b/rsax/rsax.go new file mode 100644 index 0000000..49901cf --- /dev/null +++ b/rsax/rsax.go @@ -0,0 +1,119 @@ +package rsax + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "os" +) + +//生成RSA私钥和公钥,保存到文件中 +// 与下面命令等价 +// 生成私钥 +// openssl genrsa -out rsa_private_key.pem 1024 +// 生成公钥 +// openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem +// bits 证书大小 1024/2048 +func GenerateRSAKey(bits int) { + //GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥 + //Reader是一个全局、共享的密码用强随机数生成器 + privateKey, err := rsa.GenerateKey(rand.Reader, bits) + if err != nil { + panic(err) + } + //保存私钥 + //通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串 + X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey) + //使用pem格式对x509输出的内容进行编码 + //创建文件保存私钥 + privateFile, err := os.Create("private.pem") + if err != nil { + panic(err) + } + defer privateFile.Close() + //构建一个pem.Block结构体对象 + privateBlock := pem.Block{Type: "RSA Private Key", Bytes: X509PrivateKey} + //将数据保存到文件 + pem.Encode(privateFile, &privateBlock) + + //保存公钥 + //获取公钥的数据 + publicKey := privateKey.PublicKey + //X509对公钥编码 + X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey) + if err != nil { + panic(err) + } + //pem格式编码 + //创建用于保存公钥的文件 + publicFile, err := os.Create("public.pem") + if err != nil { + panic(err) + } + defer publicFile.Close() + //创建一个pem.Block结构体对象 + publicBlock := pem.Block{Type: "RSA Public Key", Bytes: X509PublicKey} + //保存到文件 + pem.Encode(publicFile, &publicBlock) +} + +// RSA加密 +// plainText 要加密的数据 +// path 公钥匙文件地址 +func RSA_Encrypt(plainText []byte, path string) []byte { + //打开文件 + file, err := os.Open(path) + if err != nil { + panic(err) + } + defer file.Close() + //读取文件的内容 + info, _ := file.Stat() + buf := make([]byte, info.Size()) + file.Read(buf) + //pem解码 + block, _ := pem.Decode(buf) + //x509解码 + + publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + panic(err) + } + //类型断言 + publicKey := publicKeyInterface.(*rsa.PublicKey) + //对明文进行加密 + cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText) + if err != nil { + panic(err) + } + //返回密文 + return cipherText +} + +//RSA解密 +// cipherText 需要解密的byte数据 +// path 私钥文件路径 +func RSA_Decrypt(cipherText []byte, path string) []byte { + //打开文件 + file, err := os.Open(path) + if err != nil { + panic(err) + } + defer file.Close() + //获取文件内容 + info, _ := file.Stat() + buf := make([]byte, info.Size()) + file.Read(buf) + //pem解码 + block, _ := pem.Decode(buf) + //X509解码 + privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + panic(err) + } + //对密文进行解密 + plainText, _ := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText) + //返回明文 + return plainText +} diff --git a/rsax/rsax_test.go b/rsax/rsax_test.go new file mode 100644 index 0000000..285da54 --- /dev/null +++ b/rsax/rsax_test.go @@ -0,0 +1,19 @@ +package rsax_test + +import ( + "fmt" + "testing" + + "code.yun.ink/pkg/encryptx/rsax" +) + +func TestRsa(t *testing.T) { + //加密 + data := []byte("hello world") + encrypt := rsax.RSA_Encrypt(data, "public.pem") + fmt.Println(string(encrypt)) + + // 解密 + decrypt := rsax.RSA_Decrypt(encrypt, "private.pem") + fmt.Println(string(decrypt)) +} diff --git a/sha1x/sha1x.go b/sha1x/sha1x.go new file mode 100644 index 0000000..f17cc86 --- /dev/null +++ b/sha1x/sha1x.go @@ -0,0 +1,18 @@ +package sha1x + +import ( + "crypto/sha1" + "encoding/hex" +) + +func Sha1(s string) string { + h := sha1.New() + h.Write([]byte(s)) + + bs := h.Sum(nil) + return hex.EncodeToString(bs) + + // return fmt.Sprintf("%x", bs) + + // return res +} diff --git a/sha1x/sha1x_test.go b/sha1x/sha1x_test.go new file mode 100644 index 0000000..af88f07 --- /dev/null +++ b/sha1x/sha1x_test.go @@ -0,0 +1,14 @@ +package sha1x_test + +import ( + "fmt" + "testing" + + "code.yun.ink/pkg/encryptx/sha1x" +) + +func TestSha1(t *testing.T) { + s := "sha1 this string" + r := sha1x.Sha1(s) + fmt.Println(r) +} diff --git a/sha256x/sha256x.go b/sha256x/sha256x.go new file mode 100644 index 0000000..fcfc0d8 --- /dev/null +++ b/sha256x/sha256x.go @@ -0,0 +1,14 @@ +package sha256x + +import ( + "crypto/sha256" + "encoding/hex" +) + +//Sha256加密 +func Sha256(src string) string { + m := sha256.New() + m.Write([]byte(src)) + res := hex.EncodeToString(m.Sum(nil)) + return res +}