Client-side encryption is used to encrypt objects on the local client before they are uploaded to Object Storage Service (OSS).

Disclaimer

  • When you use client-side encryption, you must ensure the integrity and validity of the customer master key (CMK). If the CMK is incorrectly used or lost due to improper maintenance, you will be held responsible for all losses and consequences caused by decryption failures.
  • When you copy or migrate encrypted data, you must ensure the integrity and validity of the object metadata related to client-side encryption. If the encrypted metadata is incorrectly used or lost due to improper maintenance, you will be held responsible for all losses and consequences caused by decryption failures.

Background information

In client-side encryption, a random data key is generated for each object to perform symmetric encryption on the object. The client uses a CMK to encrypt the random data key. The encrypted data key is uploaded as a part of the object metadata and stored in the OSS server. When an encrypted object is downloaded, the client uses the CMK to decrypt the random data key and then uses the data key to decrypt the object. To ensure data security, the CMK is used only on the client and is not transmitted over the network or stored in the server.

Notice
  • Client-side encryption supports multipart upload for objects larger than 5 GB in size. When you use multipart upload to upload an object, you must specify the total size of the object and the size of each part. The size of each part except for the last part must be the same and be a multiple of 16 bytes.
  • After you upload objects encrypted on the client, object metadata related to client-side encryption is protected and cannot be modified by calling CopyObject.

Encryption methods

You can use CMKs managed in one of the following methods:

  • Use KMS-managed CMKs

    When you use a CMK stored in Key Management Service (KMS) for client-side encryption, you must send the CMK ID to OSS SDK for Python.

  • Use RSA-based CMKs managed by yourself

    When you use a CMK managed by yourself for client-side encryption, you must send the public key and the private key of your CMK to OSS SDK for Python as parameters.

You can use the preceding methods to prevent data leaks and protect your data on the client. Even if your data is leaked, the data cannot be decrypted by other users.

Object metadata related to client-side encryption

Parameter Description Required
x-oss-meta-client-side-encryption-key The encrypted data key. The encrypted data key is a string encrypted by using a customer master key (CMK) and encoded in Base64. Yes
x-oss-meta-client-side-encryption-start The initial value generated randomly for data encryption. The initial value is a string encrypted by using a CMK and encoded in Base64. Yes
x-oss-meta-client-side-encryption-cek-alg The algorithm used to encrypt data. Yes
x-oss-meta-client-side-encryption-wrap-alg The algorithm used to encrypt the data key. Yes
x-oss-meta-client-side-encryption-matdesc The description of the CMK in JSON format.
Warning We recommend that you configure a description for each CMK and store the mapping relationship between the CMK and its description. A CMK without a specified description cannot be replaced.
No
x-oss-meta-client-side-encryption-unencrypted-content-length The length of data before encryption. If Content-Length is not specified, this parameter is not generated. No
x-oss-meta-client-side-encryption-unencrypted-content-md5 The MD5 hash of the data before encryption. if Content-MD5 is not specified, this parameter is not generated. No
x-oss-meta-client-side-encryption-data-size The total size of the object to encrypt for multipart upload when init_multipart is called. Yes (for multipart upload)
x-oss-meta-client-side-encryption-part-size The size of each part to encrypt for multipart upload when init_multipart is called.
Note The size of each part must be a multiple of 16 bytes.
Yes (for multipart upload)

The following examples show how to use customer-managed CMKs (RSA-based) to encrypt or decrypt objects in different scenarios.

Encrypt objects to be uploaded from memory

The following code provides an example on how to use an RSA-based CMK managed by yourself to encrypt an object to upload from memory:

#include <alibabacloud/oss/OssEncryptionClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account that is used to access OSS. */
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";

    /* Specify the CMK and the description. */
    std::string RSAPublicKey = "your rsa public key";
    std::string RSAPrivateKey = "your rsa private key";
    std::map<std::string, std::string> desc;
    desc["comment"] = "your comment";

    /* Initialize resources such as network resources. */
    InitializeSdk();
    ClientConfiguration conf;
    CryptoConfiguration cryptoConf;
    auto materials = std::make_shared<SimpleRSAEncryptionMaterials>(RSAPublicKey, RSAPrivateKey, desc);
    OssEncryptionClient client(Endpoint, AccessKeyId, AccessKeySecret, conf, materials, cryptoConf);
    std::shared_ptr<std::iostream> content = std::make_shared<std::stringstream>();
    *content << "Thank you for using Aliyun Object Storage Service!";
    PutObjectRequest request(BucketName, ObjectName, content);
    /* Upload the object. */
    auto outcome = client.PutObject(request);
    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "PutObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }
    /* Release resources such as network resources. */
    ShutdownSdk();
    return 0;
}

Encrypt local files to be uploaded to OSS

The following code provides an example on how to use an RSA-based CMK managed by yourself to encrypt the local file that you want to upload to OSS:

#include <alibabacloud/oss/OssEncryptionClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account that is used to access OSS. */
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";

    /* Specify the CMK and the description. */
    std::string RSAPublicKey = "your rsa public key";
    std::string RSAPrivateKey = "your rsa private key";
    std::map<std::string, std::string> desc;
    desc["comment"] = "your comment";

    /* Initialize resources such as network resources. */
    InitializeSdk();
    ClientConfiguration conf;
    CryptoConfiguration cryptoConf;
    auto materials = std::make_shared<SimpleRSAEncryptionMaterials>(RSAPublicKey, RSAPrivateKey, desc);
    OssEncryptionClient client(Endpoint, AccessKeyId, AccessKeySecret, conf, materials, cryptoConf);
    /* Upload the object. */
    auto outcome = client.PutObject(BucketName, ObjectName, "yourLocalFilename");
    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "PutObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }
    /* Release resources such as network resources. */
    ShutdownSdk();
    return 0;
}

Encrypt objects to be uploaded by using resumable upload

The following code provides an example on how to use an RSA-based CMK managed by yourself to encrypt an object when you upload the object by using resumable upload:

#include <alibabacloud/oss/OssEncryptionClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account that is used to access OSS. */
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";
    /* Specify the full path of the local file. Example: D:\\localpath\\examplefile.txt. By default, if you do not specify the full path of a local file, the local file is uploaded from the path of the project to which the sample program belongs. */
    std::string UploadFilePath = "D:\\localpath\\examplefile.txt";
    /* Specify the checkpoint file that records the results of the multipart upload task. This file stores information about the upload progress of each part. If a part fails to be uploaded, the task can be continued based on the progress recorded in the checkpoint file. After the local file is uploaded, the checkpoint file is deleted. */
    /* By default, if you do not specify this parameter, the checkpoint file shares the same directory as the local file that you want to upload. */
    std::string CheckpointFilePath = "yourCheckpointFilepath"

    /* Specify the CMK and the description. */
    std::string RSAPublicKey = "your rsa public key";
    std::string RSAPrivateKey = "your rsa private key";
    std::map<std::string, std::string> desc;
    desc["comment"] = "your comment";

    /* Initialize resources such as network resources. */
    InitializeSdk();
    ClientConfiguration conf;
    CryptoConfiguration cryptoConf;
    auto materials = std::make_shared<SimpleRSAEncryptionMaterials>(RSAPublicKey, RSAPrivateKey, desc);
    OssEncryptionClient client(Endpoint, AccessKeyId, AccessKeySecret, conf, materials, cryptoConf);

    /* Start the resumable upload. */
    UploadObjectRequest request(BucketName, ObjectName, UploadFilePath, CheckpointFilePath);
    auto outcome = client.ResumableUploadObject(request);

    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "ResumableUploadObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }
    /* Release resources such as network resources. */
    ShutdownSdk();
    return 0;
}

Encrypt objects to be uploaded by using multipart upload

The following code provides an example on how to use an RSA-based CMK managed by yourself to encrypt an object when you upload the object by using multipart upload:

#include <alibabacloud/oss/OssEncryptionClient.h>
#include <fstream>
using namespace AlibabaCloud::OSS;

static int64_t getFileSize(const std::string& file)
{
    std::fstream f(file, std::ios::in | std::ios::binary);
    f.seekg(0, f.end);
    int64_t size = f.tellg();
    f.close();
    return size;
}

int main(void)
{
    /* Initialize the information about the account that is used to access OSS. */
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";
    std::string fileToUpload = "yourLocalFilename";

    /* Specify the CMK and the description. */
    std::string RSAPublicKey = "your rsa public key";
    std::string RSAPrivateKey = "your rsa private key";
    std::map<std::string, std::string> desc;
    desc["comment"] = "your comment";

    /* Initialize resources such as network resources. */
    InitializeSdk();
    ClientConfiguration conf;
    CryptoConfiguration cryptoConf;
    auto materials = std::make_shared<SimpleRSAEncryptionMaterials>(RSAPublicKey, RSAPrivateKey, desc);
    OssEncryptionClient client(Endpoint, AccessKeyId, AccessKeySecret, conf, materials, cryptoConf);

    /* Initialize the context for encryption in multipart upload. */
    /* The part size must be an integral multiple of 16 bytes. */
    int64_t partSize = 100 * 1024;
    auto fileSize = getFileSize(fileToUpload);
    MultipartUploadCryptoContext cryptoCtx;
    cryptoCtx.setPartSize(partSize);
    cryptoCtx.setDataSize(fileSize);

    /* Initiate a multipart upload task. */
    InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
    auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest, cryptoCtx);
    auto uploadId = uploadIdResult.result().UploadId();
    PartList partETagList;
    int partCount = static_cast<int> (fileSize / partSize);
    /* Calculate the number of parts. */
    if (fileSize % partSize != 0)  {
        partCount++;
    }
    /* Upload each part sequentially. */
    for (int i = 1; i <= partCount; i++) {
        auto skipBytes = partSize * (i - 1);
        auto size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
        std::shared_ptr<std::iostream> content = std::make_shared<std::fstream>(fileToUpload, std::ios::in|std::ios::binary);
        content->seekg(skipBytes, std::ios::beg);
        UploadPartRequest uploadPartRequest(BucketName, ObjectName, content);
        uploadPartRequest.setContentLength(size);
        uploadPartRequest.setUploadId(uploadId);
        uploadPartRequest.setPartNumber(i);
        auto uploadPartOutcome = client.UploadPart(uploadPartRequest, cryptoCtx);
        if (uploadPartOutcome.isSuccess()) {
            Part part(i, uploadPartOutcome.result().ETag());
            partETagList.push_back(part);
        }
        else {
            std::cout << "uploadPart fail" <<
            ",code:" << uploadPartOutcome.error().Code() <<
            ",message:" << uploadPartOutcome.error().Message() <<
            ",requestId:" << uploadPartOutcome.error().RequestId() << std::endl;
        }
    }
    /* Complete the multipart upload task. */
    CompleteMultipartUploadRequest request(BucketName, ObjectName);
    request.setUploadId(uploadId);
    request.setPartList(partETagList);
    auto outcome = client.CompleteMultipartUpload(request, cryptoCtx);
    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "CompleteMultipartUpload fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }
    /* Release resources such as network resources. */
    ShutdownSdk();
    return 0;
}

Decrypt objects to be downloaded to a local path

The following code provides an example on how to use an RSA-based CMK managed by yourself to decrypt an object when you download the object to a local path:

#include <alibabacloud/oss/OssEncryptionClient.h>
#include <fstream>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account that is used to access OSS. */
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";
    /* Download the object to the local path D:\\localpath and save the downloaded object as a local file named examplefile.txt. If a file that has the same name already exists, the downloaded object overwrites the file. Otherwise, a new file is created. */
    /* If you do not specify the local path, the downloaded object is saved to the path of the project to which the sample program belongs. */
    std::string FileNametoSave = "D:\\localpath\\examplefile.txt";

    /* Specify the CMK and the description. */
    std::string RSAPublicKey = "your rsa public key";
    std::string RSAPrivateKey = "your rsa private key";
    std::map<std::string, std::string> desc;
    desc["comment"] = "your comment";

    /* Initialize resources such as network resources. */
    InitializeSdk();
    ClientConfiguration conf;
    CryptoConfiguration cryptoConf;
    auto materials = std::make_shared<SimpleRSAEncryptionMaterials>(RSAPublicKey, RSAPrivateKey, desc);

    /* To decrypt content that is encrypted by using other CMKs, you must provide the information about the CMKs. */
    //std::string RSAPublicKey2 =  "your rsa public key";
    //std::string RSAPrivateKey2 = "your rsa private key";
    //std::map<std::string, std::string> desc2;
    //desc2["comment"] = "your comment";
    //materials.addEncryptionMaterial(RSAPublicKey2, RSAPrivateKey2, desc2);

    OssEncryptionClient client(Endpoint, AccessKeyId, AccessKeySecret, conf, materials, cryptoConf);

    /* Download the object and save the downloaded object as the local file. */
    GetObjectRequest request(BucketName, ObjectName);
    request.setResponseStreamFactory([=]() {return std::make_shared<std::fstream>(FileNametoSave, std::ios_base::out | std::ios_base::in | std::ios_base::trunc| std::ios_base::binary); });
    auto outcome = client.GetObject(request);
    if (outcome.isSuccess()) {    
        std::cout << "GetObjectToFile success" << outcome.result().Metadata().ContentLength() << std::endl;
    }
    else {
        /* Handle exceptions. */
        std::cout << "GetObjectToFile fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }
    /* Release resources such as network resources. */
    ShutdownSdk();
    return 0;
}

Decrypt objects to be downloaded to the local memory

The following code provides an example on how to use an RSA-based CMK managed by yourself to decrypt an object when you download the object to the local memory:

#include <alibabacloud/oss/OssEncryptionClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account that is used to access OSS. */
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: destfolder/exampleobject.txt. */
    std::string ObjectName = "yourObjectName";
    std::string RSAPublicKey = "your rsa public key";
    std::string RSAPrivateKey = "your rsa private key";

    /* Specify the CMK and the description. */
    std::string RSAPublicKey = "your rsa public key";
    std::string RSAPrivateKey = "your rsa private key";
    std::map<std::string, std::string> desc;
    desc["comment"] = "your comment";

    /* Initialize resources such as network resources. */
    InitializeSdk();
    ClientConfiguration conf;
    CryptoConfiguration cryptoConf;
    auto materials = std::make_shared<SimpleRSAEncryptionMaterials>(RSAPublicKey, RSAPrivateKey, desc);

    /* To decrypt content that is encrypted by using other CMKs, you must provide the information about the CMKs. */
    //std::string RSAPublicKey2 =  "your rsa public key";
    //std::string RSAPrivateKey2 = "your rsa private key";
    //std::map<std::string, std::string> desc2;
    //desc2["comment"] = "your comment";
    //materials.addEncryptionMaterial(RSAPublicKey2, RSAPrivateKey2, desc2);

    OssEncryptionClient client(Endpoint, AccessKeyId, AccessKeySecret, conf, materials, cryptoConf);

    /* Download the object to the local memory. */
    GetObjectRequest request(BucketName, ObjectName);
    auto outcome = client.GetObject(request);
    if (outcome.isSuccess()) {    
      std::cout << "getObjectToBuffer" << " success, Content-Length:" << outcome.result().Metadata().ContentLength() << std::endl;
        /* Display the downloaded content. */
        std::string content;
        *(outcome.result().Content()) >> content;
        std::cout << "getObjectToBuffer" << "content:" << content << std::endl; 
    }
    else {
        /* Handle exceptions. */
        std::cout << "getObjectToBuffer fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }

    /* Release resources such as network resources. */
    ShutdownSdk();
    return 0;
}

Decrypt objects to be downloaded by using range download

The following code provides an example on how to use an RSA-based CMK managed by yourself to decrypt an object to download by range:

#include <alibabacloud/oss/OssEncryptionClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account that is used to access OSS. */
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: destfolder/exampleobject.txt. */
    std::string ObjectName = "yourObjectName";

    /* Specify the CMK and the description. */
    std::string RSAPublicKey = "your rsa public key";
    std::string RSAPrivateKey = "your rsa private key";
    std::map<std::string, std::string> desc;
    desc["comment"] = "your comment";

    /* Initialize resources such as network resources. */
    InitializeSdk();
    ClientConfiguration conf;
    CryptoConfiguration cryptoConf;
    auto materials = std::make_shared<SimpleRSAEncryptionMaterials>(RSAPublicKey, RSAPrivateKey, desc);

    /* To decrypt content that is encrypted by using other CMKs, you must provide the information about the CMKs. */
    //std::string RSAPublicKey2 =  "your rsa public key";
    //std::string RSAPrivateKey2 = "your rsa private key";
    //std::map<std::string, std::string> desc2;
    //desc2["comment"] = "your comment";
    //materials.addEncryptionMaterial(RSAPublicKey2, RSAPrivateKey2, desc2);

    OssEncryptionClient client(Endpoint, AccessKeyId, AccessKeySecret, conf, materials, cryptoConf);

    /* Specify the download range. */
    GetObjectRequest request(BucketName,  ObjectName);
    request.setRange(0, 1);
    auto outcome = client.GetObject(request);
    if (!outcome.isSuccess ()) {    
        /* Handle exceptions. */
        std::cout << "getObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
         return -1;  
    }

    /* Release resources such as network resources. */
    ShutdownSdk();
    return 0;
}

Decrypt objects to be downloaded by using resumable download

The following code provides an example on how to use an RSA-based CMK managed by yourself to decrypt an object when you download the object by using resumable download:

#include <alibabacloud/oss/OssEncryptionClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize the information about the account that is used to access OSS.
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to access OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";
    /* Specify the full path of the object. The full path of the object cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    std::string ObjectName = "exampledir/exampleobject.txt";
    /* Download the object to the local path D:\\localpath and save the downloaded object as a local file named examplefile.txt. If a file that has the same name already exists, the downloaded object overwrites the file. Otherwise, a new file is created. */
    /* If you do not specify the local path, the downloaded object is saved to the path of the project to which the sample program belongs. */
    std::string DownloadFilePath = "D:\\localpath\\examplefile.txt";
    /* Specify the full path of the local file. Example: D:\\localpath\\examplefile.txt.dcp. */
    /* After the checkpoint file is generated because the object download is interrupted, you must set the full path of the checkpoint file only when you want to continue the download of the object. After the object is downloaded, the checkpoint file is deleted. */
    std::string CheckpointFilePath = "D:\\localpath\\examplefile.txt.dcp";

    /* Specify the CMK and the description. */
    std::string RSAPublicKey = "your rsa public key";
    std::string RSAPrivateKey = "your rsa private key";
    std::map<std::string, std::string> desc;
    desc["comment"] = "your comment";

    /* Initialize resources such as network resources. */
    InitializeSdk();
    ClientConfiguration conf;
    CryptoConfiguration cryptoConf;
    auto materials = std::make_shared<SimpleRSAEncryptionMaterials>(RSAPublicKey, RSAPrivateKey, desc);

    /* To decrypt content that is encrypted by using other CMKs, you must provide the information about the CMKs. */
    //std::string RSAPublicKey2 =  "your rsa public key";
    //std::string RSAPrivateKey2 = "your rsa private key";
    //std::map<std::string, std::string> desc2;
    //desc2["comment"] = "your comment";
    //materials.addEncryptionMaterial(RSAPublicKey2, RSAPrivateKey2, desc2);

    OssEncryptionClient client(Endpoint, AccessKeyId, AccessKeySecret, conf, materials, cryptoConf);

    /* Start the resumable download. */
    DownloadObjectRequest request(BucketName, ObjectName, DownloadFilePath, CheckpointFilePath);
    auto outcome = client.ResumableDownloadObject(request);

    if (!outcome.isSuccess()) {
        /* Handle exceptions. */
        std::cout << "ResumableDownloadObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }
    /* Release resources such as network resources. */
    ShutdownSdk();
    return 0;
}