クライアント側の暗号化が有効になっている場合、オブジェクトは Object Storage Service (OSS) にアップロードされる前にローカルで暗号化されます。 これにより、データ転送および保存中のデータセキュリティが強化されます。
免責事項
クライアント側の暗号化を使用する場合、カスタマーマスターキー (CMK) の整合性と有効性を確保する必要があります。 不適切なメンテナンスが原因で CMK が誤って使用されたり、紛失したりした場合、復号の失敗によって発生するすべての損失と結果について責任を負うものとします。
暗号化されたデータをコピーまたは移行する場合、オブジェクトメタデータの整合性と有効性について責任を負うものとします。 不適切なメンテナンスが原因で暗号化されたメタデータが正しくない場合、または失われた場合、データの復号の失敗によって発生するすべての損失と結果について責任を負うものとします。
シナリオ
機密性の高いデータ: 個人識別用情報 (PII)、金融取引記録、医療および健康データなど、非常に機密性の高い情報を含むデータの場合、ユーザーはデータがローカル環境から送信される前にデータを暗号化して、転送中に元のデータが効果的に保護されるようにすることができます。
コンプライアンス要件: HIPAA や GDPR など、特定の規制では、厳格なデータ暗号化管理が必要です。 クライアント側の暗号化は、CMK がユーザーによって管理され、ネットワークを介して渡されないため、これらのコンプライアンス要件を満たしています。
強力な権限制御: 企業または開発者は、暗号化アルゴリズムの選択や CMK の管理など、暗号化プロセスを完全に制御したいと考えています。 クライアント側の暗号化により、正当に承認されたユーザーのみがデータを復号化してアクセスできます。
リージョン間のデータ移行のセキュリティ: クライアント側の暗号化は、リージョン間のデータ移行の前後でデータを暗号化状態で維持するのに役立ちます。 これにより、インターネット経由のデータ転送のセキュリティが強化されます。
背景情報
クライアント側の暗号化では、各オブジェクトに対してランダムなデータキーが生成され、オブジェクトに対して対称暗号化が実行されます。 クライアントは CMK を使用してランダムなデータキーを暗号化します。 暗号化されたデータキーは、オブジェクトメタデータの一部としてアップロードされ、OSS サーバーに保存されます。 暗号化されたオブジェクトがダウンロードされると、クライアントは CMK を使用してランダムなデータキーを復号化し、復号化されたデータキーを使用してオブジェクトを復号化します。 データセキュリティを確保するために、CMK はクライアントでのみ使用され、ネットワーク経由で転送されたり、サーバーに保存されたりすることはありません。
クライアント側の暗号化は、サイズが 5 GB を超えるオブジェクトのマルチパートアップロードをサポートしています。 マルチパートアップロードを使用してオブジェクトをアップロードする場合は、オブジェクトの合計サイズとパートサイズを指定する必要があります。 最後の部分を除く各部分のサイズは同じで、16 の整数倍である必要があります。
ローカルクライアントで暗号化されたオブジェクトをアップロードする場合、オブジェクトの暗号化されたメタデータは保護されており、CopyObject を呼び出しても変更できません。
クライアント側の暗号化には、2 種類の CMK を使用できます。
完全なサンプルコードについては、GitHub にアクセスしてください。
KMS 管理の CMK を使用する
Key Management Service (KMS) 管理の CMK をクライアント側の暗号化に使用する場合は、オブジェクトのアップロード時に CMK ID を指定するだけで済みます。 暗号化クライアントにデータキーを提供する必要はありません。 次の図は、暗号化プロセスを示しています。
オブジェクトを暗号化してアップロードする
データキーを取得します。
クライアントは、指定された CMK ID を使用して、オブジェクトを暗号化するためのデータキーを KMS にリクエストします。 KMS はランダムなキーを生成し、データキーのプレーンテキストと暗号文を返します。
オブジェクトを暗号化し、暗号化されたオブジェクトを OSS にアップロードします。
クライアントは、データキーのプレーンテキストを使用してクライアント側でオブジェクトを暗号化し、暗号化されたオブジェクトとデータキーの暗号文を OSS にアップロードします。
オブジェクトをダウンロードして復号化する
オブジェクトをダウンロードします。
クライアントは、暗号化されたオブジェクトとデータキーの暗号文を OSS からダウンロードします。
オブジェクトを復号化します。
クライアントは、データキーの暗号文と対応する CMK ID を KMS に送信します。 KMS は、クライアントから送信された CMK を使用して暗号化されたオブジェクトを復号化し、データキーのプレーンテキストをクライアントに返します。
クライアントは、一意のデータキーを使用して、アップロードする各オブジェクトを暗号化します。
データセキュリティを確保するために、CMK を定期的にローテーションまたは更新することをお勧めします。
CMK ID と暗号化されたオブジェクトのマッピング関係を維持する必要があります。
顧客管理の CMK を使用する
顧客管理の CMK をクライアント側の暗号化に使用する場合は、CMK を手動で生成および管理する必要があります。 オブジェクトの暗号化のために、対称 CMK または非対称 CMK を暗号化クライアントにアップロードする必要があります。 次の図は、暗号化プロセスを示しています。
オブジェクトを暗号化してアップロードする
クライアントに、対称 CMK または非対称 CMK を提供します。
クライアントは、CMK を使用して、アップロードするオブジェクトの暗号化にのみ使用されるワンタイム対称データキーを生成します。 クライアントは、アップロードする各オブジェクトに対してランダムで一意のデータキーを生成します。
クライアントは、データキーを使用してアップロードするオブジェクトを暗号化し、CMK を使用してデータキーを暗号化します。
クライアントは、暗号化されたオブジェクトを、オブジェクトのメタデータに含まれる暗号化されたデータキーとともに OSS にアップロードします。
オブジェクトをダウンロードして復号化する
クライアントは、暗号化されたオブジェクトとそのメタデータを OSS からダウンロードします。
クライアントは、対応する CMK を使用して、メタデータによって示されるキーマテリアルに基づいて暗号化されたデータキーを復号化し、復号化されたデータキーを使用してオブジェクトを復号化します。
クライアントは、CMK と暗号化されていないデータを OSS に送信しません。 CMK を安全に保管する必要があります。 CMK が失われた場合、この CMK から生成されたデータキーを使用して暗号化されたオブジェクトは復号化できません。
データキーは、クライアントによってランダムに生成されます。
OSS SDK を使用する
次のサンプルコードは、一般的なプログラミング言語の OSS SDK を使用してクライアント側の暗号化を設定する方法の例を示しています。 OSS SDK を使用して他のプログラミング言語でクライアント側の暗号化を設定する方法の詳細については、「概要」をご参照ください。
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 {
// この例では、中国 (杭州) リージョンのエンドポイントが使用されています。 実際のエンドポイントを指定してください。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 環境変数からアクセス認証情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が構成されていることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// バケットの名前を指定します。 例: examplebucket。
String bucketName = "examplebucket";
// オブジェクトの完全なパスを指定します。 例: exampleobject.txt。 完全なパスにバケット名を含めないでください。
String objectName = "exampleobject.txt";
String content = "Hello OSS!";
// RSA 秘密鍵文字列を指定します。 OpenSSL を使用して文字列を生成できます。 次の行は、サンプルの RSA 秘密鍵文字列を示しています。
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-----";
// RSA 公開鍵文字列を指定します。 OpenSSL を使用して文字列を生成できます。 次の行は、サンプルの RSA 公開鍵文字列を示しています。
final String PUBLIC_X509_PEM =
"-----BEGIN PUBLIC KEY-----\n" +
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw+XO/UByW\n" +
"6mse2QsIgz3ZwBtMNu59fR5zttSx+8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" +
"5MFO1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n" +
"1EKib1Id8hpooY5xaQID****\n" +
"-----END PUBLIC KEY-----";
// RSA キーペアを作成します。
RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM);
RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM);
KeyPair keyPair = new KeyPair(publicKey, privateKey);
// CMK の説明を指定します。 説明は、指定後に変更することはできません。 1 つの CMK に対して 1 つの説明のみを指定できます。
// 暗号化するすべてのオブジェクトが CMK を共有する場合、CMK の説明を空のままにすることができます。 この場合、CMK を置き換えることはできません。
// CMK の説明を空のままにすると、クライアントは復号に使用する CMK を判別できません。
// 各 CMK の説明を指定し、CMK と説明のマッピング関係をクライアントに保存することをお勧めします。 サーバーはマッピング関係を保存しません。
Map<String, String> matDesc = new HashMap<String, String>();
matDesc.put("desc-key", "desc-value");
// RSA 暗号化マテリアルを作成します。
SimpleRSAEncryptionMaterials encryptionMaterials = new SimpleRSAEncryptionMaterials(keyPair, matDesc);
// 他の CMK を使用して暗号化されたオブジェクトをダウンロードして復号化するには、これらの CMK とその説明を暗号化マテリアルに追加します。
// encryptionMaterials.addKeyPairDescMaterial(<otherKeyPair>, <otherKeyPairMatDesc>);
// クライアント側の暗号化用のクライアントを作成します。
// クライアントが使用されなくなったときに関連付けられたリソースを解放するには、shutdown メソッドを呼び出します。
OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder().
build(endpoint, credentialsProvider, encryptionMaterials);
try {
// オブジェクトを暗号化してアップロードします。
ossEncryptionClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
// オブジェクトをダウンロードします。 オブジェクトは自動的に復号化されます。
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();
// 復号化されたコンテンツが、プレーンテキストでアップロードされたオブジェクトと同じであるかどうかを確認します。
System.out.println("Put plain text: " + content);
System.out.println("Get and decrypted text: " + buffer.toString());
} catch (OSSException oe) {
System.out.println("OSSException が発生しました。これは、リクエストが OSS に到達しましたが、何らかの理由でエラー応答で拒否されたことを意味します。");
System.out.println("エラーメッセージ:" + oe.getErrorMessage());
System.out.println("エラーコード:" + oe.getErrorCode());
System.out.println("リクエスト ID:" + oe.getRequestId());
System.out.println("ホスト ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("ClientException が発生しました。これは、クライアントが OSS と通信しようとしているときに、ネットワークにアクセスできないなど、重大な内部問題が発生したことを意味します。");
System.out.println("エラーメッセージ:" + 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
import alibabacloud_oss_v2.crypto
from alibabacloud_oss_v2.encryption_client import EncryptionClient, EncryptionMultiPartContext
# コマンドライン引数を解析するためのコマンドラインパラメータパーサーを作成します。
parser = argparse.ArgumentParser(description="encryption kms sample")
# (必須)バケットが配置されているリージョンを指定する --region パラメータを指定します。
parser.add_argument('--region', help='バケットが配置されているリージョン。', required=True)
# (必須)バケットの名前を指定する --bucket パラメータを指定します。
parser.add_argument('--bucket', help='バケットの名前。', required=True)
# (オプション)他のサービスが OSS にアクセスするために使用できるエンドポイントを指定する --endpoint パラメータを指定します。
parser.add_argument('--endpoint', help='他のサービスが OSS にアクセスするために使用できるドメイン名')
# (必須)オブジェクトの名前を指定する --key パラメータを指定します。
parser.add_argument('--key', help='オブジェクトの名前。', required=True)
# (必須)CMK(カスタマーマスターキー)の ID を指定する --kms_id パラメータを指定します。
parser.add_argument('--kms_id', help='CMK ID。', required=True)
# カスタムマスターキーエンクリプタークラス。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
# マスターキーの説明が提供されている場合は、JSON 文字列にシリアル化します。
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:
# 暗号化アルゴリズム名を返します。「KMS/ALICLOUD」に固定されています。
return 'KMS/ALICLOUD'
def get_mat_desc(self) -> str:
return self._mat_desc or ''
def encrypt(self, data: bytes) -> bytes:
"""
KMS サービスを使用してデータを暗号化します。
:param data: 暗号化する元のデータ(バイト形式)
:return: 暗号化されたデータ(バイト形式)
"""
# 元のデータを Base64 形式でエンコードします。
base64_crypto = base64.b64encode(data)
# 暗号化リクエストオブジェクトを構築します。
request = EncryptRequest()
request.set_KeyId(self.kms_id) # CMK ID を設定します。
request.set_Plaintext(base64_crypto) # 暗号化する Base64 データを設定します。
# KMS クライアントを呼び出して暗号化操作を実行し、レスポンスを取得します。
response = self.kms_client.do_action_with_exception(request)
# レスポンスの暗号化データフィールドを解析し、バイト形式にデコードします。
return base64.b64decode(json.loads(response).get('CiphertextBlob'))
def decrypt(self, data: bytes) -> bytes:
"""
KMS サービスを使用してデータを復号化します。
:param data: 暗号化されたデータ(バイト形式)
:return: 復号化された元のデータ(バイト形式)
"""
# 暗号化されたデータを Base64 形式でエンコードします。
base64_crypto = base64.b64encode(data)
# 復号化リクエストオブジェクトを構築します。
request = DecryptRequest()
request.set_CiphertextBlob(base64_crypto) # 暗号化されたデータを設定します。
# KMS クライアントを呼び出して復号化操作を実行し、レスポンスを取得します。
response = self.kms_client.do_action_with_exception(request)
# レスポンスのプレーンテキストフィールドを解析し、バイト形式にデコードします。
return base64.b64decode(json.loads(response).get('Plaintext'))
def main():
# コマンドライン引数を解析します。
args = parser.parse_args()
# 環境変数からアクセス認証情報(AccessKey ID と AccessKey シークレット)を取得します。
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
# SDK のデフォルト構成を読み込みます。
cfg = oss.config.load_default()
# 認証情報プロバイダーを指定します。
cfg.credentials_provider = credentials_provider
# バケットが配置されているリージョンを指定します。
cfg.region = args.region
# カスタムエンドポイントが提供されている場合は、endpoint パラメータを変更します。
if args.endpoint is not None:
cfg.endpoint = args.endpoint
# 前述の構成を使用して、OSSClient インスタンスを初期化します。
client = oss.Client(cfg)
# KMS サービスと対話するための KMS クライアントを初期化します。
kms_client = KmsTransferAcsClient(
ak=credentials_provider._credentials.access_key_id, # 認証情報プロバイダーから AccessKeyId を取得します。
secret=credentials_provider._credentials.access_key_secret, # 認証情報プロバイダーから AccessKeySecret を取得します。
region_id=args.region # リージョン情報を指定します。
)
# 暗号化および復号化操作のために、マスターキーエンクリプター(MasterKmsCipher)を初期化します。
mc = MasterKmsCipher(
mat_desc={"desc": "your master encrypt key material describe information"}, # マスターキーの説明情報
kms_client=kms_client, # KMS クライアントインスタンス
kms_id=args.kms_id # ユーザーの CMK ID
)
# 暗号化クライアントを作成します。
encryption_client = oss.EncryptionClient(client, mc)
# アップロードするデータを定義します。
data = b'hello world'
# 暗号化クライアントの put_object メソッドを呼び出して、暗号化されたオブジェクトをアップロードします。
result = encryption_client.put_object(
oss.PutObjectRequest(
bucket=args.bucket, # ターゲットバケットの名前を指定します。
key=args.key, # オブジェクトの名前(ファイルパス)を指定します。
body=data, # アップロードするデータを指定します。
)
)
# 暗号化されたオブジェクトのアップロード結果を出力します。
print(vars(result))
# 暗号化クライアントの get_object メソッドを呼び出して、暗号化されたオブジェクトのコンテンツを取得します。
result = encryption_client.get_object(
oss.GetObjectRequest(
bucket=args.bucket, # ターゲットバケットの名前を指定します。
key=args.key, # オブジェクトの名前(ファイルパス)を指定します。
)
)
# 暗号化されたオブジェクトの取得結果を出力します。
print(vars(result))
# 復号化されたオブジェクトコンテンツを出力します。
print(result.body.read())
if __name__ == "__main__":
# スクリプトが直接実行された場合に、スクリプトのメイン関数にエントリポイントを指定します。
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() {
// 環境変数からアクセス認証情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が構成されていることを確認してください。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("認証情報プロバイダーの作成エラー: %v", err)
}
// OSSClient インスタンスを作成します。
// バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンに配置されている場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。 実際のエンドポイントを指定してください。
// バケットが配置されているリージョンを指定します。 たとえば、バケットが中国 (杭州) リージョンに配置されている場合は、リージョンを cn-hangzhou に設定します。 実際のリージョンを指定してください。
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// 署名アルゴリズムのバージョンを指定します。
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("OSS クライアントの作成エラー: %v", err)
}
// CMK の説明を指定します。 説明は、指定後に変更することはできません。 1 つの CMK に対して 1 つの説明のみを指定できます。
// すべてのオブジェクトが CMK を共有する場合、CMK の説明を空のままにすることができます。 この場合、CMK を置き換えることはできません。
// CMK の説明を空のままにすると、クライアントは復号に使用する CMK を判別できません。
// 各 CMK に JSON 文字列形式の説明を構成し、CMK と説明のマッピング関係をクライアントに保存することをお勧めします。 サーバーはマッピング関係を保存しません。
// JSON 文字列である CMK の説明に基づいてマッピング関係を取得します。
materialDesc := map[string]string{
"desc": "your master encrypt key material describe information",
}
// CMK の説明に基づいて CMK オブジェクトを作成します。
// yourRsaPublicKey を管理する CMK の公開鍵に設定し、yourRsaPrivateKey を管理する CMK の秘密鍵に設定します。
masterRsaCipher, err := osscrypto.CreateMasterRsa(materialDesc, "yourRsaPublicKey", "yourRsaPrivateKey")
if err != nil {
log.Fatalf("マスター RSA 暗号の作成エラー: %v", err)
}
// CMK オブジェクトに基づいて暗号化操作を作成し、AES CTR モードで暗号化を実行します。
contentProvider := osscrypto.CreateAesCtrCipher(masterRsaCipher)
// クライアント側の暗号化に使用する既存のバケットを取得します。
// クライアント側の暗号化が構成されているバケットは、一般的なバケットと同じ方法で使用されます。
cryptoBucket, err := osscrypto.GetCryptoBucket(client, "yourBucketName", contentProvider)
if err != nil {
log.Fatalf("暗号バケットの取得エラー: %v", err)
}
// PutObject 操作を呼び出すと、暗号化が自動的に実行されます。
err = cryptoBucket.PutObject("yourObjectName", bytes.NewReader([]byte("yourObjectValueByteArrary")))
if err != nil {
log.Fatalf("オブジェクトの配置エラー: %v", err)
}
// GetObject 操作を呼び出すと、復号化が自動的に実行されます。
body, err := cryptoBucket.GetObject("yourObjectName")
if err != nil {
log.Fatalf("オブジェクトの取得エラー: %v", err)
}
defer body.Close()
data, err := io.ReadAll(body)
if err != nil {
log.Fatalf("オブジェクトデータの読み取りエラー: %v", err)
}
log.Printf("データ: %s", string(data))
}
#include <alibabacloud/oss/OssEncryptionClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* OSS にアクセスするために使用されるアカウントに関する情報を初期化します。 */
/* バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンに配置されている場合は、エンドポイントを https://oss-cn-hangzhou.aliyuncs.com に設定します。 */
std::string Endpoint = "yourEndpoint";
/* バケットが配置されているリージョンを指定します。 たとえば、バケットが中国 (杭州) リージョンに配置されている場合は、リージョンを cn-hangzhou に設定します。 */
std::string Region = "yourRegion";
/* バケットの名前を指定します。 例: examplebucket。 */
std::string BucketName = "examplebucket";
/* オブジェクトの完全なパスを指定します。 完全なパスにバケット名を含めないでください。 例: exampledir/exampleobject.txt。 */
std::string ObjectName = "exampledir/exampleobject.txt";
/* CMK と説明を指定します。 */
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";
/* ネットワークリソースなどのリソースを初期化します。 */
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
/* 環境変数からアクセス認証情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_ID および OSS_ACCESS_KEY_SECRET 環境変数が構成されていることを確認してください。 */
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);
/* オブジェクトをアップロードします。 */
auto outcome = client.PutObject(BucketName, ObjectName, "yourLocalFilename");
if (!outcome.isSuccess()) {
/* 例外を処理します。 */
std::cout << "PutObject fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
return -1;
}
/* ネットワークリソースなどのリソースを解放します。 */
ShutdownSdk();
return 0;
}<?php
// 依存ライブラリを読み込むために、autoload ファイルを導入します。
require_once 'vendor/autoload.php';
use AlibabaCloud\Dkms\Gcs\Sdk\Client as KmsClient;
use AlibabaCloud\Oss\V2 as Oss;
// コマンドラインパラメータの説明を指定します。
$optsdesc = [
"region" => ['help' => 'バケットが配置されているリージョン。', 'required' => True], // (必須)バケットが配置されているリージョンを指定します。
"endpoint" => ['help' => '他のサービスが OSS にアクセスするために使用できるドメイン名。', 'required' => False], // (オプション)他のサービスが OSS にアクセスするために使用できるエンドポイントを指定します。
"bucket" => ['help' => 'バケットの名前', 'required' => True], // (必須)バケットの名前を指定します。
"key" => ['help' => 'オブジェクトの名前', 'required' => True], // (必須)オブジェクトの名前を指定します。
];
// コマンドラインパラメータを解析するために、長いオプションリストを生成します。
$longopts = \array_map(function ($key) {
return "$key:"; // 各パラメータの末尾にコロン (:) を追加して、値が必要であることを示します。
}, array_keys($optsdesc));
// コマンドラインパラメータを解析します。
$options = getopt("", $longopts);
// 必要なパラメータが構成されているかどうかを確認します。
foreach ($optsdesc as $key => $value) {
if ($value['required'] === True && empty($options[$key])) {
$help = $value['help'];
echo "エラー: 次の引数は必須です: --$key, $help"; // 必要なパラメータが構成されていないことを示します。
exit(1);
}
}
// コマンドラインパラメータの値を取得します。
$region = $options["region"]; // バケットが配置されているリージョン。
$bucket = $options["bucket"]; // バケットの名前。
$key = $options["key"]; // オブジェクトの名前。
// 環境変数を使用して、AccessKey ID と AccessKey シークレットを読み込みます。
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
// MasterCipherInterface 操作を呼び出すために、KMS 暗号化および復号化クラスを指定します。
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;
}
// 暗号化方法を指定します。
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);
}
// 復号化方法を指定します。
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);
}
// ラッピングアルゴリズムを取得します。
public function getWrapAlgorithm(): string
{
return "KMS/ALICLOUD";
}
public function getMatDesc(): string
{
return $this->matDesc;
}
}
/**
* 専用の KMS SDK クライアントを作成します。
* @return KmsClient
*/
function getDkmsGcsSdkClient()
{
global $clientKeyFile, $password, $endpoint;
// 専用の KMS SDK クライアントの構成を作成します。
$config = new \AlibabaCloud\Dkms\Gcs\OpenApi\Models\Config();
$config->protocol = 'https';
$config->clientKeyFile = $clientKeyFile;
$config->password = $password;
$config->endpoint = $endpoint;
// 証明書を確認します。
$config->caFilePath = 'path/to/caCert.pem';
// KMS SDK クライアントを作成します。
return new \AlibabaCloud\Dkms\Gcs\Sdk\Client($config);
}
// KMS インスタンスのクライアントキーを保存するファイルのパスを指定します。
$clientKeyFile = '<your client key file path>';
// クライアントキーファイルを作成するときのパスワードを指定します。
$password = '<your dkms client passowrd>';
// KMS インスタンスのエンドポイントを指定します。
$endpoint = '<your dkms instance service address>';
// KMS で作成したキーの ID を指定します。
$kmsKeyId = '<your cmk id>';
// 暗号化および復号化アルゴリズムを指定します。
$algorithm = '<your encrypt algorithm>';
// 専用の KMS SDK クライアントを指定します。
$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;