美文网首页
AWS-SDK-GO 通过SSE-C服务端加密存储

AWS-SDK-GO 通过SSE-C服务端加密存储

作者: 时彬斌 | 来源:发表于2022-03-25 11:39 被阅读0次

    我们在需要存储文件的数据落盘加密时,就会用到这种简单的服务端加密实现;
    使用的前提是:

    1. S3存储服务端支持https;
    2. S3存储服务端实现了AES256加密

    下面我们以go的aws sdk来进行举例,本例是访问私有签发证书的服务:

    import (
        "bytes"
        "context"
        "crypto/md5"
        "crypto/tls"
        "crypto/x509"
        "encoding/json"
        "fmt"
        "github.com/aws/aws-sdk-go/aws"
        "github.com/aws/aws-sdk-go/aws/awserr"
        credentials2 "github.com/aws/aws-sdk-go/aws/credentials"
        "github.com/aws/aws-sdk-go/aws/session"
        "github.com/aws/aws-sdk-go/service/iam"
        "github.com/aws/aws-sdk-go/service/s3"
        "github.com/aws/aws-sdk-go/service/s3/s3manager"
        "github.com/minio/minio-go/v7"
        "github.com/minio/minio-go/v7/pkg/credentials"
        "github.com/minio/minio-go/v7/pkg/encrypt"
        "io"
        "io/ioutil"
        "net"
        "net/http"
        "time"
    )
    var(
        ak       = "accessKeyValue"                     //文件服务分配的账号
        sk       = "secretKeyValue"                     //文件服务分配的秘钥
        endPoint = "https://127.0.0.1:9000"     // 存储服务的地址
        region   = "default"              //适用范围
        svc      *s3.S3                     // aws s3 的client
        iamSvc *iam.IAM
        uploader *s3manager.Uploader
        s3Client *minio.Client      // minio s3的client
    )
    func Init(){
        cres := credentials2.NewStaticCredentials(ak, sk, "")
        cfg := aws.NewConfig().WithRegion(region).WithEndpoint(endPoint).WithCredentials(cres).WithS3ForcePathStyle(
            true).WithMaxRetries(0).WithDisableSSL(true)
            // 这段代码就是跳过证书校验,不然会报X509的错误
        tr := &http.Transport{
            TLSClientConfig: &tls.Config{
                InsecureSkipVerify: true,
            },
        }
        cfg.HTTPClient = &http.Client{
            Transport: tr,
        }
        sess, err := session.NewSession(cfg)
        if err != nil {
            fmt.Println(err)
        }
    //   sws S3 的client
        svc = s3.New(sess)
        iamSvc = iam.New(sess, cfg)
    // minio 的client
        s3Client, err = minio.New("127.0.0.1:9000", &minio.Options{
            Creds: credentials.NewStaticV4(ak, sk, ""),
            Secure: true,
            Transport: tr,
        })
        if err != nil {
            fmt.Println(err)
            return
        }
    }
    func main(){
        Init()
        t := time.Now()
        bucketName := "test-ssec"
        objectID := time.Now().Format("20060102150405")
        createBucket(bucketName)
        putSSECObject([]byte("2222-2222-2222-2222"), bucketName, "", objectID)
        getSSECObject(bucketName,objectID)
        putSSECObjectMinio([]byte("2222-2222-2222-2222"), bucketName, "", objectID)
        fmt.Println(time.Since(t))
    }
    
    // 创建bucket
    func createBucket(bucketName string) {
        input := &s3.CreateBucketInput{
            Bucket: aws.String(bucketName),
        }
        result, err := svc.CreateBucket(input)
        fmt.Printf("CreateBucket %v \n", result)
        if err != nil {
            if aerr, ok := err.(awserr.Error); ok {
                switch aerr.Code() {
                case s3.ErrCodeBucketAlreadyExists:
                    fmt.Println(s3.ErrCodeBucketAlreadyExists, aerr.Error())
                case s3.ErrCodeBucketAlreadyOwnedByYou:
                    fmt.Println(s3.ErrCodeBucketAlreadyOwnedByYou, aerr.Error())
                default:
                    fmt.Println(aerr.Error())
                }
            } else {
                fmt.Println(err.Error())
            }
        }
    }
    // aws s3 client 通过SSE-C 的方式上传文件
    func putSSECObject(dataImage []byte, bucketName, contentType, objectID string){
        t := time.Now()
        inputObject := &s3.PutObjectInput{
    
            Bucket:      aws.String(bucketName),
            Key:         aws.String(objectID),
            ContentType: aws.String(contentType),
            Body:       bytes.NewReader(dataImage),
            ContentLength: aws.Int64(int64(len(dataImage))),
            // 目前只支持 AES256
            SSECustomerAlgorithm: aws.String("AES256"),
            // 秘钥的是32位的字符串(下面的是 32byteslongsecretkeymustprovided aws会帮我们做base64编码)
            SSECustomerKey: aws.String("32byteslongsecretkeymustprovided"),
            // 原始秘钥的MD5值,切记是base64之前的秘钥
            SSECustomerKeyMD5: aws.String("7PpPLAK26ONlVUGOWlusfg=="),
        }
    
        fmt.Println(int64(len(dataImage)))
        resp, err := svc.PutObject(inputObject)
        if err != nil {
            fmt.Println(err.Error())
        }
        fmt.Printf("upload resp: %v cost time : %v \n",resp, time.Since(t))
    }
    
    // aws s3 client 通过SSE-C 的方式下载文件
    func getSSECObject(bucketName, objectID string){
        t := time.Now()
        inputObject := &s3.GetObjectInput{
            Bucket:      aws.String(bucketName),
            Key:         aws.String(objectID),
            // 目前只支持 AES256
            SSECustomerAlgorithm: aws.String("AES256"),
            // 秘钥的256位base64编码的字符串(下面的是 32byteslongsecretkeymustprovided 做了base64编码)
            SSECustomerKey: aws.String("32byteslongsecretkeymustprovided"),
            // 原始秘钥的MD5值,切记是base64之前的秘钥
            SSECustomerKeyMD5: aws.String("7PpPLAK26ONlVUGOWlusfg=="),
        }
    
        resp, err := svc.GetObject(inputObject)
        if err != nil {
            fmt.Println(err.Error())
        }
        fmt.Printf("get resp: %v cost time : %v \n",resp, time.Since(t))
        res, err := ioutil.ReadAll(resp.Body)
        if err != nil {
            fmt.Println(err.Error())
        }
        fmt.Println(string(res))
    }
    
    // minio client 上传文件
    func putSSECObjectMinio(dataImage []byte, bucketName, contentType, objectID string){
    
        sse,_ := encrypt.NewSSEC([]byte("32byteslongsecretkeymustprovided"))
        resp, err := s3Client.PutObject(context.Background(), bucketName,objectID,bytes.NewReader(dataImage),
            int64(len(dataImage)),
            minio.PutObjectOptions{
                ServerSideEncryption: sse,
        })
        if err != nil {
            fmt.Printf("putSSECObjectMinio err : %v \n" ,err)
        }
        fmt.Printf("putSSECObjectMinio %v\n", resp)
    }
    
    

    相关文章

      网友评论

          本文标题:AWS-SDK-GO 通过SSE-C服务端加密存储

          本文链接:https://www.haomeiwen.com/subject/aqgrjrtx.html