package main import ( "bytes" "context" "crypto/md5" "crypto/rand" "fmt" "io" "io/ioutil" math_rand "math/rand" "net/http" "net/url" "os" "time" "github.com/tencentyun/cos-go-sdk-v5" "github.com/tencentyun/cos-go-sdk-v5/crypto" "github.com/tencentyun/cos-go-sdk-v5/debug" ) func log_status(err error) { if err == nil { return } if cos.IsNotFoundError(err) { // WARN fmt.Println("WARN: Resource is not existed") } else if e, ok := cos.IsCOSError(err); ok { fmt.Printf("ERROR: Code: %v\n", e.Code) fmt.Printf("ERROR: Message: %v\n", e.Message) fmt.Printf("ERROR: Resource: %v\n", e.Resource) fmt.Printf("ERROR: RequestId: %v\n", e.RequestID) // ERROR } else { fmt.Printf("ERROR: %v\n", err) // ERROR } os.Exit(1) } func simple_put_object() { u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") b := &cos.BaseURL{BucketURL: u} c := cos.NewClient(b, &http.Client{ Transport: &cos.AuthorizationTransport{ SecretID: os.Getenv("COS_SECRETID"), SecretKey: os.Getenv("COS_SECRETKEY"), Transport: &debug.DebugRequestTransport{ RequestHeader: true, RequestBody: false, ResponseHeader: true, ResponseBody: false, }, }, }) // Case1 上传对象 name := "test/example2" fmt.Println("============== simple_put_object ======================") // 该标识信息唯一确认一个主加密密钥, 解密时,需要传入相同的标识信息 materialDesc := make(map[string]string) materialDesc["desc"] = "" // 创建KMS客户端 kmsclient, _ := coscrypto.NewKMSClient(c.GetCredential(), "ap-guangzhou") // 创建KMS主加密密钥,标识信息和主密钥一一对应 kmsID := os.Getenv("KMSID") masterCipher, _ := coscrypto.CreateMasterKMS(kmsclient, kmsID, materialDesc) // 创建加密客户端 client := coscrypto.NewCryptoClient(c, masterCipher) contentLength := 1024*1024*10 + 1 originData := make([]byte, contentLength) _, err := rand.Read(originData) f := bytes.NewReader(originData) // 加密上传 _, err = client.Object.Put(context.Background(), name, f, nil) log_status(err) math_rand.Seed(time.Now().UnixNano()) rangeStart := math_rand.Intn(contentLength) rangeEnd := rangeStart + math_rand.Intn(contentLength-rangeStart) opt := &cos.ObjectGetOptions{ Range: fmt.Sprintf("bytes=%v-%v", rangeStart, rangeEnd), } // 解密下载 resp, err := client.Object.Get(context.Background(), name, opt) log_status(err) defer resp.Body.Close() decryptedData, _ := ioutil.ReadAll(resp.Body) if bytes.Compare(decryptedData, originData[rangeStart:rangeEnd+1]) != 0 { fmt.Println("Error: encryptedData != originData") } } func simple_put_object_from_file() { u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") b := &cos.BaseURL{BucketURL: u} c := cos.NewClient(b, &http.Client{ Transport: &cos.AuthorizationTransport{ SecretID: os.Getenv("COS_SECRETID"), SecretKey: os.Getenv("COS_SECRETKEY"), Transport: &debug.DebugRequestTransport{ RequestHeader: true, RequestBody: false, ResponseHeader: true, ResponseBody: false, }, }, }) // Case1 上传对象 name := "test/example1" fmt.Println("============== simple_put_object_from_file ======================") // 该标识信息唯一确认一个主加密密钥, 解密时,需要传入相同的标识信息 materialDesc := make(map[string]string) materialDesc["desc"] = "" // 创建KMS客户端 kmsclient, _ := coscrypto.NewKMSClient(c.GetCredential(), "ap-guangzhou") // 创建KMS主加密密钥,标识信息和主密钥一一对应 kmsID := os.Getenv("KMSID") masterCipher, _ := coscrypto.CreateMasterKMS(kmsclient, kmsID, materialDesc) // 创建加密客户端 client := coscrypto.NewCryptoClient(c, masterCipher) filepath := "test" fd, err := os.Open(filepath) log_status(err) defer fd.Close() m := md5.New() io.Copy(m, fd) originDataMD5 := m.Sum(nil) // 加密上传 _, err = client.Object.PutFromFile(context.Background(), name, filepath, nil) log_status(err) // 解密下载 _, err = client.Object.GetToFile(context.Background(), name, "./test.download", nil) log_status(err) fd, err = os.Open("./test.download") log_status(err) defer fd.Close() m = md5.New() io.Copy(m, fd) decryptedDataMD5 := m.Sum(nil) if bytes.Compare(decryptedDataMD5, originDataMD5) != 0 { fmt.Println("Error: encryptedData != originData") } } func multi_put_object() { u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") b := &cos.BaseURL{BucketURL: u} c := cos.NewClient(b, &http.Client{ Transport: &cos.AuthorizationTransport{ SecretID: os.Getenv("COS_SECRETID"), SecretKey: os.Getenv("COS_SECRETKEY"), Transport: &debug.DebugRequestTransport{ RequestHeader: true, RequestBody: false, ResponseHeader: true, ResponseBody: false, }, }, }) // Case1 上传对象 name := "test/example1" fmt.Println("============== multi_put_object ======================") // 该标识信息唯一确认一个主加密密钥, 解密时,需要传入相同的标识信息 materialDesc := make(map[string]string) materialDesc["desc"] = "" // 创建KMS客户端 kmsclient, _ := coscrypto.NewKMSClient(c.GetCredential(), "ap-guangzhou") // 创建KMS主加密密钥,标识信息和主密钥一一对应 kmsID := os.Getenv("KMSID") masterCipher, _ := coscrypto.CreateMasterKMS(kmsclient, kmsID, materialDesc) // 创建加密客户端 client := coscrypto.NewCryptoClient(c, masterCipher) contentLength := int64(1024*1024*10 + 1) originData := make([]byte, contentLength) _, err := rand.Read(originData) log_status(err) // 分块上传 cryptoCtx := coscrypto.CryptoContext{ DataSize: contentLength, // 每个分块需要16字节对齐 PartSize: (contentLength / 16 / 3) * 16, } v, _, err := client.Object.InitiateMultipartUpload(context.Background(), name, nil, &cryptoCtx) log_status(err) // 切分数据 chunks, _, err := cos.SplitSizeIntoChunks(contentLength, cryptoCtx.PartSize) log_status(err) optcom := &cos.CompleteMultipartUploadOptions{} for _, chunk := range chunks { opt := &cos.ObjectUploadPartOptions{ ContentLength: chunk.Size, } f := bytes.NewReader(originData[chunk.OffSet : chunk.OffSet+chunk.Size]) resp, err := client.Object.UploadPart(context.Background(), name, v.UploadID, chunk.Number, f, opt, &cryptoCtx) log_status(err) optcom.Parts = append(optcom.Parts, cos.Object{ PartNumber: chunk.Number, ETag: resp.Header.Get("ETag"), }) } _, _, err = client.Object.CompleteMultipartUpload(context.Background(), name, v.UploadID, optcom) log_status(err) resp, err := client.Object.Get(context.Background(), name, nil) log_status(err) defer resp.Body.Close() decryptedData, _ := ioutil.ReadAll(resp.Body) if bytes.Compare(decryptedData, originData) != 0 { fmt.Println("Error: encryptedData != originData") } } func multi_put_object_from_file() { u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") b := &cos.BaseURL{BucketURL: u} c := cos.NewClient(b, &http.Client{ Transport: &cos.AuthorizationTransport{ SecretID: os.Getenv("COS_SECRETID"), SecretKey: os.Getenv("COS_SECRETKEY"), Transport: &debug.DebugRequestTransport{ RequestHeader: true, RequestBody: false, ResponseHeader: true, ResponseBody: false, }, }, }) // Case1 上传对象 name := "test/example1" fmt.Println("============== multi_put_object_from_file ======================") // 该标识信息唯一确认一个主加密密钥, 解密时,需要传入相同的标识信息 materialDesc := make(map[string]string) materialDesc["desc"] = "" // 创建KMS客户端 kmsclient, _ := coscrypto.NewKMSClient(c.GetCredential(), "ap-guangzhou") // 创建KMS主加密密钥,标识信息和主密钥一一对应 kmsID := os.Getenv("KMSID") masterCipher, _ := coscrypto.CreateMasterKMS(kmsclient, kmsID, materialDesc) // 创建加密客户端 client := coscrypto.NewCryptoClient(c, masterCipher) filepath := "test" stat, err := os.Stat(filepath) log_status(err) contentLength := stat.Size() // 分块上传 cryptoCtx := coscrypto.CryptoContext{ DataSize: contentLength, // 每个分块需要16字节对齐 PartSize: (contentLength / 16 / 3) * 16, } // 切分数据 _, chunks, _, err := cos.SplitFileIntoChunks(filepath, cryptoCtx.PartSize) log_status(err) // init mulitupload v, _, err := client.Object.InitiateMultipartUpload(context.Background(), name, nil, &cryptoCtx) log_status(err) // part upload optcom := &cos.CompleteMultipartUploadOptions{} for _, chunk := range chunks { fd, err := os.Open(filepath) log_status(err) opt := &cos.ObjectUploadPartOptions{ ContentLength: chunk.Size, } fd.Seek(chunk.OffSet, os.SEEK_SET) resp, err := client.Object.UploadPart(context.Background(), name, v.UploadID, chunk.Number, io.LimitReader(fd, chunk.Size), opt, &cryptoCtx) log_status(err) optcom.Parts = append(optcom.Parts, cos.Object{ PartNumber: chunk.Number, ETag: resp.Header.Get("ETag"), }) } // complete upload _, _, err = client.Object.CompleteMultipartUpload(context.Background(), name, v.UploadID, optcom) log_status(err) _, err = client.Object.GetToFile(context.Background(), name, "test.download", nil) log_status(err) } func main() { simple_put_object() simple_put_object_from_file() multi_put_object() multi_put_object_from_file() }