数据文件备份

文件压缩、加密与解压缩&解密

1、注意事项

1、先压缩、在加密(加密后变成2进制在压缩没啥效果);先解密、在解压缩

· 加密后的数据由于其高度的随机性和熵值,压缩效果会非常有限

2、需要压缩到新文件,需要清理原文件;还原文件后 也需要删除原加密文件

· 避免原文件积累占用磁盘

2、代码

cat encry_gzip_tarfiles.go

package main

import (
    "archive/tar"
    "bytes"
    "compress/gzip"
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
    "encoding/hex"
    "fmt"
    "io"
    "os"
    "path/filepath"
    "strings"
)

//生成用于 AES 加密的密钥通常涉及生成一个足够强度的随机字节序列
func generateAESKey(size int) ([]byte, error) {
    key := make([]byte, size)
    if _, err := rand.Read(key); err != nil {
        return nil, fmt.Errorf("failed to generate key: %v", err)
    }
    return key, nil
}

func compressAndEncrypt(filename string, key []byte) error {
    // 读取原始文件
    plaintext, err := os.ReadFile(filename)
    if err != nil {
        return err
    }

    // 先进行压缩
    var b bytes.Buffer
    gz := gzip.NewWriter(&b)
    if _, err := gz.Write(plaintext); err != nil {
        return err
    }
    if err := gz.Close(); err != nil {
        return err
    }
    compressedData := b.Bytes()
    // 设置加密
    block, err := aes.NewCipher(key)
    if err != nil {
        return err
    }
    ciphertext := make([]byte, aes.BlockSize+len(compressedData))
    iv := ciphertext[:aes.BlockSize]
    if _, err := io.ReadFull(rand.Reader, iv); err != nil {
        return err
    }
    stream := cipher.NewCFBEncrypter(block, iv)
    stream.XORKeyStream(ciphertext[aes.BlockSize:], compressedData)
    // 写入加密后的压缩文件
    encryptedFile, err := os.Create(filename + ".gz.enc")
    if err != nil {
        return err
    }
    defer encryptedFile.Close()
    if _, err = encryptedFile.Write(ciphertext); err != nil {
        return err
    }
    // 删除原始文件
    err = os.Remove(filename)
    if err != nil {
        return err
    }
    return nil
}

func TarFiles(sourceDir, tarFilename string) error {
    // 创建 tar 文件
    tarFile, err := os.Create(tarFilename)
    if err != nil {
        return err
    }
    defer tarFile.Close()
    // 创建 tar.Writer 对象
    tarWriter := tar.NewWriter(tarFile)
    defer tarWriter.Close()
    // 遍历目录
    err = filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        // 创建 tar 头部信息
        header, err := tar.FileInfoHeader(info, "")
        if err != nil {
            return err
        }

        // 设置头部信息的 Name 属性为文件相对于 sourceDir 的路径
        header.Name, err = filepath.Rel(sourceDir, path)
        if err != nil {
            return err
        }

        // 写入头部信息
        if err := tarWriter.WriteHeader(header); err != nil {
            return err
        }

        // 如果是普通文件,则写入文件内容
        if !info.IsDir() {
            file, err := os.Open(path)
            if err != nil {
                return err
            }
            defer file.Close()
            if _, err := io.Copy(tarWriter, file); err != nil {
                return err
            }
        }
        return nil
    })

    return err
}

// func uploadToS3(bucket, item, filename string) error {
//  sess := session.Must(session.NewSession())
//  svc := s3.New(sess)

//  file, err := os.Open(filename)
//  if err != nil {
//      return err
//  }
//  defer file.Close()

//  _, err = svc.PutObject(&s3.PutObjectInput{
//      Bucket: aws.String(bucket),
//      Key:    aws.String(item),
//      Body:   file,
//  })
//  return err
// }

// decryptAndDecompress 解密并解压缩文件
func decryptAndDecompress(filename string, key []byte) error {
    // 读取加密的文件
    ciphertext, err := os.ReadFile(filename)
    if err != nil {
        return err
    }

    // 设置解密
    block, err := aes.NewCipher(key)
    if err != nil {
        return err
    }
    if len(ciphertext) < aes.BlockSize {
        return io.ErrUnexpectedEOF
    }
    iv := ciphertext[:aes.BlockSize]
    ciphertext = ciphertext[aes.BlockSize:]

    stream := cipher.NewCFBDecrypter(block, iv)
    stream.XORKeyStream(ciphertext, ciphertext)

    // 解压缩数据
    b := bytes.NewBuffer(ciphertext)
    gz, err := gzip.NewReader(b)
    if err != nil {
        return err
    }
    defer gz.Close()
    // 读取解压缩后的数据
    decompressedData, err := io.ReadAll(gz)
    if err != nil {
        return err
    }
    // 写入解压缩后的文件
    newFilename := strings.TrimSuffix(filename, ".gz.enc")
    decompressedFile, err := os.Create(newFilename)
    // decompressedFile, err := os.Create(filename + ".dec")
    if err != nil {
        return err
    }
    defer decompressedFile.Close()
    if _, err = decompressedFile.Write(decompressedData); err != nil {
        return err
    }

    err = os.Remove(filename)
    if err != nil {
        return err
    }

    return nil
}

func encryptAndCompressFiles(files []string, key []byte) error {
    for _, filename := range files {
        err := compressAndEncrypt(filename, key)
        if err != nil {
            return err
        }
    }
    return nil
}

func decryptAndDecompressFiles(files []string, key []byte) error {
    for _, filename := range files {
        err := decryptAndDecompress(filename, key)
        if err != nil {
            return err
        }
    }
    return nil
}

func getAllFiles(dir string) ([]string, error) {
    var files []string
    err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        // 跳过目录
        if info.IsDir() {
            return nil
        }
        files = append(files, path)
        return nil
    })

    if err != nil {
        return nil, err
    }

    return files, nil
}

func UntarFiles(tarFilename, destDir string) error {
    // 打开 tar 文件
    tarFile, err := os.Open(tarFilename)
    if err != nil {
        return err
    }
    defer tarFile.Close()

    // 创建 tar.Reader 对象
    tarReader := tar.NewReader(tarFile)

    // 遍历 tar 中的所有项目
    for {
        header, err := tarReader.Next()
        if err == io.EOF {
            break // 文件结束
        }
        if err != nil {
            return err
        }

        // 目标文件路径
        targetPath := filepath.Join(destDir, header.Name)

        switch header.Typeflag {
        case tar.TypeDir: // 是目录
            // 创建目录
            if err := os.MkdirAll(targetPath, 0755); err != nil {
                return err
            }
        case tar.TypeReg: // 是普通文件
            // 创建文件
            outFile, err := os.Create(targetPath)
            if err != nil {
                return err
            }
            defer outFile.Close()

            // 复制文件内容
            if _, err := io.Copy(outFile, tarReader); err != nil {
                return err
            }
        }
    }

    return nil
}

func main() {
    // //生成随机加密key
    // prikey, err := generateAESKey(32) // 生成一个256位的AES密钥,加、解密用到

    // //压缩、加密子文件、打包为一个备份文件
    // sourceDir := "1046/2024_03_01/mymongo/"
    // inifiles, err := getAllFiles(sourceDir)
    // if err != nil {
    //  fmt.Println("获取文件列表失败:", err)
    //  return
    // }

    // if err != nil {
    //  fmt.Println("Error generating prikey:", err)
    //  return
    // }
    // fmt.Printf("Generated prikey: %xn", prikey)

    // fmt.Println("开始加密、压缩文件...")
    // err = encryptAndCompressFiles(inifiles, prikey)
    // if err != nil {
    //  fmt.Println("加密、压缩文件失败:", err)
    //  return
    // }

    // fmt.Println("开始打包加密子文件...")
    // tarFilename := "sre-core.tar"
    // if err := TarFiles(sourceDir, tarFilename); err != nil {
    //  panic(err)
    // }

    // 解包备份文件、解密、解压缩
    tarFilename := "sre-core.tar"
    destDir := "extracted_files/"
    if err := UntarFiles(tarFilename, destDir); err != nil {
        panic(err)
    }

    // sourceDir := "1046/2024_03_01/mymongo/"
    encr_bakfiles, err := getAllFiles(destDir)
    if err != nil {
        fmt.Println("获取文件列表失败:", err)
        return
    }

    fmt.Println("开始解密、解压缩文件...")
    pprikey := "761d400147d02ccad0e9fb0929560311867019c5ba46491f5bd04a7532659600"
    prikeyBytes, err := hex.DecodeString(pprikey) // 解码十六进制字符串
    if err != nil {
        panic(err) // 处理可能的解码错误
    }

    err = decryptAndDecompressFiles(encr_bakfiles, prikeyBytes)
    if err != nil {
        panic(err)
    } else {
        fmt.Println("备份文件解密、解压缩完成!!!")
    }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
Secured By miniOrange