クライアント側の暗号化が有効になっている場合、オブジェクトはOSS (Object Storage Service) にアップロードされる前にローカルで暗号化されます。 オブジェクトを復号化できるのは、顧客マスターキー (CMK) の所有者だけです。 クライアント側の暗号化は、データ送信および保存中のデータセキュリティを強化します。
免責事項
クライアント側の暗号化を使用する場合は、CMKの整合性と有効性を確保する必要があります。 不適切なメンテナンスのためにCMKが誤って使用されたり失われたりした場合、復号化の失敗によって引き起こされるすべての損失と結果に対して責任があります。
暗号化されたデータをコピーまたは移行する場合、オブジェクトメタデータの整合性と有効性に責任があります。 暗号化されたメタデータが正しくないか、不適切なメンテナンスのために失われた場合、データの復号化の失敗によって引き起こされるすべての損失と結果に対して責任があります。
シナリオ
機密性の高いデータ: 個人を特定できる情報 (PII) 、金融取引記録、健康データ、およびその他の機密性の高いデータについては、データがローカル環境を離れる前にデータを暗号化して、送信中に傍受されても元のデータが効果的に保護されるようにすることができます。
コンプライアンス要件: 医療保険の相互運用性および説明責任法 (HIPAA) や一般データ保護規則 (GDPR) などの特定の業界および規制では、サードパーティのプラットフォームに保存されているデータの厳密な暗号化管理が必要です。 CMKはユーザーによって管理され、ネットワークを経由したり、クラウドサービスプロバイダーに公開されたりしないため、クライアント側の暗号化はこれらのコンプライアンス要件を満たすのに役立ちます。
完全な暗号化制御: 企業または開発者は、暗号化アルゴリズムの選択、CMKの管理およびローテーションなど、暗号化プロセスを完全に制御したい場合があります。 クライアント側の暗号化により、許可されたユーザーのみがデータを復号化およびアクセスできます。
クロスリージョンデータ移行のセキュリティ: クライアント側の暗号化は、クロスリージョンデータ移行の前後でデータを暗号化された状態に維持するのに役立ちます。 これは、インターネット上のデータ伝送のセキュリティを増幅する。
使用上の注意
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用します。 OSSと同じリージョンにある他のAlibaba CloudサービスからOSSにアクセスする場合は、内部エンドポイントを使用します。 OSSリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
このトピックでは、アクセス資格情報は環境変数から取得します。 アクセス資格情報の設定方法の詳細については、「アクセス資格情報の設定」をご参照ください。
このトピックでは、OSSエンドポイントを使用してOSSClientインスタンスを作成します。 カスタムドメイン名またはSecurity Token Service (STS) を使用してOSSClientインスタンスを作成する場合は、「OSSClientインスタンスの作成」をご参照ください。
背景情報
クライアント側の暗号化では、オブジェクトに対して対称暗号化を実行するために、オブジェクトごとにランダムなデータキーが生成されます。 クライアントはCMKを使用してランダムデータキーを暗号化します。 暗号化されたデータキーは、オブジェクトメタデータの一部としてアップロードされ、OSSサーバーに保存されます。 暗号化されたオブジェクトがダウンロードされると、クライアントはCMKを使用してランダムデータキーを復号し、次にデータキーを使用してオブジェクトを復号します。 データのセキュリティを確保するために、CMKはクライアントでのみ使用され、ネットワーク経由で送信されたり、サーバーに保存されたりすることはありません。
クライアント側の暗号化は、サイズが5 GBを超えるオブジェクトのマルチパートアップロードをサポートします。 マルチパートアップロードを使用してオブジェクトをアップロードする場合、オブジェクトの合計サイズと各パーツのサイズを指定する必要があります。 最後の部分を除く各部分のサイズは同じで、16の倍数でなければなりません。
クライアントで暗号化されたオブジェクトをアップロードした後、クライアント側の暗号化に関連するオブジェクトメタデータは保護され、CopyObject操作を呼び出して変更することはできません。
暗号化方法
クライアント側の暗号化には、次の2種類のCMKを使用できます。
KMSマネージドCMK
Key Management Service (KMS) が管理するCMKをクライアント側の暗号化に使用する場合、CMK IDをOSS SDK for Pythonに送信する必要があります。
自分で管理するRSAベースのCMK
自分で管理するCMKをクライアント側の暗号化に使用する場合は、CMKの公開鍵と秘密鍵をOSS SDK for Pythonにパラメーターとして送信する必要があります。
上記の暗号化方法を使用して、データ漏洩を防ぎ、クライアント上のデータを保護できます。 データが漏洩しても、他のユーザーはデータを復号することはできません。
クライアント側暗号化に関連するオブジェクトメタデータ
パラメーター | 説明 | 必須 |
x-oss-meta-client-side-encryption-key | 暗号化されたデータキー。 暗号化されたキーは、カスタマーマスターキー (CMK) を使用して暗号化され、Base64でエンコードされた文字列です。 | 可 |
x-oss-meta-client-side-encryption-start | データ暗号化のためにランダムに生成される初期値。 初期値は、CMKを使用して暗号化され、Base64でエンコードされた文字列です。 | 可 |
x-oss-meta-client-side-encryption-cek-alg | データの暗号化に使用されるアルゴリズム。 | 可 |
x-oss-meta-client-side-encryption-wrap-alg | データキーの暗号化に使用されるアルゴリズム。 | 可 |
x-oss-meta-client-side-encryption-matdesc | JSON形式のCMKの説明。 警告 各CMKの説明を設定し、CMKとその説明の間のマッピング関係を保存することを推奨します。 記述が指定されていないCMKは置き換えることができません。 | 任意 |
x-oss-meta-client-side-encryption-unencrypted-content-length | 暗号化前のデータの長さ。 Content-Lengthが指定されていない場合、このパラメーターは生成されません。 | 任意 |
x-oss-meta-client-side-encryption-unencrypted-content-md5 | 暗号化前のデータのMD5ハッシュ。 Content-MD5が指定されていない場合、このパラメーターは生成されません。 | 任意 |
x-oss-meta-client-side-encryption-data-size | init_multipartが呼び出されたときにマルチパートアップロードのために暗号化されるデータの合計サイズ。 | はい (マルチパートアップロードの場合) |
x-oss-meta-client-side-encryption-part-size | init_multipartが呼び出されたときにマルチパートアップロードのために暗号化される各パーツのサイズ。 重要 部品サイズは16の倍数でなければなりません。 | はい (マルチパートアップロードの場合) |
OpenSSL
デフォルトでは、PRIVATE_PKCS8_PEMはOpenSSLバージョン3.xを使用して生成されます。 OpenSSLを使用してPRIVATE_PKCS1_PEMを生成する必要がある場合は、-traditionalオプションを指定する必要があります。 詳細については、「OpenSSL」をご参照ください。
クライアント側暗号化用のクライアントを作成する
RSAベースまたはKMSベースの暗号化用のクライアントを作成するときは、OSS SDK for Java 3.9.1以降を使用し、Bouncy Castleが提供するJavaライブラリ (bcprov-jdk15on) をMavenプロジェクトにインポートしていることを確認してください。 次のサンプルコードは、bcprov-jdk15onライブラリをインポートする方法の例を示しています。
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.62</version>
</dependency>
java.security.InvalidKeyException: 不正なキーサイズまたはデフォルトパラメーター
エラーメッセージが返された場合は、OracleのJava Cryptography Extension (JCE) 管轄ポリシーファイルを追加し、このファイルをJRE環境にデプロイする必要があります。
使用するJDKバージョンに基づいて、次のいずれかのファイルをダウンロードします。 次に、ファイルをjre/lib/securityディレクトリに解凍します。
RSAベースの暗号化のためのクライアントの作成
RSAベースの暗号化用のクライアントを作成する前に、非対称キーペアを作成する必要があります。 OSS SDK for Javaは、PEM形式のPKCS #1エンコードまたはPKCS #8エンコードされた秘密鍵文字列をRSA秘密鍵に変換するメソッドと、PEM形式のX.509エンコードされた公開鍵文字列をRSA公開鍵に変換するメソッドを提供します。
次の方法を使用して、上記の要件を満たすキーを変換できます。
RSAPrivateKey SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1 (文字列privateKeyStr);
RSAPrivateKey SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS8 (文字列privateKeyStr);
RSAPublicKey SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509 (文字列publicKeyStr);
次のサンプルコードは、RSAベースの暗号化用にクライアントを作成する方法の例を示しています。
com.aliyun.oss.*;
impor t com.aliyun.oss.com mon.auth.*;
com.aliyun.oss.crypto.SimpleRSAEncryptionMaterialsをインポートします。java.security.KeyPairをインポートします。java.security.int erfaces.RSAPrivateKeyをインポートします。java.security.int erfaces.RSAPublicKeyをインポートします。java.util.HashMapをインポートします。java.util.Mapをインポートします。public classデモ {
public static void main(String[] args) Throwable {
// この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 次のコマンドを実行して、秘密鍵と公開鍵のPEMファイルを別々に生成できます。 次に、PRIVATE_PKCS1_PEMおよびPUBLIC_X509_PEMの値を、秘密鍵および公開鍵のPEMファイルに含まれる文字列に設定します。
// openssl genrsa -out private_key.pem 2048
// openssl rsa -in private_key.pem -out rsa_public_key.pem -pubout
// RSA秘密鍵文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA秘密鍵文字列のサンプルを示しています。
final文字列PRIVATE_PKCS1_PEM=
"----- BEGIN RSA PRIVATE KEY -----\n" +
「MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n」 +
"ttSx 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO 1PByrE/MNd5AAfSVba93\n"
「I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n」 +
「AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n」 +
"nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" +
「JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n」 +
「36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n」 +
「6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw 4/a8vZm2tXXK/QfTQrJVXp\n」 +
「VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n」
"gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs + d5Tv4Cvquk0efOQJAd9OC\n" +
「lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n」 +
「Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG 7/S7Z74gyq5qZF4FUElOAZkz123E\n」 +
"yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo ****\n" +
"----- END RSAプライベートキー -----";
// RSA公開キー文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA公開キー文字列のサンプルを示します。
final String PUBLIC_X509_PEM=
「 ----- 公開キーを開始 ----- 」
「MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw XO/UByW\n」 +
"6mse2QsIgz3ZwBtMNu59fR5zttSx + 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" +
「5MFO 1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n」 +
「1EKib1Id8hpooY5xaQID ****\n」 +
"----- END PUBLIC KEY -----";
// RSAキーペアを作成します。
RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM);
RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM);
KeyPair keyPair=新しいKeyPair(publicKey, privateKey);
// CMKの説明を指定します。 記述は、指定後に変更することはできません。 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>);
// RSAベースの暗号化用のクライアントを作成します。
OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder() 。
ビルド (endpoint, credentialsProvider, encryptionMaterials);
try {
// ビジネスコードを書きます。
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to 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 e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
} 最後に{
if (ossEncryptionClient != null) {
ossEncryptionClient.shutdown();
}
}
}
}
KMSベースの暗号化用のクライアントの作成
KMSベースの暗号化用のクライアントを作成する場合、Bouncy Castleが提供するJavaライブラリ (bcprov-jdk15on) とkmsが提供するJavaライブラリ (KMS-transfer-client) をMavenプロジェクトにインポートする必要があります。 次のサンプルコードは、kms-transfer-clientライブラリをインポートする方法の例を示しています。
<dependency>
<groupId>com.aliyun.kms</groupId>
<artifactId>kms-transfer-client</artifactId>
<version>0.1.0</version>
<scope> テスト </scope>
</dependency>
次のサンプルコードは、KMSベースの暗号化用のクライアントを作成する方法の例を示しています。
com.aliyun.oss.*;
impor t com.aliyun.oss.com mon.auth.*;
impor t com.aliyun.oss.com mon.utils.BinaryUtil;
com.aliyun.oss.crypto.ContentCryptoMaterialRWをインポートします。com.aliyun.oss.crypto.EncryptionMaterialsをインポートします。com.aliyuncs.DefaultAcsClientをインポートします。com.aliyuncs.http.FormatTypeをインポートします。com.aliyuncs.http.MethodTypeをインポートします。com.aliyuncs.http.ProtocolTypeをインポートします。com.aliyuncs.kms.mo del.v20160120.DecryptRequestをインポートします。com.aliyuncs.kms.mo del.v20160120.DecryptResponseをインポートします。com.aliyuncs.kms.mo del.v20160120.EncryptRequestをインポートします。com.aliyuncs.kms.mo del.v20160120.EncryptResponseをインポートします。com.aliyuncs.profile.DefaultProfileをインポートします。com.aliyuncs.profile.IClientProfileをインポートします。javax.crypto.SecretKeyをインポートします。javax.crypto.spec.SecretKeySpecをインポートします。java.lang.reflect.Fieldをインポートします。java.util.HashMapをインポートします。java.util.LinkedHashMapをインポートします。java.util.Mapをインポートします。public classデモ {
public static void main(String[] args) Throwable {
// この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// CMK IDを指定します。 例: e1935511-cf88-1123-a0f8-1be8d251 **** 。
文字列cmk = "e1935511-cf88-1123-a0f8-1be8d251 ****";
// CMKが属するリージョンを指定します。 例:cn-hangzhou。
文字列region = "cn-hangzhou";
// CMKの説明を指定します。 記述は、指定後に変更することはできません。 CMKに指定できる説明とリージョンは1つだけです。
// 暗号化するすべてのオブジェクトがCMKを共有する場合は、CMKの説明を空のままにすることができます。 この場合、CMKは交換できません。
// CMKの説明を空のままにすると、クライアントはどのCMKを復号化に使用するかを判断できません。
// CMKごとに説明を指定し、CMKと説明の間のマッピング関係をクライアントに保存することをお勧めします。 サーバーは関係を保存しません。
Map<String, String> matDesc = new HashMap<String, String>();
matDesc.put("desc-key", "desc-value");
// KMS暗号化マテリアルを作成します。
KmsEncryptionMaterialsV3 encryptionMaterials = new KmsEncryptionMaterialsV3(region, cmk, matDesc);
encryptionMaterials.setKmsCredentialsProvider(credentialsProvider);
// 他のCMKを使用して暗号化されたオブジェクトをダウンロードして復号化するには、CMKのリージョン名と説明をKMS暗号化マテリアルに追加します。
// encryptionMaterials.addKmsDescMaterial(<otherKmsRegion>, <otherKmsMatDesc>);
// KMSへのアクセスに使用されるアカウントとOSSへのアクセスに使用されるアカウントが異なり、他のCMKを使用して暗号化されたオブジェクトをダウンロードして復号化する場合は、CMKのリージョン名、資格情報、および説明をKMS暗号化マテリアルに追加します。
// encryptionMaterials.addKmsDescMaterial(<otherKmsRegion>, <otherKmsCredentialsProvider>, <otherKmsMatDesc>);
// クライアント側暗号化用のクライアントを作成します。
OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder() 。
ビルド (endpoint, credentialsProvider, encryptionMaterials);
try {
// ビジネスコードを書きます。
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to 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 e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
} 最後に{
if (ossEncryptionClient != null) {
ossEncryptionClient.shutdown();
}
}
}
}
クラスKmsEncryptionMaterialsV3はEncryptionMaterialsを実装します {
プライベート静的ファイナルストリングKEY_WRAP_ALGORITHM = "KMS/ALICLOUD";
private String region;
プライベート文字列cmk;
CredentialsProvider credentialsProvider;
プライベートファイナルMap<String, String> desc;
プライベートファイナルLinkedHashMap<KmsEncryptionMaterialsV3.KmsClientSuite, Map<String, String>> kmsDescMaterials=
新しいLinkedHashMap<KmsEncryptionMaterialsV3.KmsClientSuite、Map<String、String>>();
public KmsEncryptionMaterialsV3(String region, String cmk) {
assertParameterNotNull(region、"kms region");
assertParameterNotNull(cmk、"kms cmk");
this.region = region;
この. cmk = cmk;
this.de sc = new HashMap<String, String>();
}
public KmsEncryptionMaterialsV3(String region, String cmk, Map<String, String> desc) {
assertParameterNotNull(region、"kms region");
assertParameterNotNull(region、"kms cmk");
this.region = region;
この. cmk = cmk;
this.de sc = (desc == null) ? new HashMap<String, String>() : new HashMap<String, String>(desc);
}
プライベートファイナルクラスKmsClientSuite {
private String region;
プライベートCredentialsProvider credentialsProvider;
KmsClientSuite(String region, CredentialsProvider credentialsProvider) {
this.region = region;
this.credentialsProvider = credentialsProvider;
}
}
public void setKmsCredentialsProvider(CredentialsProvider) {
this.credentialsProvider = credentialsProvider;
kmsDescMaterials.put (新しいKmsEncryptionMaterialsV3.KmsClientSuite(region, credentialsProvider), desc);
}
プライベートDefaultAcsClient createKmsClient(String region, CredentialsProvider credentialsPorvider) {
Credentials credentials = credentialsPorvider.getCredentials();
IClientProfile profile = DefaultProfile.getProfile(region, credentials.getAccessKeyId(),
credentials.getSecretAccessKey(), credentials.getSecurityToken();
新しいKmsTransferAcsClient (プロファイル) を返します。
}
private EncryptResponse encryptPlainText(String keyId, String plainText) throws ClientException {
DefaultAcsClient kmsClient = createKmsClient(region, credentialsProvider);
final EncryptRequest encReq = new EncryptRequest();
encReq.setSysProtocol(ProtocolType.HTTPS);
encReq.setAcceptFormat(FormatType.JSON);
encReq.setSysMethod(MethodType.POST);
encReq.setKeyId(keyId);
encReq.setPlaintext(plainText);
最終的なEncryptResponse encResponse;
try {
encResponse = kmsClient.getAcsResponse(encReq);
} catch (Exception e) {
新しいClientExceptionをスローします (「kmsクライアントによるデータの暗号化に失敗しました」 + e.getMessage() 、e);
}
return encResponse;
}
private DecryptResponse decryptCipherBlob(KmsEncryptionMaterialsV3.KmsClientSuite kmsClientSuite, String cipherBlob)
throws ClientException {
final DefaultAcsClient kmsClient = createKmsClient(kmsClientSuite.region, kmsClientSuite.credentialsProvider);
final DecryptRequest decReq = new DecryptRequest();
decReq.setSysProtocol(ProtocolType.HTTPS);
decReq.setAcceptFormat(FormatType.JSON);
decReq.setSysMethod(MethodType.POST);
decReq.setCiphertextBlob(cipherBlob);
最終的なDecryptResponse decResponse;
try {
decResponse = kmsClient.getAcsResponse(decReq);
} catch (Exception e) {
新しいClientExceptionをスローします ("kmsクライアントはデータの失敗を解読します。" e.getMessage() 、e);
}
return decResponse;
}
public void addKmsDescMaterial(String region, Map<String, String> description) {
addKmsDescMaterial(region, credentialsProvider, 説明);
}
public synchronized void addKmsDescMaterial(String region, CredentialsProvider credentialsProvider, Map<String, String> description) {
assertParameterNotNull(region、"region");
assertParameterNotNull(credentialsProvider、"credentialsProvider");
KmsEncryptionMaterialsV3.KmsClientSuite kmsClientSuite = new KmsEncryptionMaterialsV3.KmsClientSuite(region, credentialsProvider);
if (description != null) {
kmsDescMaterials.put(kmsClientSuite、新しいHashMap <文字列、文字列> (説明));
} else {
kmsDescMaterials.put(kmsClientSuite, new HashMap<String, String>());
}
}
プライベートKmsEncryptionMaterialsV3.KmsClientSuite findKmsClientSuiteByDescription(Map<String, String> desc) {
if (desc == null) {
ヌルを返します。
}
for (Map.Entry<KmsEncryptionMaterialsV3.KmsClientSuite, Map<String, String>> エントリ: kmsDescMaterials.entrySet()) {
if (desc.equals(entry.getValue())) {
return entry.getKey();
}
}
ヌルを返します。
}
プライベート <K, V> Map.Entry<K, V> getTailByReflection(LinkedHashMap<K, V> map)
NoSuchFieldException、IllegalAccessExceptionをスロー {
Field tail = map.getClass().getDeclaredField("tail");
tail.setAccessible(true);
リターン (Map.Entry<K, V>) tail.get(map);
}
@オーバーライド
public void encryptCEK(ContentCryptoMaterialRW contentMaterialRW) {
try {
assertParameterNotNull(contentMaterialRW、"contentMaterialRW");
assertParameterNotNull(contentMaterialRW.getIV() 、"contentMaterialRW#getIV");
assertParameterNotNull(contentMaterialRW.getCEK() 、"contentMaterialRW#getCEK");
byte[] iv = contentMaterialRW.getIV();
EncryptResponse encryptresponse = encryptPlainText(cmk, BinaryUtil.toBase64String(iv));
byte[] encryptedIV = BinaryUtil.fromBase64String(encryptresponse.getCiphertextBlob());
SecretKey cek = contentMaterialRW.getCEK();
encryptresponse = encryptPlainText(cmk, BinaryUtil.toBase64String(cek.getEncoded()));
byte[] encryptedCEK = BinaryUtil.fromBase64String(encryptresponse.getCiphertextBlob());
contentMaterialRW.setEncryptedCEK(encryptedCEK);
contentMaterialRW.setEncryptedIV(encryptedIV);
contentMaterialRW.setKeyWrapAlgorithm(KEY_WRAP_ALGORITHM);
contentMaterialRW.setMaterialsDescription(desc);
} catch (Exception e) {
新しいClientExceptionをスローします ("KmsはCEK IVエラーを暗号化します。 "
+ 「cmk、region、accessKeyId、accessSecretIdを確認してください。」 + e.getMessage() 、e);
}
}
@オーバーライド
public void decryptCEK(ContentCryptoMaterialRW contentMaterialRW) {
assertParameterNotNull(contentMaterialRW、"ContentCryptoMaterialRW");
assertParameterNotNull(contentMaterialRW.getEncryptedCEK() 、"ContentCryptoMaterialRW#getEncryptedCEK");
assertParameterNotNull(contentMaterialRW.getEncryptedIV() 、"ContentCryptoMaterialRW#getEncryptedIV");
assertParameterNotNull(contentMaterialRW.getKeyWrapAlgorithm() 、"ContentCryptoMaterialRW#getKeyWrapAlgorithm");
if (!contentMaterialRW.getKeyWrapAlgorithm().toLowerCase().equals(KEY_WRAP_ALGORITHM.toLowerCase())) {
新しいClientExceptionを投げる (
"オブジェクトキーのラップアルゴリズムを認識しない:" + contentMaterialRW.getKeyWrapAlgorithm();
}
try {
KmsEncryptionMaterialsV3.KmsClientSuite kmsClientSuite = findKmsClientSuiteByDescription(contentMaterialRW.getMaterialsDescription());
if (kmsClientSuite == null) {
Map.Entry<KmsEncryptionMaterialsV3.KmsClientSuite, Map<String, String>> entry = getTailByReflection(kmsDescMaterials);
kmsClientSuite = entry.getKey();
}
DecryptResponse decryptIvResp = decryptCipherBlob(kmsClientSuite、
BinaryUtil.toBase64String(contentMaterialRW.getEncryptedIV());
byte[] iv = BinaryUtil.fromBase64String(decryptIvResp.getPlaintext());
DecryptResponse decryptCEKResp = decryptCipherBlob(kmsClientSuite、
BinaryUtil.toBase64String(contentMaterialRW.getEncryptedCEK());
byte[] cekBytes = BinaryUtil.fromBase64String(decryptCEKResp.getPlaintext());
SecretKey cek=新しいSecretKeySpec(cekBytes、"");
contentMaterialRW.setCEK(cek);
contentMaterialRW.setIV(iv);
} catch (Exception e) {
throw new ClientException("コンテンツ保護鍵を復号化できず、iv. "
「kms地域とmaterailsの説明を確認してください。」 + e.getMessage() 、e);
}
}
private void assertParameterNotNull(Object parameterValue, String errorMessage) {
if (parameterValue == null)
新しいIllegalArgumentException(errorMessage) を投げる。
}
}
次のセクションでは、顧客管理CMK (RSAベース) を使用して、単純なアップロードとダウンロード、マルチパートアップロード、および範囲ダウンロードでクライアント側の暗号化を実行するための完全なサンプルコードを示します。
KMSベースのクライアント側暗号化は、RSAベースのクライアント側暗号化とは、OSSEncryptionClientの作成のみが異なります。
簡単なアップロードとダウンロードでRSAベースのクライアント側暗号化を実行する
次のサンプルコードでは、CMKを使用して単純なアップロードでオブジェクトを暗号化し、単純なダウンロードでオブジェクトを復号化する方法の例を示します。
com.aliyun.oss.*;
impor t com.aliyun.oss.com mon.auth.*;
com.aliyun.oss.crypto.SimpleRSAEncryptionMaterialsをインポートします。com.aliyun.oss.mo del.OSSObjectをインポートします。java.io.BufferedReaderをインポートします。java.io.ByteArrayInputStreamをインポートします。java.io.InputStreamReaderをインポートします。java.security.KeyPairをインポートします。java.security.int erfaces.RSAPrivateKeyをインポートします。java.security.int erfaces.RSAPublicKeyをインポートします。java.util.HashMapをインポートします。java.util.Mapをインポートします。public classデモ {
public static void main(String[] args) 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。 バケット名をフルパスに含めないでください。
文字列objectName = "exampleobject.txt";
String content = "Hello OSS!";
// RSA秘密鍵文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA秘密鍵文字列のサンプルを示しています。
final文字列PRIVATE_PKCS1_PEM=
"----- BEGIN RSA PRIVATE KEY -----\n" +
「MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n」 +
"ttSx 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO 1PByrE/MNd5AAfSVba93\n"
「I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n」 +
「AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n」 +
"nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" +
「JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n」 +
「36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n」 +
「6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw 4/a8vZm2tXXK/QfTQrJVXp\n」 +
「VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n」
"gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs + d5Tv4Cvquk0efOQJAd9OC\n" +
「lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n」 +
「Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG 7/S7Z74gyq5qZF4FUElOAZkz123E\n」 +
"yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo ****\n" +
"----- END RSAプライベートキー -----";
// RSA公開キー文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA公開キー文字列のサンプルを示します。
final String PUBLIC_X509_PEM=
「 ----- 公開キーを開始 ----- 」
「MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw XO/UByW\n」 +
"6mse2QsIgz3ZwBtMNu59fR5zttSx + 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" +
「5MFO 1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n」 +
「1EKib1Id8hpooY5xaQID ****\n」 +
"----- END PUBLIC KEY -----";
// RSAキーペアを作成します。
RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM);
RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM);
KeyPair keyPair=新しいKeyPair(publicKey, privateKey);
// CMKの説明を指定します。 記述は、指定後に変更することはできません。 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>);
// クライアント側暗号化用のクライアントを作成します。
OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder() 。
ビルド (endpoint, credentialsProvider, encryptionMaterials);
try {
// オブジェクトを暗号化してアップロードします。
ossEncryptionClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
// Download the object. オブジェクトは自動的に復号化されます。
OSSObject ossObject = ossEncryptionClient.getObject(bucketName, objectName);
BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
StringBuffer buffer = new StringBuffer();
文字列ライン;
while (((line = reader.readLine())) != null) {
buffer.append (ライン);
}
reader.close();
// 復号化されたコンテンツが、平文でアップロードされたオブジェクトと同じかどうかを確認します。
System.out.println("Put plain text: " + content);
System.out.println("Get and decrypted text: " + buffer.toString());
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to 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 e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
} 最後に{
if (ossEncryptionClient != null) {
ossEncryptionClient.shutdown();
}
}
}
}
マルチパートアップロードでRSAベースのクライアント側暗号化を実行する
次のサンプルコードは、顧客管理CMK (RSAベース) を使用してマルチパートアップロードでオブジェクトを暗号化する方法の例を示しています。
com.aliyun.oss.*;
impor t com.aliyun.oss.com mon.auth.*;
com.aliyun.oss.crypto.MultipartUploadCryptoContextをインポートします。com.aliyun.oss.crypto.SimpleRSAEncryptionMaterialsをインポートします。com.aliyun.oss.mo delをインポートします。*;
java.io.* をインポートします。java.security.KeyPairをインポートします。java.security.int erfaces.RSAPrivateKeyをインポートします。java.security.int erfaces.RSAPublicKeyをインポートします。java.util.ArrayListをインポートします。java.util.HashMapをインポートします。java.util.Listをインポートします。java.util.Mapをインポートします。public classデモ {
public static void main(String[] args) 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。 バケット名をフルパスに含めないでください。
文字列objectName = "exampleobject.txt";
// ローカルファイルのフルパスを指定します。 例: D :\\ localpath\\examplefile.txt。
String localFile = "D :\\ localpath\\examplefile.txt";
// RSA秘密鍵文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA秘密鍵文字列のサンプルを示しています。
final文字列PRIVATE_PKCS1_PEM=
"----- BEGIN RSA PRIVATE KEY -----\n" +
「MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n」 +
"ttSx 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO 1PByrE/MNd5AAfSVba93\n"
「I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n」 +
「AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n」 +
"nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" +
「JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n」 +
「36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n」 +
「6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw 4/a8vZm2tXXK/QfTQrJVXp\n」 +
「VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n」
"gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs + d5Tv4Cvquk0efOQJAd9OC\n" +
「lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n」 +
「Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG 7/S7Z74gyq5qZF4FUElOAZkz123E\n」 +
"yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo ****\n" +
"----- END RSAプライベートキー -----";
// RSA公開キー文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA公開キー文字列のサンプルを示します。
final String PUBLIC_X509_PEM=
「 ----- 公開キーを開始 ----- 」
「MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw XO/UByW\n」 +
"6mse2QsIgz3ZwBtMNu59fR5zttSx + 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" +
「5MFO 1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n」 +
「1EKib1Id8hpooY5xaQID ****\n」 +
"----- END PUBLIC KEY -----";
// RSAキーペアを作成します。
RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM);
RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM);
KeyPair keyPair=新しいKeyPair(publicKey, privateKey);
// CMKの説明を指定します。 記述は、指定後に変更することはできません。 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>);
// クライアント側暗号化用のクライアントを作成します。
OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder() 。
ビルド (endpoint, credentialsProvider, encryptionMaterials);
try {
// MultipartUploadCryptoContextオブジェクトを作成し、オブジェクトサイズとパーツサイズを指定します。 部品サイズは16バイトの倍数でなければなりません。
File file = new File(localFile);
long fileLength = file.length();
final long partSize = 100 * 1024L; // 100K
MultipartUploadCryptoContextコンテキスト=新しいMultipartUploadCryptoContext();
context.setPartSize(partSize);
context.setDataSize(fileLength);
// マルチパートアップロードタスクを開始します。
InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(bucketName, objectName);
// 作成したMultipartUploadCryptoContextオブジェクトを使用します。
InitiateMultipartUploadResult upressult=ossEncryptionClient.initiateMultipartUpload(initiateMultipartUploadRequest、コンテキスト);
String uploadId = upresult.getUploadId();
// PartETagsのコレクションを作成します。 PartETagは、部品番号と部品のETagで構成されます。
List<PartETag> partETags = new ArrayList<PartETag>();
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
// オブジェクトのすべての部分をアップロードします。
for (int i = 0; i <recordCount; i ++ ) {
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
InputStream instream = new FileInputStream (ファイル);
instream.skip(startPos);
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setInputStream(instream);
uploadPartRequest.setPartSize(curPartSize);
uploadPartRequest.setPartNumber( i + 1);
// 作成したMultipartUploadCryptoContextオブジェクトを使用します。
UploadPartResult uploadPartResult = ossEncryptionClient.uploadPart(uploadPartRequest、コンテキスト);
partETags.add(uploadPartResult.getPartETag());
}
// マルチパートアップロードタスクを完了します。
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
ossEncryptionClient.com pleteMultipartUpload(completeMultipartUploadRequest);
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to 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 e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
} 最後に{
if (ossEncryptionClient != null) {
ossEncryptionClient.shutdown();
}
}
}
}
再開可能アップロードでRSAベースのクライアント側暗号化を実行する
次のサンプルコードは、顧客管理CMK (RSAベース) を使用して再開可能なアップロードでオブジェクトを暗号化する方法の例を示しています。
com.aliyun.oss.*;
impor t com.aliyun.oss.com mon.auth.*;
com.aliyun.oss.crypto.SimpleRSAEncryptionMaterialsをインポートします。com.aliyun.oss.mo delをインポートします。*;
java.security.KeyPairをインポートします。java.security.int erfaces.RSAPrivateKeyをインポートします。java.security.int erfaces.RSAPublicKeyをインポートします。java.util.HashMapをインポートします。java.util.Mapをインポートします。public classデモ {
public static void main(String[] args) 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。 バケット名をフルパスに含めないでください。
文字列objectName = "exampleobject.txt";
// ローカルファイルのフルパスを指定します。 例: D :\\ localpath\\examplefile.txt。
String localFile = "D :\\ localpath\\examplefile.txt";
// RSA秘密鍵文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA秘密鍵文字列のサンプルを示しています。
final文字列PRIVATE_PKCS1_PEM=
"----- BEGIN RSA PRIVATE KEY -----\n" +
「MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n」 +
"ttSx 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO 1PByrE/MNd5AAfSVba93\n"
「I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n」 +
「AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n」 +
"nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" +
「JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n」 +
「36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n」 +
「6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw 4/a8vZm2tXXK/QfTQrJVXp\n」 +
「VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n」
"gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs + d5Tv4Cvquk0efOQJAd9OC\n" +
「lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n」 +
「Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG 7/S7Z74gyq5qZF4FUElOAZkz123E\n」 +
"yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo ****\n" +
"----- END RSAプライベートキー -----";
// RSA公開キー文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA公開キー文字列のサンプルを示します。
final String PUBLIC_X509_PEM=
「 ----- 公開キーを開始 ----- 」
「MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw XO/UByW\n」 +
"6mse2QsIgz3ZwBtMNu59fR5zttSx + 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" +
「5MFO 1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n」 +
「1EKib1Id8hpooY5xaQID ****\n」 +
"----- END PUBLIC KEY -----";
// RSAキーペアを作成します。
RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM);
RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM);
KeyPair keyPair=新しいKeyPair(publicKey, privateKey);
// CMKの説明を指定します。 記述は、指定後に変更することはできません。 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>);
// クライアント側暗号化用のクライアントを作成します。
OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder() 。
ビルド (endpoint, credentialsProvider, encryptionMaterials);
try {
// UploadFileRequestオブジェクトを作成します。
UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, objectName);
// アップロードするオブジェクトのパスを指定します。
uploadFileRequest.setUploadFile(localFile);
// パーツサイズを指定します。 有効なパーツサイズは100 KB〜5 GBです。 デフォルトのパーツサイズは、オブジェクトサイズの1万分の1です。
uploadFileRequest.setPartSize(100*1024);
// 再開可能アップロードを有効にするかどうかを指定します。 デフォルトでは、再開可能アップロードは無効になっています。
uploadFileRequest.setEnableCheckpoint(true);
// チェックポイントファイルの名前を指定します。 チェックポイントファイルの名前を指定しない場合、デフォルトのチェックポイントファイル名は "localfile.ucp" 形式に従います。 デフォルトのチェックポイントファイルは、アップロードするローカルファイルと同じディレクトリにあります。
// このファイルには、アップロードの進行状況に関する情報が格納されます。 パーツのアップロードに失敗した場合、記録された進行状況に基づいてパーツのアップロードが続行されます。 オブジェクトがアップロードされると、チェックポイントファイルは削除されます。
uploadFileRequest.setCheckpointFile("test-upload.ucp");
// Start resumable upload.
ossEncryptionClient.uploadFile(uploadFileRequest);
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to 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 e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
} 最後に{
if (ossEncryptionClient != null) {
ossEncryptionClient.shutdown();
}
}
}
}
RSAベースのクライアント側暗号化を使用して、再開可能なダウンロードでオブジェクトを復号化する
次のサンプルコードは、顧客管理CMK (RSAベース) を使用して再開可能なダウンロードでオブジェクトを復号化する方法の例を示しています。
com.aliyun.oss.*;
impor t com.aliyun.oss.com mon.auth.*;
com.aliyun.oss.crypto.SimpleRSAEncryptionMaterialsをインポートします。com.aliyun.oss.mo delをインポートします。*;
java.security.KeyPairをインポートします。java.security.int erfaces.RSAPrivateKeyをインポートします。java.security.int erfaces.RSAPublicKeyをインポートします。java.util.HashMapをインポートします。java.util.Mapをインポートします。public classデモ {
public static void main(String[] args) 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。 バケット名をフルパスに含めないでください。
文字列objectName = "exampleobject.txt";
// RSA秘密鍵文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA秘密鍵文字列のサンプルを示しています。
final文字列PRIVATE_PKCS1_PEM=
"----- BEGIN RSA PRIVATE KEY -----\n" +
「MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n」 +
"ttSx 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO 1PByrE/MNd5AAfSVba93\n"
「I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n」 +
「AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n」 +
"nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" +
「JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n」 +
「36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n」 +
「6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw 4/a8vZm2tXXK/QfTQrJVXp\n」 +
「VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n」
"gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs + d5Tv4Cvquk0efOQJAd9OC\n" +
「lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n」 +
「Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG 7/S7Z74gyq5qZF4FUElOAZkz123E\n」 +
"yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo ****\n" +
"----- END RSAプライベートキー -----";
// RSA公開キー文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA公開キー文字列のサンプルを示します。
final String PUBLIC_X509_PEM=
「 ----- 公開キーを開始 ----- 」
「MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw XO/UByW\n」 +
"6mse2QsIgz3ZwBtMNu59fR5zttSx + 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" +
「5MFO 1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n」 +
「1EKib1Id8hpooY5xaQID ****\n」 +
"----- END PUBLIC KEY -----";
// RSAキーペアを作成します。
RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM);
RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM);
KeyPair keyPair=新しいKeyPair(publicKey, privateKey);
// CMKの説明を指定します。 記述は、指定後に変更することはできません。 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>);
// クライアント側暗号化用のクライアントを作成します。
OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder() 。
ビルド (endpoint, credentialsProvider, encryptionMaterials);
try {
// 10回のダウンロードタスクが同時に実行される再開可能ダウンロードを開始するリクエストを送信します。
DownloadFileRequest downloadFileRequest = new DownloadFileRequest(bucketName, objectName);
downloadFileRequest.setDownloadFile("<yourDownloadFile>");
downloadFileRequest.setPartSize(1 * 1024 * 1024);
downloadFileRequest.setTaskNum(10);
downloadFileRequest.setEnableCheckpoint(true);
downloadFileRequest.setCheckpointFile("<yourCheckpointFile>");
// Start resumable download.
DownloadFileResult downloadRes = ossEncryptionClient.downloadFile(downloadFileRequest);
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to 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 e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
} 最後に{
if (ossEncryptionClient != null) {
ossEncryptionClient.shutdown();
}
}
}
}
RSAベースのクライアント側暗号化を使用して、範囲ダウンロードでオブジェクトを復号化する
次のサンプルコードは、顧客管理CMK (RSAベース) を使用して、範囲ダウンロード内のオブジェクトを復号化する方法の例を示しています。
com.aliyun.oss.*;
impor t com.aliyun.oss.com mon.auth.*;
com.aliyun.oss.crypto.SimpleRSAEncryptionMaterialsをインポートします。com.aliyun.oss.mo delをインポートします。*;
java.io.BufferedReaderをインポートします。java.io.ByteArrayInputStreamをインポートします。java.io.InputStreamReaderをインポートします。java.security.KeyPairをインポートします。java.security.int erfaces.RSAPrivateKeyをインポートします。java.security.int erfaces.RSAPublicKeyをインポートします。java.util.HashMapをインポートします。java.util.Mapをインポートします。public classデモ {
public static void main(String[] args) 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。 バケット名をフルパスに含めないでください。
文字列objectName = "exampleobject.txt";
String content = "test-range-get-content-82042795hlnf12s8yhfs976y2nfoshhnsdfsf235bvsmnhtskbcfd!";
// RSA秘密鍵文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA秘密鍵文字列のサンプルを示しています。
final文字列PRIVATE_PKCS1_PEM=
"----- BEGIN RSA PRIVATE KEY -----\n" +
「MIICWwIBAAKBgQCokfiAVXXf5ImFzKDw XO/UByW6mse2QsIgz3ZwBtMNu59fR5z\n」 +
"ttSx 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC5MFO 1PByrE/MNd5AAfSVba93\n"
「I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MmR1EKib1Id8hpooY5xaQIDAQAB\n」 +
「AoGAOPUZgkNeEMinrw31U3b2JS5sepG6oDG2CKpPu8OtdZMaAkzEfVTJiVoJpP2Y\n」 +
"nPZiADhFW3e0ZAnak9BPsSsySRaSNmR465cG9tbqpXFKh9Rp/sCPo4Jq2n65yood\n" +
「JBrnGr6/xhYvNa14sQ6xjjfSgRNBSXD1XXNF4kALwgZyCAECQQDV7t4bTx9FbEs5\n」 +
「36nAxPsPM6aACXaOkv6d9LXI7A0J8Zf42FeBV6RK0q7QG5iNNd1WJHSXIITUizVF\n」 +
「6aX5NnvFAkEAybeXNOwUvYtkgxF4s28s6gn11c5HZw 4/a8vZm2tXXK/QfTQrJVXp\n」 +
「VwxmSr0FAajWAlcYN/fGkX1pWA041CKFVQJAG08ozzekeEpAuByTIOaEXgZr5MBQ\n」
"gBbHpgZNBl8Lsw9CJSQI15wGfv6yDiLXsH8FyC9TKs + d5Tv4Cvquk0efOQJAd9OC\n" +
「lCKFs48hdyaiz9yEDsc57PdrvRFepVdj/gpGzD14mVerJbOiOF6aSV19ot27u4on\n」 +
「Td/3aifYs0CveHzFPQJAWb4LCDwqLctfzziG 7/S7Z74gyq5qZF4FUElOAZkz123E\n」 +
"yZvADwuz/4aK0od0lX9c4Jp7Mo5vQ4TvdoBnPuGo ****\n" +
"----- END RSAプライベートキー -----";
// RSA公開キー文字列を指定します。 OpenSSLを使用して文字列を生成できます。 次の行は、RSA公開キー文字列のサンプルを示します。
final String PUBLIC_X509_PEM=
「 ----- 公開キーを開始 ----- 」
「MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokfiAVXXf5ImFzKDw XO/UByW\n」 +
"6mse2QsIgz3ZwBtMNu59fR5zttSx + 8fB7vR4CN3bTztrP9A6bjoN0FFnhlQ3vNJC\n" +
「5MFO 1PByrE/MNd5AAfSVba93I6sx8NSk5MzUCA4NJzAUqYOEWGtGBcom6kEF6MnR\n」 +
「1EKib1Id8hpooY5xaQID ****\n」 +
"----- END PUBLIC KEY -----";
// RSAキーペアを作成します。
RSAPrivateKey privateKey = SimpleRSAEncryptionMaterials.getPrivateKeyFromPemPKCS1(PRIVATE_PKCS1_PEM);
RSAPublicKey publicKey = SimpleRSAEncryptionMaterials.getPublicKeyFromPemX509(PUBLIC_X509_PEM);
KeyPair keyPair=新しいKeyPair(publicKey, privateKey);
// CMKの説明を指定します。 記述は、指定後に変更することはできません。 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>);
// クライアント側暗号化用のクライアントを作成します。
OSSEncryptionClient ossEncryptionClient = new OSSEncryptionClientBuilder() 。
ビルド (endpoint, credentialsProvider, encryptionMaterials);
try {
// オブジェクトを暗号化してアップロードします。
ossEncryptionClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
// Start range download.
int start = 17;
int end = 35;
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName);
getObjectRequest.setRange(start、end);
OSSObject ossObject = ossEncryptionClient.getObject(getObjectRequest);
BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
StringBuffer buffer = new StringBuffer();
文字列ライン;
while (((line = reader.readLine())) != null) {
buffer.append (ライン);
}
reader.close();
// ダウンロードしたデータを表示します。
System.out.println("Range-プレーンテキストを取得する:" + content.substring(start, end + 1));
System.out.println("Range-復号化されたテキストを取得する:" + buffer.toString());
} catch (Exception e) {
System.out.println("Caught an OSSException, which means your request made it to 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 e) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ 「ネットワークにアクセスできないなど」;
System.out.println("エラーメッセージ:" + ce.getMessage());
} 最後に{
if (ossEncryptionClient != null) {
ossEncryptionClient.shutdown();
}
}
}
}
参考資料
クライアント側の暗号化の実行に使用される完全なサンプルコードについては、『GitHub』をご参照ください。