You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
305 lines
9.4 KiB
305 lines
9.4 KiB
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"] = "<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 ======================")
|
|
// 该标识信息唯一确认一个主加密密钥, 解密时,需要传入相同的标识信息
|
|
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 ======================")
|
|
// 该标识信息唯一确认一个主加密密钥, 解密时,需要传入相同的标识信息
|
|
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: (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"] = "<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: (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()
|
|
}
|