tencent cloud

All product documents
Cloud Object Storage
Client-Side Encryption
Last updated: 2024-02-02 15:51:37
Client-Side Encryption
Last updated: 2024-02-02 15:51:37

Overview

The Go SDK supports client-side encryption. Files can be encrypted before the upload and decrypted during the download. Client-side encryption is suitable for users who store sensitive data.
Client-side encryption supports: KMS managed keys: You can provide the ID of your KMS CMK to the SDK. To use this type of keys, the KMS service needs to be activated. For more information, see Key Management Service.

Overview

When you copy or migrate encrypted data, note that you should ensure the integrity and accuracy of the cryptographic metadata. If any encrypted data cannot be decoded due to cryptographic metadata loss/corruption caused by your inappropriate maintenance, you shall bear all losses and consequences arising from it.

Encryption upon Upload

Before each upload, a random symmetric key will be generated, which will be encrypted using the KMS service. KMS will then Base64-encode the key and store it in the object metadata.
1. During the upload, the file is encrypted in memory using the AES256 algorithm.

Decryption upon Download

Get the necessary encryption information from the metadata of the file, Base64-decode it, and then decrypt it using the KMS or customer managed key to get the encryption key at upload.
1. Use the resulting key to decrypt the downloaded input stream using AES256.

Sample Request

For the complete sample, please see Client-Side Encryption - Full Demo of KMS Encryption.

Sample 1. Simple upload and download

// Create the original client.
u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("SECRETID"), // User `SecretId`. We recommend that you use a sub-account key and follow the principle of least privilege to reduce risks. For information about how to obtain a sub-account key, visit https://cloud.tencent.com/document/product/598/37140.
SecretKey: os.Getenv("SECRETKEY"), // User `SecretKey`. We recommend you use a sub-account key and follow the principle of least privilege to reduce risks. For information about how to obtain a sub-account key, visit https://cloud.tencent.com/document/product/598/37140.
},
})

// Sample 1. Upload an object.
name := "test/example"

// An identifier that determines a unique master encryption key, which also needs to be passed in during decryption.
// During KMS encryption, set it to EncryptionContext. Up to 1,024 characters are supported. If a value is specified in Encrypt, the same value should be passed to Decrypt.
materialDesc := make(map[string]string)
//materialDesc["desc"] = "material information of your master encrypt key"

// Create a KMS client.
kmsclient, _ := coscrypto.NewKMSClient(c.GetCredential(), "ap-guangzhou")
// Create the KMS master encryption key, whose identifier, materialDesc, should correspond to the master encryption key one to one.
kmsID := os.Getenv("KMSID")
masterCipher, _ := coscrypto.CreateMasterKMS(kmsclient, kmsID, materialDesc)
// Create an encryption client.
client := coscrypto.NewCryptoClient(c, masterCipher)

contentLength := 1024*1024*10 + 1
originData := make([]byte, contentLength)
_, err := rand.Read(originData)
f := bytes.NewReader(originData)
// Encrypt data upon upload.
_, err = client.Object.Put(context.Background(), name, f, nil)
log_status(err)

// Decrypt data upon download.
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[rangeStart:rangeEnd+1]) != 0 {
fmt.Println("Error: encryptedData != originData")
}

Sample 2. Uploading and downloading an object

// Create the original client.
u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("SECRETID"), // User `SecretId`. We recommend that you use a sub-account key and follow the principle of least privilege to reduce risks. For information about how to obtain a sub-account key, visit https://cloud.tencent.com/document/product/598/37140.
SecretKey: os.Getenv("SECRETKEY"), // User `SecretKey`. We recommend you use a sub-account key and follow the principle of least privilege to reduce risks. For information about how to obtain a sub-account key, visit https://cloud.tencent.com/document/product/598/37140.
},
})

// Sample 1. Upload an object.
name := "test/example"

// An identifier that determines a unique master encryption key, which also needs to be passed in during decryption.
// During KMS encryption, set it to EncryptionContext. Up to 1,024 characters are supported. If a value is specified in Encrypt, the same value should be passed to Decrypt.
materialDesc := make(map[string]string)
//materialDesc["desc"] = "material information of your master encrypt key"

// Create a KMS client.
kmsclient, _ := coscrypto.NewKMSClient(c.GetCredential(), "ap-guangzhou")
// Create the KMS master encryption key, whose identifier, materialDesc, should correspond to the master encryption key one to one.
kmsID := os.Getenv("KMSID")
masterCipher, _ := coscrypto.CreateMasterKMS(kmsclient, kmsID, materialDesc)
// Create an encryption client.
client := coscrypto.NewCryptoClient(c, masterCipher)

// Encrypt data upon upload.
_, err = client.Object.PutFromFile(context.Background(), name, filepath, nil)
if err != nil{
//ERROR
}

// Decrypt data upon download.
_, err = client.Object.GetToFile(context.Background(), name, "./test.download", nil)
if err != nil{
//ERROR
}

Sample 3. Multipart upload

// Create the original client.
u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("SECRETID"), // User `SecretId`. We recommend that you use a sub-account key and follow the principle of least privilege to reduce risks. For information about how to obtain a sub-account key, visit https://cloud.tencent.com/document/product/598/37140.
SecretKey: os.Getenv("SECRETKEY"), // User `SecretKey`. We recommend you use a sub-account key and follow the principle of least privilege to reduce risks. For information about how to obtain a sub-account key, visit https://cloud.tencent.com/document/product/598/37140.
},
})

// Sample 1. Upload an object.
name := "test/example"

// An identifier that determines a unique master encryption key, which also needs to be passed in during decryption.
// During KMS encryption, set it to EncryptionContext. Up to 1,024 characters are supported. If a value is specified in Encrypt, the same value should be passed to Decrypt.
materialDesc := make(map[string]string)
//materialDesc["desc"] = "material information of your master encrypt key"

// Create a KMS client.
kmsclient, _ := coscrypto.NewKMSClient(c.GetCredential(), "ap-guangzhou")
// Create the KMS master encryption key, whose identifier, materialDesc, should correspond to the master encryption key one to one.
kmsID := os.Getenv("KMSID")
masterCipher, _ := coscrypto.CreateMasterKMS(kmsclient, kmsID, materialDesc)
// Create an encryption client.
client := coscrypto.NewCryptoClient(c, masterCipher)

filepath := "test"
stat, err := os.Stat(filepath)
if err !- nil {
// ERROR
}
contentLength := stat.Size()

// Multipart upload
// Each part should be aligned to 16 bytes and not smaller than 1 MB.
partSize := (contentLength / 16 / 3) * 16
if partSize < int64(1024*1024) {
partSize = int64(1024*1024)
}
cryptoCtx := coscrypto.CryptoContext{
DataSize: contentLength,
// Each part should be aligned to 16 bytes.
PartSize: partSize,
}
// Split the data.
_, chunks, _, err := cos.SplitFileIntoChunks(filepath, cryptoCtx.PartSize)
if err !- nil {
// ERROR
}

// init mulitupload
v, _, err := client.Object.InitiateMultipartUpload(context.Background(), name, nil, &cryptoCtx)
if err !- nil {
// ERROR
}

// part upload
optcom := &cos.CompleteMultipartUploadOptions{}
for _, chunk := range chunks {
fd, err := os.Open(filepath)
if err !- nil {
// ERROR
}
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)
if err !- nil {
// ERROR
}
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)
if err !- nil {
// ERROR
}

_, err = client.Object.GetToFile(context.Background(), name, "test.download", nil)
if err !- nil {
// ERROR
}
Was this page helpful?
You can also Contact Sales or Submit a Ticket for help.
Yes
No

Feedback

Contact Us

Contact our sales team or business advisors to help your business.

Technical Support

Open a ticket if you're looking for further assistance. Our Ticket is 7x24 avaliable.

7x24 Phone Support
Hong Kong, China
+852 800 906 020 (Toll Free)
United States
+1 844 606 0804 (Toll Free)
United Kingdom
+44 808 196 4551 (Toll Free)
Canada
+1 888 605 7930 (Toll Free)
Australia
+61 1300 986 386 (Toll Free)
EdgeOne hotline
+852 300 80699
More local hotlines coming soon