この記事の目次
AWSのCSEとは?
AWSのCSE(Client Side Encryption)とは、ユーザーがオブジェクトを暗号化し、セキュリティを強化する方式のことを言います。この方式では自身でキーを作成し、ユーザー以外には解読不可能なオブジェクトをS3に登録することができます。
S3の暗号化方式にはキーの作成・管理、オブジェクトの暗号化がサーバーサイド側かクライアント側かによって分類されます。今回、紹介する方式はクライアント側で暗号化するソリューションであり、AWS SDKの機能として提供されています。
AWSのCSEを使用する上での注意点
AWSのCSEはセキュリティを高めることに大変有能なシステムですが、使用する上で注意しておくべきことがいくつかあります。
ここで、どのような点に注意したらよいのかを確認しておきましょう。
キーの管理を徹底しておく
暗号化するキーの管理はユーザー自身で行わなければなりません。
そのため、Amazon CloudHSMやHSMsなどのセキュリティモジュールを使用することをおすすめします。
暗号化の種別を知っておく必要がある
登録されたオブジェクトは暗号の種別を知らなければ、暗号化されているかどうかを確認することができません。
AWSのCSEを使用する前には、暗号化の種別を理解しておきましょう。
暗号化と種別の強制ができない
同じキーに対しては、オブジェクトが暗号化されているかどうかに関わらず、上書きすることができます。よって、他の人がオブジェクトを登録していた場合にオブジェクトの取得ができないことがあります。
このような場合は、AWSのCSEを強制させるためにBucketポリシーを設定する必要があります。
AWSのCSEの使用方法
ここでは、AWSのCSEの使用方法を実際のコードを見ながら説明していきます。
暗号化キーの作成から、暗号化したもののアップロード方法などを使用前に確認しておきましょう。
暗号化キーの作成
暗号化のためのキーを作成するコードを確認しておきましょう。
public class GenerateSymmetricMasterKey {
private static final String keyDir = "<キーファイルのディレクトリを指定>";
private static final String keyName = "secret.key";
public static void main(String[] args) throws Exception {
//Generate symmetric 256 bit AES key.
KeyGenerator symKeyGenerator = KeyGenerator.getInstance("AES");
symKeyGenerator.init(256);
SecretKey symKey = symKeyGenerator.generateKey();
//Save key.
saveSymmetricKey(keyDir, symKey);
//Base64 Encoded String.
String encoded = Base64.getEncoder().encodeToString(symKey.getEncoded());
System.out.println(encoded);
}
public static void saveSymmetricKey(String path, SecretKey secretKey)
throws IOException {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
secretKey.getEncoded());
FileOutputStream keyfos = new FileOutputStream(path + "/" + keyName);
keyfos.write(x509EncodedKeySpec.getEncoded());
keyfos.close();
}
}
CSEの暗号化ファイルをS3にアップロード
AWSで暗号化したCSEのファイルをS3にアップロードする方法を紹介します。コード内の「秘密鍵のファイルパス」「バケット名」「キー名」「アップロードするファイルパス」は自分の環境にあったものに書き換えてください。
/** 秘密鍵ファイルのパス */
private static final String symmetricKeyPath = "<秘密鍵のファイルパス>";
/** バケット名(ex. cm-bucket) */
private static final String bucketName = "<バケット名>";
/** キー名(ex. users.csv) */
private static final String key = "<ファイル名もしくはファイルパス>";
/** アップロードするファイルパス */
private static final String uploadPath = "<アップロードするファイルパス>";
public static void main(String[] args) {
try {
// オブジェクトの生成
S3ClientSideEncryption s3cse = new S3ClientSideEncryption(symmetricKeyPath);
System.out.println("master_symmetric_key: " + s3cse.getSymmetricKeyBase64());
// ファイルのS3アップロード
File uploadFile = new File(uploadPath);
if (uploadFile.exists()) {
PutObjectResult result = s3cse.putFile(bucketName, key, uploadFile);
if (result == null) {
System.err.println("Upload failed.");
} else {
System.out.println("Upload success.");
}
} else {
System.err.println("File not found.:" + uploadPath);
}
} catch (Exception e) {
e.printStackTrace();
}
}
S3の暗号化ファイルをCSEにアップロード
AWSで暗号化したS3のファイルをCSEにアップロードする方法を紹介します。コード内の「秘密鍵のファイルパス」「バケット名」「キー名」「アップロードするファイルパス」は自分の環境にあったものに書き換えてください。
/** 秘密鍵ファイルのパス */
private static final String symmetricKeyPath = "<秘密鍵のファイルパス>";
/** バケット名(ex. cm-bucket) */
private static final String bucketName = "<バケット名>";
/** キー名(ex. users.csv) */
private static final String key = "<ファイル名もしくはファイルパス>";
/** ダウンロードするファイルパス */
private static final String downloadPath = "<ダウンロードするファイルパス>";
public static void main(String[] args) {
try {
// オブジェクトの生成
S3ClientSideEncryption s3cse = new S3ClientSideEncryption(symmetricKeyPath);
// S3ファイルのダウンロード
File downloadFile = new File(downloadPath);
long fileSize = s3cse.getFile(bucketName, key, downloadFile);
if (fileSize >= 0) {
System.out.println("Download Success.:" + downloadFile.getPath());
} else {
System.err.println("Download Failed.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
AWSのCSEを使って、セキュリティを強化しよう!
いかがだったでしょうか?
この記事では、AWSのCSEの利点や使用方法について説明しました。効率的な暗号化ができるAWSのCSEですが、キーの管理を徹底しなければ他人にアクセスされてしまう恐れがあります。
AWSのCSEを利用する際は、キーの管理を徹底しましょう。