Lorsque le chiffrement côté client est activé, les objets sont chiffrés localement avant d'être téléchargés vers Object Storage Service (OSS). Cette approche renforce la sécurité des données lors de leur transmission et de leur stockage.
Clause de non-responsabilité
Lorsque vous utilisez le chiffrement côté client, vous devez garantir l'intégrité et la validité de la clé principale cliente (CMK). Si la CMK est utilisée de manière incorrecte ou perdue en raison d'une maintenance inadéquate, vous êtes responsable de toutes les pertes et conséquences résultant des échecs de déchiffrement.
Lorsque vous copiez ou migrez des données chiffrées, vous êtes responsable de l'intégrité et de la validité des métadonnées des objets. Si les métadonnées chiffrées sont incorrectes ou perdues en raison d'une maintenance inadéquate, vous êtes responsable de toutes les pertes et conséquences résultant des échecs de déchiffrement des données.
Scénarios
Données hautement sensibles : pour les données contenant des informations extrêmement sensibles, telles que les informations personnelles identifiables (PII), les registres de transactions financières ou les données médicales et de santé, les utilisateurs peuvent chiffrer les données avant qu'elles ne quittent l'environnement local afin de garantir une protection efficace des données originales pendant la transmission.
Exigences de conformité : certaines réglementations spécifiques, comme HIPAA et GDPR, imposent une gestion stricte du chiffrement des données. Le chiffrement côté client répond à ces exigences de conformité, car les CMK sont gérées par les utilisateurs et ne transitent pas par le réseau.
Contrôle des autorisations renforcé : une entreprise ou un développeur souhaite disposer d'un contrôle total sur le processus de chiffrement, y compris la sélection des algorithmes de chiffrement et la gestion des CMK. Le chiffrement côté client garantit que seuls les utilisateurs légalement autorisés peuvent déchiffrer et accéder aux données.
Sécurité de la migration des données entre régions : le chiffrement côté client permet de maintenir les données dans un état chiffré avant et après la migration des données entre régions. Cela améliore la sécurité de la transmission des données sur Internet.
Informations générales
Dans le cadre du chiffrement côté client, une clé de données aléatoire est générée pour chaque objet afin d'effectuer un chiffrement symétrique de celui-ci. Le client utilise une CMK pour chiffrer cette clé de données aléatoire. La clé de données chiffrée est ensuite téléchargée en tant que partie des métadonnées de l'objet et stockée sur le serveur OSS. Lors du téléchargement d'un objet chiffré, le client utilise la CMK pour déchiffrer la clé de données aléatoire, puis utilise la clé de données déchiffrée pour déchiffrer l'objet. Pour garantir la sécurité des données, la CMK est utilisée uniquement sur le client et n'est ni transmise via le réseau ni stockée sur le serveur.
Le chiffrement côté client prend en charge le téléchargement multipartie pour les objets dont la taille est supérieure à 5 Go. Lorsque vous utilisez le téléchargement multipartie pour télécharger un objet, vous devez spécifier la taille totale de l'objet ainsi que la taille de chaque partie. La taille de chaque partie, à l'exception de la dernière, doit être identique et constituer un multiple entier de 16.
Si vous téléchargez un objet chiffré sur un client local, les métadonnées chiffrées de l'objet sont protégées et ne peuvent pas être modifiées en appelant CopyObject.
Vous pouvez utiliser deux types de CMK pour le chiffrement côté client :
Pour consulter l'exemple de code complet, rendez-vous sur GitHub.
Utiliser des CMK gérées par KMS
Si vous utilisez une CMK gérée par Key Management Service (KMS) pour le chiffrement côté client, il vous suffit de spécifier un ID de CMK lors du téléchargement d'un objet. Vous n'avez pas besoin de fournir une clé de données au client de chiffrement. Le schéma suivant illustre le processus de chiffrement.
-
Chiffrer et télécharger un objet
-
Obtenez une clé de données.
Le client utilise l'ID de CMK spécifié pour demander une clé de données à KMS afin de chiffrer un objet. KMS génère une clé aléatoire et renvoie le texte en clair et le texte chiffré de la clé de données.
-
Chiffrez l'objet et téléchargez l'objet chiffré vers OSS.
Le client utilise le texte en clair de la clé de données pour chiffrer l'objet côté client, puis télécharge l'objet chiffré ainsi que le texte chiffré de la clé de données vers OSS.
-
-
Télécharger et déchiffrer un objet
-
Téléchargez un objet.
Le client télécharge un objet chiffré et le texte chiffré de la clé de données depuis OSS.
-
Déchiffrez l'objet.
Le client envoie le texte chiffré de la clé de données et l'ID de CMK correspondant à KMS. KMS utilise la CMK envoyée par le client pour déchiffrer l'objet chiffré et renvoie le texte en clair de la clé de données au client.
-
Le client utilise une clé de données unique pour chiffrer chaque objet à télécharger.
Afin de garantir la sécurité des données, nous vous recommandons de faire tourner ou de mettre à jour régulièrement la CMK.
Vous devez maintenir la relation de correspondance entre les ID de CMK et les objets chiffrés.
Utiliser des CMK gérées par le client
Pour utiliser des CMK gérées par le client dans le cadre du chiffrement côté client, vous devez générer et gérer manuellement les CMK. Vous devez télécharger une CMK symétrique ou asymétrique vers le client de chiffrement pour le chiffrement des objets. Le schéma suivant illustre le processus de chiffrement.
-
Chiffrer et télécharger un objet
Fournissez au client une CMK symétrique ou asymétrique.
Le client utilise la CMK pour générer une clé de données symétrique à usage unique, destinée uniquement au chiffrement de l'objet à télécharger. Le client génère une clé de données aléatoire et unique pour chaque objet que vous souhaitez télécharger.
Le client utilise la clé de données pour chiffrer l'objet à télécharger et utilise la CMK pour chiffrer la clé de données.
Le client télécharge l'objet chiffré vers OSS, en incluant la clé de données chiffrée dans les métadonnées de l'objet.
-
Télécharger et déchiffrer un objet
Le client télécharge un objet chiffré et ses métadonnées depuis OSS.
Le client utilise la CMK correspondante pour déchiffrer la clé de données chiffrée, en se basant sur le matériel de clé indiqué par les métadonnées, puis utilise la clé de données déchiffrée pour déchiffrer l'objet.
Le client n'envoie ni les CMK ni les données non chiffrées à OSS. Vous devez conserver vos CMK en toute sécurité. Si une CMK est perdue, les objets chiffrés à l'aide des clés de données générées à partir de cette CMK ne pourront pas être déchiffrés.
Les clés de données sont générées de manière aléatoire par le client.
Utiliser les SDK OSS
Les exemples de code suivants montrent comment configurer le chiffrement côté client à l'aide des SDK OSS pour les langages de programmation courants. Pour plus d'informations sur la configuration du chiffrement côté client avec les SDK OSS pour d'autres langages, consultez Présentation.
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.crypto.SimpleRSAEncryptionMaterials;
import com.aliyun.oss.model.OSSObject;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.security.KeyPair;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;
public class Demo {
public static void main(String[] args) throws Throwable {
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Specify the name of the bucket. Example: examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object. Example: exampleobject.txt. Do not include the bucket name in the full path.
String objectName = "exampleobject.txt";
String content = "Hello OSS!";
// Specify your RSA private key string. You can generate the string by using OpenSSL. The following lines show a sample RSA private key string.
final String PRIVATE_PKCS1_PEM =
"-----BEGIN RSA PRIVATE KEY-----\n" +
"MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw+XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n" +
"ttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO1PByrE/MNd5AAfSVba93\n" +
"I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n" +
"AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n" +
"nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" +
"JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n" +
"36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n" +
"6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw4/a8vZm2tXXK/QfTQrJVXp\n" +
"VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n" +
"gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs+d5Tv4Cvquk0efOQJAd9OC\n" +
"lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n" +
"Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG7/S7Z74gyq5qZF4FUElOAZkz123E\n" +
"yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo****\n" +
"-----END RSA PRIVATE KEY-----";
// Specify your RSA public key string. You can generate the string by using OpenSSL. The following lines show a sample RSA public key string.
final String PUBLIC_X509_PEM =
"-----BEGIN PUBLIC KEY-----\n" +
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw+XO/UByW\n" +
"6mse2QsIgz3ZwBtMNu59fR5zttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" +
"5MFO1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n" +
"1EKib1Id8hpooY5xaQID****\n" +
"-----END PUBLIC KEY-----";
// Create an RSA key pair.
RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM);
RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM);
KeyPair keyPair = new KeyPair(publicKey, privateKey);
// Specify the description of the CMK. The description cannot be modified after it is specified. You can specify only one description for a CMK.
// If all objects that you want to encrypt share a CMK, you can leave the description of the CMK empty. In this case, the CMK cannot be replaced.
// If you leave the description of the CMK empty, the client cannot determine which CMK to use for decryption.
// We recommend that you specify a description for each CMK and store the mapping relationship between the CMK and the description on the client. The server does not store the mapping relationship.
Map<String, String> matDesc = new HashMap<String, String>();
matDesc.put("desc-key", "desc-value");
// Create RSA encryption materials.
SimpleRSAEncryptionMaterials encryptionMaterials = new SimpleRSAEncryptionMaterials(keyPair, matDesc);
// To download and decrypt objects encrypted by using other CMKs, add these CMKs and their descriptions to the encryption materials.
// encryptionMaterials.addKeyPairDescMaterial(<otherKeyPair>, <otherKeyPairMatDesc>);
// Create a client for client-side encryption.
// Call the shutdown method to release associated resources when the client is no longer in use.
OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder().
build(endpoint, credentialsProvider, encryptionMaterials);
try {
// Encrypt and upload the object.
ossEncryptionClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
// Download the object. The object is automatically decrypted.
OSSObject ossObject = ossEncryptionClient.getObject(bucketName, objectName);
BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
StringBuffer buffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
reader.close();
// Check whether the decrypted content is the same as the uploaded object in plaintext.
System.out.println("Put plain text: " + content);
System.out.println("Get and decrypted text: " + buffer.toString());
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossEncryptionClient != null) {
ossEncryptionClient.shutdown();
}
}
}
}import argparse
import base64
import json
from aliyunsdkkms.request.v20160120.DecryptRequest import DecryptRequest
from aliyunsdkkms.request.v20160120.EncryptRequest import EncryptRequest
from alibabacloud_dkms_transfer.kms_transfer_acs_client import KmsTransferAcsClient
from typing import Optional, Dict
import alibabacloud_oss_v2 as oss
# Parse the command line parameters
parser = argparse.ArgumentParser(description="encryption kms sample")
# Add the --region command line parameter, which specifies the region where the bucket is located. This parameter is required.
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# Add the --bucket command line parameter, which specifies the name of the bucket. This parameter is required.
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# Add the --endpoint command line parameter, which specifies the domain name used by other services to access OSS. This parameter is optional.
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# Add the --key command line parameter, which specifies the name of the object (file path). This parameter is required.
parser.add_argument('--key', help='The name of the object.', required=True)
# Add the --kms_id command line parameter, which specifies the user's CMK (Customer Master Key) ID. This parameter is required.
parser.add_argument('--kms_id', help='The id of the your CMK ID.', required=True)
# Custom master key encryptor class, inheriting from oss.crypto.MasterCipher
class MasterKmsCipher(oss.crypto.MasterCipher):
def __init__(
self,
mat_desc: Optional[Dict] = None,
kms_client: Optional[KmsTransferAcsClient] = None,
kms_id: Optional[str] = None,
):
self.kms_client = kms_client
self.kms_id = kms_id
self._mat_desc = None
# If a description of the master key is provided, serialize it to a JSON string
if mat_desc is not None and len(mat_desc.items()) > 0:
self._mat_desc = json.dumps(mat_desc)
def get_wrap_algorithm(self) -> str:
# Return the encryption algorithm name, fixed as 'KMS/ALICLOUD'
return 'KMS/ALICLOUD'
def get_mat_desc(self) -> str:
return self._mat_desc or ''
def encrypt(self, data: bytes) -> bytes:
"""
Encrypt data using the KMS service
:param data: Original data to be encrypted (in bytes format)
:return: Encrypted data (in bytes format)
"""
# Encode the original data in Base64 format
base64_crypto = base64.b64encode(data)
# Construct an encryption request object
request = EncryptRequest()
request.set_KeyId(self.kms_id) # Set the CMK ID
request.set_Plaintext(base64_crypto) # Set the Base64 data to be encrypted
# Call the KMS client to perform the encryption operation and get the response
response = self.kms_client.do_action_with_exception(request)
# Parse the encrypted data field in the response and decode it to bytes format
return base64.b64decode(json.loads(response).get('CiphertextBlob'))
def decrypt(self, data: bytes) -> bytes:
"""
Decrypt data using the KMS service
:param data: Encrypted data (in bytes format)
:return: Decrypted original data (in bytes format)
"""
# Encode the encrypted data in Base64 format
base64_crypto = base64.b64encode(data)
# Construct a decryption request object
request = DecryptRequest()
request.set_CiphertextBlob(base64_crypto) # Set the encrypted data
# Call the KMS client to perform the decryption operation and get the response
response = self.kms_client.do_action_with_exception(request)
# Parse the plaintext field in the response and decode it to bytes format
return base64.b64decode(json.loads(response).get('Plaintext'))
def main():
# Parse the command line arguments
args = parser.parse_args()
# Load credential information (AccessKeyId and AccessKeySecret) from environment variables
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
# Load the default configuration of the SDK
cfg = oss.config.load_default()
# Specify the credential provider
cfg.credentials_provider = credentials_provider
# Set the region where the bucket is located
cfg.region = args.region
# If the user provides a custom endpoint, set it in the configuration
if args.endpoint is not None:
cfg.endpoint = args.endpoint
# Initialize the OSS client with the configuration object
client = oss.Client(cfg)
# Initialize the KMS client for interacting with the KMS service
kms_client = KmsTransferAcsClient(
ak=credentials_provider._credentials.access_key_id, # Get AccessKeyId from the credential provider
secret=credentials_provider._credentials.access_key_secret, # Get AccessKeySecret from the credential provider
region_id=args.region # Specify region information
)
# Initialize the master key encryptor (MasterKmsCipher) for encryption and decryption operations
mc = MasterKmsCipher(
mat_desc={"desc": "your master encrypt key material describe information"}, # Master key description information
kms_client=kms_client, # KMS client instance
kms_id=args.kms_id # User's CMK ID
)
# Create an encryption client
encryption_client = oss.EncryptionClient(client, mc)
# Define the data to upload
data = b'hello world'
# Call the put_object method of the encryption client to upload the encrypted object
result = encryption_client.put_object(
oss.PutObjectRequest(
bucket=args.bucket, # Specify the name of the target bucket
key=args.key, # Specify the name of the object (file path)
body=data, # Specify the data to upload
)
)
# Print the result of uploading the encrypted object
print(vars(result))
# Call the get_object method of the encryption client to get the content of the encrypted object
result = encryption_client.get_object(
oss.GetObjectRequest(
bucket=args.bucket, # Specify the name of the target bucket
key=args.key, # Specify the name of the object (file path)
)
)
# Print the result of getting the encrypted object
print(vars(result))
# Print the decrypted object content
print(result.body.read())
if __name__ == "__main__":
# Program entry, call the main function to execute the logic
main()
package main
import (
"bytes"
"io"
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
osscrypto "github.com/aliyun/aliyun-oss-go-sdk/oss/crypto"
)
func main() {
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Error creating credentials provider: %v", err)
}
// Create an OSSClient instance.
// 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. Specify your actual endpoint.
// Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. Specify the actual region.
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// Specify the version of the signature algorithm.
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Error creating OSS client: %v", err)
}
// Specify a description for the CMK. The description cannot be modified after being specified. You can specify only one description for a CMK.
// If all objects share a CMK, you can leave the description of the CMK empty. In this case, the CMK cannot be replaced.
// If the description of the CMK is left empty, the client cannot determine which CMK to use for decryption.
// We recommend that you configure a description in the form of a JSON string for each CMK and store the mapping relationship between the CMK and the description on the client. The server does not store the mapping relationship.
// Obtain the mapping relationship based on the CMK description that is a JSON string.
materialDesc := map[string]string{
"desc": "your master encrypt key material describe information",
}
// Create a CMK object based on the description of the CMK.
// Set yourRsaPublicKey to the public key of the CMK that you manage, and set yourRsaPrivateKey to the private key of the CMK that you manage.
masterRsaCipher, err := osscrypto.CreateMasterRsa(materialDesc, "yourRsaPublicKey", "yourRsaPrivateKey")
if err != nil {
log.Fatalf("Error creating master RSA cipher: %v", err)
}
// Create an encryption operation based on the CMK object and perform encryption in AES CTR mode.
contentProvider := osscrypto.CreateAesCtrCipher(masterRsaCipher)
// Obtain an existing bucket to be used for client-side encryption.
// The bucket for which client-side encryption is configured is used in the same manner in which a common bucket is used.
cryptoBucket, err := osscrypto.GetCryptoBucket(client, "yourBucketName", contentProvider)
if err != nil {
log.Fatalf("Error getting crypto bucket: %v", err)
}
// Encryption is automatically performed when you call the PutObject operation.
err = cryptoBucket.PutObject("yourObjectName", bytes.NewReader([]byte("yourObjectValueByteArrary")))
if err != nil {
log.Fatalf("Error putting object: %v", err)
}
// Decryption is automatically performed when you call the GetObject operation.
body, err := cryptoBucket.GetObject("yourObjectName")
if err != nil {
log.Fatalf("Error getting object: %v", err)
}
defer body.Close()
data, err := io.ReadAll(body)
if err != nil {
log.Fatalf("Error reading object data: %v", err)
}
log.Printf("Data: %s", string(data))
}
#include <alibabacloud/oss/OssEncryptionClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* Initialize the OSS account information. */
/* Set yourEndpoint to the Endpoint of the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the Endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
std::string Endpoint = "yourEndpoint";
/* Set yourRegion to the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the Region to cn-hangzhou. */
std::string Region = "yourRegion";
/* Specify the bucket name. 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";
/* The master key and its 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 network resources. */
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
/* Obtain access credentials from environment variables. Before you run this code example, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. */
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
CryptoConfiguration cryptoConf;
auto materials = std::make_shared<SimpleRSAEncryptionMaterials>(RSAPublicKey, RSAPrivateKey, desc);
OssEncryptionClient client(Endpoint, credentialsProvider, conf, materials, cryptoConf);
/* Upload the file. */
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;
return -1;
}
/* Release network resources. */
ShutdownSdk();
return 0;
}<?php
// Introduce autoload files to load dependent libraries.
require_once __DIR__ . '/../vendor/autoload.php';
use AlibabaCloud\Dkms\Gcs\Sdk\Client as KmsClient;
use AlibabaCloud\Oss\V2 as Oss;
// Specify descriptions for command line parameters.
$optsdesc = [
"region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // (Required) Specify the region in which the bucket is located.
"endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // (Optional) Specify the endpoint that can be used by other services to access OSS.
"bucket" => ['help' => 'The name of the bucket', 'required' => True], // (Required) Specify the name of the bucket.
"key" => ['help' => 'The name of the object', 'required' => True], // (Required) Specify the name of the object.
];
// Generate a long options list to parse the command line parameters.
$longopts = \array_map(function ($key) {
return "$key:"; // Add a colon (:) to the end of each parameter to indicate that a value is required.
}, array_keys($optsdesc));
// Parse the command line parameters.
$options = getopt("", $longopts);
// Check whether the required parameters are configured.
foreach ($optsdesc as $key => $value) {
if ($value['required'] === True && empty($options[$key])) {
$help = $value['help'];
echo "Error: the following arguments are required: --$key, $help"; // Indicate that the required parameters are not configured.
exit(1);
}
}
// Obtain the values of the command line parameters.
$region = $options["region"]; // The region in which the bucket is located.
$bucket = $options["bucket"]; // The name of the bucket.
$key = $options["key"]; // The name of the object.
// Use environment variables to load the AccessKey ID and AccessKey secret.
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
// Specify the KMS encryption and decryption class to call the MasterCipherInterface operation.
class KmsCipher implements Oss\Crypto\MasterCipherInterface
{
private $matDesc;
private ?KmsClient $kmsClient;
private ?string $keyId;
private ?string $algorithm;
public function __construct(
$matDesc = null,
?string $keyId = null,
?KmsClient $kmsClient = null,
?string $algorithm = null
)
{
$this->keyId = $keyId;
$this->matDesc = null;
if (\is_array($matDesc)) {
$val = json_encode($matDesc);
if ($val !== false) {
$this->matDesc = $val;
}
} else if (is_string($matDesc)) {
$this->matDesc = $matDesc;
}
$this->kmsClient = $kmsClient;
$this->algorithm = $algorithm;
}
// Specify the encryption method.
public function encrypt(string $data): string
{
$encryptRequest = new \AlibabaCloud\Dkms\Gcs\Sdk\Models\AdvanceEncryptRequest();
$encryptRequest->algorithm = $this->algorithm;
$encryptRequest->keyId = $this->keyId;
$encryptRequest->plaintext = \AlibabaCloud\Tea\Utils\Utils::toBytes($data);
$runtimeOptions = new \AlibabaCloud\Dkms\Gcs\OpenApi\Util\Models\RuntimeOptions();
$encryptResponse = $this->kmsClient->advanceEncryptWithOptions($encryptRequest, $runtimeOptions);
return base64_decode((string)$encryptResponse->ciphertextBlob);
}
// Specify the decryption method.
public function decrypt(string $data): string
{
$decryptRequest = new \AlibabaCloud\Dkms\Gcs\Sdk\Models\AdvanceDecryptRequest();
$decryptRequest->keyId = $this->keyId;
$decryptRequest->ciphertextBlob = $data;
$decryptRequest->algorithm = $this->algorithm;
$runtimeOptions = new \AlibabaCloud\Dkms\Gcs\OpenApi\Util\Models\RuntimeOptions();
$decryptResponse = $this->kmsClient->advanceDecryptWithOptions($decryptRequest, $runtimeOptions);
return base64_decode((string)$decryptResponse->plaintext);
}
// Obtain the wrapping algorithm.
public function getWrapAlgorithm(): string
{
return "KMS/ALICLOUD";
}
public function getMatDesc(): string
{
return $this->matDesc;
}
}
/**
* Create a dedicated KMS SDK client.
* @return KmsClient
*/
function getDkmsGcsSdkClient()
{
global $clientKeyFile, $password, $endpoint;
// Create configurations for the dedicated KMS SDK client.
$config = new \AlibabaCloud\Dkms\Gcs\OpenApi\Models\Config();
$config->protocol = 'https';
$config->clientKeyFile = $clientKeyFile;
$config->password = $password;
$config->endpoint = $endpoint;
// Verify the certificate.
$config->caFilePath = 'path/to/caCert.pem';
// Create a KMS SDK client.
return new \AlibabaCloud\Dkms\Gcs\Sdk\Client($config);
}
// Specify the path of the file that stores the client key of the KMS instance.
$clientKeyFile = '<your client key file path>';
// Specify the password when you create the client key file.
$password = '<your dkms client passowrd>';
// Specify the endpoint of the KMS instance.
$endpoint = '<your dkms instance service address>';
// Specify the ID of the key that you created in KMS.
$kmsKeyId = '<your cmk id>';
// Specify the encryption and decryption algorithms.
$algorithm = '<your encrypt algorithm>';
// Specify the dedicated KMS SDK client.
$kmsClient = getDkmsGcsSdkClient();
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider);
$cfg->setRegion($region);
if (isset($options["endpoint"])) {
$cfg->setEndpoint($options["endpoint"]);
}
$client = new Oss\Client($cfg);
$materialDesc = ['desc' => 'your kms encrypt key material describe information'];
$masterKmsCipher = new KmsCipher($materialDesc, $kmsKeyId, $kmsClient, $algorithm);
$eClient = new \AlibabaCloud\Oss\V2\EncryptionClient($client, $masterKmsCipher);
$eClient->putObject(new Oss\Models\PutObjectRequest(
bucket: $bucket,
key: $key,
body: Oss\Utils::streamFor('hi kms')
));
$result = $eClient->getObject(new Oss\Models\GetObjectRequest(
bucket: $bucket,
key: $key,
));
$data = $result->body->getContents();
echo "get object data: " . $data;