|
|
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 cos_max(x, y int64) int64 { if x > y { return x } return y }
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 ======================") // 该标识信息唯一确认一个主加密密钥, 解密时,需要传入相同的标识信息
// KMS加密时,该信息设置成EncryptionContext,最大支持1024字符,如果Encrypt指定了该参数,则在Decrypt 时需要提供同样的参数
materialDesc := make(map[string]string) //materialDesc["desc"] = "material information of your master encrypt key"
// 创建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 ======================") // 该标识信息唯一确认一个主加密密钥, 解密时,需要传入相同的标识信息
// KMS加密时,该信息设置成EncryptionContext,最大支持1024字符,如果Encrypt指定了该参数,则在Decrypt 时需要提供同样的参数
materialDesc := make(map[string]string) //materialDesc["desc"] = "material information of your master encrypt key"
// 创建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 ======================") // 该标识信息唯一确认一个主加密密钥, 解密时,需要传入相同的标识信息
// KMS加密时,该信息设置成EncryptionContext,最大支持1024字符,如果Encrypt指定了该参数,则在Decrypt 时需要提供同样的参数
materialDesc := make(map[string]string) //materialDesc["desc"] = "material information of your master encrypt key"
// 创建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: cos_max(1024*1024, (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 ======================") // 该标识信息唯一确认一个主加密密钥, 解密时,需要传入相同的标识信息
// KMS加密时,该信息设置成EncryptionContext,最大支持1024字符,如果Encrypt指定了该参数,则在Decrypt 时需要提供同样的参数
materialDesc := make(map[string]string) //materialDesc["desc"] = "material information of your master encrypt key"
// 创建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: cos_max(1024*1024, (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, cos.LimitReadCloser(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() }
|