Compare commits

...

3 Commits

  1. 101
      aufs/crypto/example.go
  2. 191
      aufs/crypto/keygen.go
  3. 9
      aufs/db/servDb.go
  4. 9
      aufs/go.mod
  5. 10
      aufs/go.sum
  6. 17
      aufs/main.go
  7. 30
      aufs/private.pem
  8. 9
      aufs/public.pem

101
aufs/crypto/example.go

@ -0,0 +1,101 @@
package crypto
import (
"fmt"
"os"
)
// 示例:生成密钥对并存入文件
func ExampleGenerateAndSaveKeys() {
// 密钥位数
bits := 2048
// 用户密码(实际应用中应该从用户输入获取)
password := "your_secure_password"
// 密钥文件保存路径
privateKeyPath := "private.pem"
publicKeyPath := "public.pem"
// 生成并保存密钥对
err := GenerateAndSaveKeysWithPassword(bits, password, privateKeyPath, publicKeyPath)
if err != nil {
fmt.Printf("生成密钥失败: %v\n", err)
return
}
fmt.Println("密钥生成和保存成功!")
}
// 示例:读取并解密私钥
func ExampleReadAndDecryptPrivateKey() {
// 密码和文件路径
password := "your_secure_password"
privateKeyPath := "private.pem"
// 读取加密的私钥文件
data, err := os.ReadFile(privateKeyPath)
if err != nil {
fmt.Printf("读取私钥文件失败: %v\n", err)
return
}
// 解密私钥
privateKey, err := DecryptPrivateKey(data, password)
if err != nil {
fmt.Printf("解密私钥失败: %v\n", err)
return
}
fmt.Println("私钥解密成功!")
fmt.Printf("私钥模数长度: %d 位\n", privateKey.N.BitLen())
}
// 主函数示例(如果单独运行这个文件)
func ExampleMain() {
// 生成密钥对
ExampleGenerateAndSaveKeys()
// 读取并解密私钥
ExampleReadAndDecryptPrivateKey()
}
/*
使用说明
1. 生成密钥对
- 调用GenerateAndSaveKeysWithPassword函数
- 参数密钥位数(通常2048或4096)保护私钥的密码私钥保存路径公钥保存路径
2. 读取并解密私钥
- 读取私钥文件
- 调用DecryptPrivateKey函数用密码解密
3. 注意事项
- 密码应足够复杂且安全存储
- 私钥文件应妥善保管建议设置严格的文件权限
- 密钥位数推荐使用2048位以上以保证安全性
示例代码
package main
import (
"fmt"
"your_project/crypto"
)
func main() {
// 生成密钥对
bits := 2048
password := "your_secure_password"
privateKeyPath := "private.pem"
publicKeyPath := "public.pem"
err := crypto.GenerateAndSaveKeysWithPassword(bits, password, privateKeyPath, publicKeyPath)
if err != nil {
fmt.Printf("错误: %v\n", err)
return
}
fmt.Println("密钥生成完成!")
}
*/

191
aufs/crypto/keygen.go

@ -0,0 +1,191 @@
package crypto
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"golang.org/x/crypto/bcrypt"
"os"
)
// KeyPair 表示生成的密钥对
type KeyPair struct {
PrivateKey *rsa.PrivateKey
PublicKey *rsa.PublicKey
}
// GenerateRSAKeyPair 生成指定位数的RSA密钥对
func GenerateRSAKeyPair(bits int) (*KeyPair, error) {
// 生成RSA私钥
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, fmt.Errorf("生成RSA密钥失败: %v", err)
}
// 验证私钥
err = privateKey.Validate()
if err != nil {
return nil, fmt.Errorf("验证RSA密钥失败: %v", err)
}
// 获取公钥
publicKey := &privateKey.PublicKey
return &KeyPair{
PrivateKey: privateKey,
PublicKey: publicKey,
}, nil
}
// EncryptPrivateKey 使用密码加密私钥
func EncryptPrivateKey(privateKey *rsa.PrivateKey, password string) ([]byte, error) {
if password == "" {
return nil, errors.New("密码不能为空")
}
// 将私钥转换为PKCS#1格式
privDER := x509.MarshalPKCS1PrivateKey(privateKey)
// 使用密码加密私钥
block, err := x509.EncryptPEMBlock(
rand.Reader,
"RSA PRIVATE KEY",
privDER,
[]byte(password),
x509.PEMCipherAES256,
)
if err != nil {
return nil, fmt.Errorf("加密私钥失败: %v", err)
}
// 将加密后的私钥转换为PEM格式
encprivPEM := pem.EncodeToMemory(block)
return encprivPEM, nil
}
// ExportPublicKey 将公钥导出为PEM格式
func ExportPublicKey(publicKey *rsa.PublicKey) ([]byte, error) {
// 将公钥转换为DER格式
pubDER, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
return nil, fmt.Errorf("编码公钥失败: %v", err)
}
// 创建PEM块
block := &pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: pubDER,
}
// 将公钥转换为PEM格式
pubPEM := pem.EncodeToMemory(block)
return pubPEM, nil
}
// HashPassword 对密码进行哈希处理
func HashPassword(password string) (string, error) {
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return "", err
}
return string(hash), nil
}
// CheckPasswordHash 验证密码是否与哈希值匹配
func CheckPasswordHash(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}
// GenerateKeysWithPassword 生成加密的密钥对,返回公钥和加密后的私钥
func GenerateKeysWithPassword(bits int, password string) (publicKeyPEM []byte, encryptedPrivateKeyPEM []byte, err error) {
// 生成密钥对
keyPair, err := GenerateRSAKeyPair(bits)
if err != nil {
return nil, nil, err
}
// 加密私钥
encryptedPrivateKeyPEM, err = EncryptPrivateKey(keyPair.PrivateKey, password)
if err != nil {
return nil, nil, err
}
// 导出公钥
publicKeyPEM, err = ExportPublicKey(keyPair.PublicKey)
if err != nil {
return nil, nil, err
}
return publicKeyPEM, encryptedPrivateKeyPEM, nil
}
// DecryptPrivateKey 使用密码解密私钥
func DecryptPrivateKey(encryptedPrivateKeyPEM []byte, password string) (*rsa.PrivateKey, error) {
if password == "" {
return nil, errors.New("密码不能为空")
}
// 解码PEM块
block, _ := pem.Decode(encryptedPrivateKeyPEM)
if block == nil {
return nil, errors.New("无法解码PEM块")
}
// 解密私钥
decryptedDER, err := x509.DecryptPEMBlock(block, []byte(password))
if err != nil {
return nil, fmt.Errorf("解密私钥失败: %v", err)
}
// 解析私钥
privateKey, err := x509.ParsePKCS1PrivateKey(decryptedDER)
if err != nil {
return nil, fmt.Errorf("解析私钥失败: %v", err)
}
return privateKey, nil
}
// SaveKeyToFile 将密钥数据保存到指定文件
func SaveKeyToFile(filePath string, keyData []byte) error {
// 写入文件
err := os.WriteFile(filePath, keyData, 0600) // 仅用户可读写权限
if err != nil {
return fmt.Errorf("保存密钥到文件失败: %v", err)
}
fmt.Printf("密钥已成功保存到: %s\n", filePath)
return nil
}
// GenerateAndSaveKeysWithPassword 生成密钥对并用密码保护私钥,然后保存到文件
func GenerateAndSaveKeysWithPassword(bits int, password, privateKeyPath, publicKeyPath string) error {
// 生成密钥对
publicKeyPEM, encryptedPrivateKeyPEM, err := GenerateKeysWithPassword(bits, password)
if err != nil {
return err
}
// 保存公钥到文件
err = SaveKeyToFile(publicKeyPath, publicKeyPEM)
if err != nil {
return err
}
// 保存加密后的私钥到文件
err = SaveKeyToFile(privateKeyPath, encryptedPrivateKeyPEM)
if err != nil {
return err
}
fmt.Println("密钥对已成功生成并保存!")
return nil
}

9
aufs/db/servDb.go

@ -9,13 +9,20 @@ import (
func CreateScdb() { func CreateScdb() {
// 建表语句 // 建表语句
sts := ` sts := `
CREATE TABLE sc_server ( CREATE TABLE IF NOT EXISTS sc_server (
id INTEGER PRIMARY KEY NOT NULL PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY NOT NULL PRIMARY KEY AUTOINCREMENT,
scname TEXT NOT NULL, scname TEXT NOT NULL,
addr TEXT NOT NULL, addr TEXT NOT NULL,
port TEXT NOT NULL, port TEXT NOT NULL,
token TEXT NOT NULL, token TEXT NOT NULL,
status INTEGER NOT NULL status INTEGER NOT NULL
);`
// 系统用户表
sts += `
CREATE TABLE IF NOT EXISTS sc_user (
id INTEGER PRIMARY KEY NOT NULL PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
password TEXT NOT NULL
);` );`
// 执行建表语句 // 执行建表语句
_, err = db.Exec(sts) _, err = db.Exec(sts)

9
aufs/go.mod

@ -1,11 +1,14 @@
module aufs module aufs
go 1.23.0 go 1.24.0
toolchain go1.24.6
require ( require (
github.com/jmoiron/sqlx v1.4.0 github.com/jmoiron/sqlx v1.4.0
github.com/logoove/sqlite v1.37.1 github.com/logoove/sqlite v1.37.1
github.com/schollz/progressbar/v3 v3.18.0 github.com/schollz/progressbar/v3 v3.18.0
golang.org/x/crypto v0.44.0
google.golang.org/protobuf v1.36.7 google.golang.org/protobuf v1.36.7
) )
@ -18,8 +21,8 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
golang.org/x/sys v0.34.0 // indirect golang.org/x/sys v0.38.0 // indirect
golang.org/x/term v0.28.0 // indirect golang.org/x/term v0.37.0 // indirect
modernc.org/libc v1.66.3 // indirect modernc.org/libc v1.66.3 // indirect
modernc.org/mathutil v1.7.1 // indirect modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect modernc.org/memory v1.11.0 // indirect

10
aufs/go.sum

@ -40,6 +40,8 @@ github.com/schollz/progressbar/v3 v3.18.0 h1:uXdoHABRFmNIjUfte/Ex7WtuyVslrw2wVPQ
github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec= github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
@ -47,10 +49,10 @@ golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=

17
aufs/main.go

@ -3,6 +3,7 @@ package main
import ( import (
"aufs/config" "aufs/config"
"aufs/core" "aufs/core"
"aufs/crypto"
"fmt" "fmt"
"log" "log"
"mime" "mime"
@ -97,6 +98,22 @@ func main() {
os.Exit(1) os.Exit(1)
} }
// 初始化加密证书
if flag == "-mc" {
bits := 2048
password := "xc1123"
privateKeyPath := "private.pem"
publicKeyPath := "public.pem"
err := crypto.GenerateAndSaveKeysWithPassword(bits, password, privateKeyPath, publicKeyPath)
if err != nil {
fmt.Printf("错误: %v\n", err)
return
}
fmt.Println("密钥生成完成!")
}
// args 长度大于4 才有意思 // args 长度大于4 才有意思
if len(args) > 4 { if len(args) > 4 {
config.G.Port = args[4] config.G.Port = args[4]

30
aufs/private.pem

@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,60c8623b1977ed9926f090a559fefbb7
EXkcUgG90PRmUMzWCc9tYhVV/FclX0Kgbnaaj++ssUVLfHqo7ktrQ757VGLuJ2zC
Sr6Gi88jxRJq98i6gCe4EzL0Q1I7pzqlH3bGxervnCtX9nbDiA4UKpDDQ/nsDuBp
fzyTtwx3xu7MXxQX54XADexcfX4kP08h4LJoPJbnRk9dvEI29TUAmwX9vCyCZVec
DE1kYQOLDzJvX4sKMsCiKzjTQwl46LdYHdn3wYzETnmR3/0dIzDLldWt9TZuYue4
/lpUdtVY2DGC2+2y9jvNlos9vpsZ2FyUi+M0NICmtkiPoqXzqhuPewwZ+hCw3rbe
p/Q12NiMcnX+0cWwNqgZjDgwUOM+b8UW4pYNYlFzzhBBFA88EI4QGJLHM2ougTS2
9gXrIOwknRdnvIuUzuf7UIJ7s2C6tIhKQyyMbdzZ2tQQQ7ei+S7EpY6fHJ5OfYfK
5KbjuneZV/8eCoT97KInTKqMpT57cFVNHzLlri+9kXPpY6HAl+L8Qp7IhAjfDnp7
jElgWPaNcuuR4wYJY6ehNBFQ0Hp8SgduquATVf8FssrM4eTyirBsBrMYSbwl3FGZ
H6BuksvCqq31M/k1EscSbGrb99MokMsQTUeNbY438QvukRi6oowXuriqiQwXhgOl
4Xc8AIxeE79dDfPPskbhGWgBxztolrHEpE2Ttdxa/4q95sMHhEqPDtLYri6immqk
WHcly5tlAtA/JiEAxC2dwDL4vkdB0s92+wCXt5HOlkGqXLLkkE9ST+mwpGGwCk/9
BI65vh87ME/dBCPNfNCK7iKU2E1cRjJmpgD+dowCwH4g8QmIj73t1pZtY6XiWdx3
5797R8cA62HItmGw05/Ab9niFkecJYhDWM+N7iqLHadhtTubwCkOIE7PkBjuWsL/
zTj3RlyGxELwokJ6qeC93Zg/OzKGFCdLMHEkD1RIrglYOGBLO1NovFzPHFav8rkB
jEkl4GsQX6OzeImlDOCkx0YH1ron8lydBTY2ohhtwJkn2MDlEa3CYC/yz9IqzzkI
fMBqFpVe/Ehy2ekuRYen5LRBaDG1DhHeCByr00+q7liCqm47bALsiS7O0d8W6mEw
UNr5GkHPCsxq3fk0zw2OuR6txfmCP/tF8jC/SLpZdTv7+sQIqDq5qkcand5nzkT4
o2Laz6Z5zKj0zwBQ983NQm4Ikz4uJ/eL0vxZ2CtmLi381r1bhWDNyz3KhGbGG7U/
qfE5sTdS3FaFAT8rrsgUb7pwNX2p9jYkn/KKy9Qp1fCFavdSmN/W0JBSH/3zGMCI
346tShf5D7ZF2Wo9Jn1PKP+YLG1zo5f9KUa28sGgCtly1TJlCSsHC7dOVoVg8s6A
mRDlmE+/xL4AgPLVmupUvNn8uW+Y8iNnlZpmtsSvsIv0p2Xj5T/UZPUQZ3FR8YyB
7CiUOTCq/goUIqv3SnpK7prQ31Uxj13UbiAIZGOVjkkSRlC/eX4oYuxCM+iMFzd4
XkH6hVOh67AFU/wri1vzQfCfL78XomlMc+nYviI5dwbO/5uSv5bqEThkFO/9arAt
SVshbq1c5hhFRHE4BuIRTobaJLMJcrWwSyfodAxYWpLpY4BVnO/b8Uc+fRVEnvmG
-----END RSA PRIVATE KEY-----

9
aufs/public.pem

@ -0,0 +1,9 @@
-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvWKj7FVU7KtUUWWeV53K
a1t538iiydZI2VEkRSsXt3LIi6j94PsdOmS8e6ZyByGj0T+deVVEdqO7pvJTlZCt
R5z2gut3Z/heG1SF0o5i6YfZvfeyeNWrW6TVQCy+FCweVA6Zlh1QiLubAfYFclTm
5wdF+suZHSnXS1reborotzRGZzq86XEluIQufdvfk55ixY8R/bdoaR4G/SvNzU+2
uBYjOxlBbgtnHmPxs3bAk2wCnPunfjlWw0ngk8UVw7XrAdrIwMItpj4Y0iKUsr5Z
CVpheVmHNfjH8oyio/aERdSXnsM4GksFgOlA9wKQ6opwfQSMhH0mMNThpqzKx/Xt
0wIDAQAB
-----END RSA PUBLIC KEY-----
Loading…
Cancel
Save