If client-side encryption is performed, objects are encrypted on the local client before they are uploaded to OSS.

Disclaimer

  • When you use client-side encryption, you must ensure the integrity and validity of the 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 encrypted metadata. 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 object is downloaded, the client uses the CMK to decrypt the random data key and then uses the data key to decrypt the object. The CMK is used only on the client and is not transmitted over the network or stored in the server, which secures data.

Notice
  • Client-side encryption can be performed only on objects smaller than 5 GB.
  • After performing client-side encryption on an object and uploading the object, do not call update_object_meta or CopyObject provided by OSS SDK for Python to modify the object metadata.

Encryption method

You can use CMKs managed in either of the following ways:

  • Use CMKs managed by KMS

    When you use a CMK stored in KMS for client-side encryption, you must send the CMK ID to the SDK.

  • Use CMKs managed by yourself (RSA)

    When you use your own CMK to perform client-side encryption, you must send your CMK and the data key generated by the CMK to the SDK as parameters.

By using the preceding methods, you can prevent data leaks and protect data security on the client. Even if your data leaks, it cannot be decrypted by others.

For more information about client-side encryption, see Client-side encryption in the Developer Guide. For the complete sample code, visit GitHub.

Object metadata related to client-side encryption

Parameter Description Required
x-oss-meta-oss-crypto-key The encrypted data key, which is a string encrypted by using the CMK and encoded in Base64. Yes
x-oss-meta-oss-crypto-start The initial value which is generated randomly for data encryption. The initial value is a string encrypted by using the CMK and encoded in Base64. Yes
x-oss-meta-oss-cek-alg The encryption algorithm used to encrypt data. Valid values: AES, GCM, and NoPadding. Yes
x-oss-meta-oss-wrap-alg The encryption algorithm used to encrypt data keys. Valid values: rsa and kms Yes
x-oss-meta-oss-matdesc The description of the content encryption key (CEK) in JSON format. This parameter does not take effect currently. No
x-oss-meta-unencrypted-content-length The length of data before encryption. This parameter is not generated if Content-Length is not specified. No
x-oss-meta-unencrypted-content-md5 The MD5 hash of the data before encryption. This parameter is not generated if Content-MD5 is not specified. No

Perform client-side encryption in uploads and downloads by using CMKs managed by yourself

You can perform client-side encryption in uploads and downloads by using CMKs managed by yourself. The following code provides an example on how to perform client-side encryption by using CMKs managed by yourself:

# -*- coding: utf-8 -*-
import os
import oss2
from  oss2.crypto import LocalRsaProvider

# Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to log on to OSS, because the account has permissions on all API operations. We recommend that you use your RAM user's credentials to call API operations or perform routine operations and maintenance. To create a RAM user, log on to https://ram.console.aliyun.com.
auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')

# Create a bucket and use CMKs managed by yourself (RSA) to perform client-side encryption. This encryption method only supports uploads and downloads of entire objects.
bucket = oss2.CryptoBucket(auth,'<yourEndpoint>', '<yourBucketName>', crypto_provider=LocalRsaProvider())

key = 'motto.txt'
content = b'a' * 1024 * 1024
filename = 'download.txt'


# Upload an object.
bucket.put_object(key, content, headers={'content-length': str(1024 * 1024)})

# Download an object.
result = bucket.get_object(key)

# Verify the downloaded object.
content_got = b''
for chunk in result:
    content_got += chunk
assert content_got == content

# Download an object to a local file.
result = bucket.get_object_to_file(key, filename)

# Verify the downloaded object.
with open(filename, 'rb') as fileobj:
    assert fileobj.read() == content

os.remove(filename)
			

Perform client-side encryption in uploads and downloads by using CMKs managed by KMS

  • Prerequisites
    1. You have activated the Alibaba Cloud Key Management Service.
    2. A CMK ID has been generated in the region of your bucket.
    3. You have created a custom policy and associate the policy with corresponding users. To create a custom policy, log on to the RAM console and select RAM > Policies > Custom Policy > Create Authorization Policy.

    The following code provides an example on how to create a custom policy:

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "kms:CreateKey",
            "kms:GenerateDataKey",
            "kms:ListKeys",
            "kms:Encrypt",
            "kms:Decrypt"
          ],
          "Resource": [
            "acs:kms:<yourRegion>:<yourloginUserId>:key/*"
          ]
        }
      ]
    }
    					
  • Sample code
    # -*- coding: utf-8 -*-
    import os
    import oss2
    from  oss2.crypto import AliKMSProvider
    
    # Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to log on to OSS, because the account has permissions on all API operations. We recommend that you use your RAM user's credentials to call API operations or perform routine operations and maintenance. To create a RAM user, log on to https://ram.console.aliyun.com.
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    
    # Create a bucket and use CMKs managed by KMS to perform client-side encryption. This encryption method only supports uploads and downloads of entire objects.
    bucket = oss2.CryptoBucket(auth,'<yourEndpoint>', 'liusiman123456',crypto_provider=AliKMSProvider('<yourAccessKeyId>', '<yourAccessKeySecret>', '<yourRegion>', '<yourCMK>', '1234'))
    
    key = 'motto.txt'
    content = b'a' * 1024 * 1024
    filename = 'download.txt'
    
    # Upload an object.
    bucket.put_object(key, content, headers={'content-length': str(1024 * 1024)})
    
    # Download an object.
    result = bucket.get_object(key)
    
    # Verify the downloaded object.
    content_got = b''
    for chunk in result:
        content_got += chunk
    assert content_got == content
    
    # Download an object to a local file.
    result = bucket.get_object_to_file(key, filename)
    
    # Verify the downloaded object.
    with open(filename, 'rb') as fileobj:
        assert fileobj.read() == content
    
    os.remove(filename)