

# 署名付き URL と署名付き Cookie を使用したプライベートコンテンツを提供する
<a name="PrivateContent"></a>

インターネット経由でコンテンツを配信する多くの企業が、選ばれたユーザー (料金を支払っているユーザーなど) のドキュメント、ビジネスデータ、メディアストリーム、またはコンテンツに対して、アクセスを制限する必要があると考えています。CloudFront を使用してこのプライベートコンテンツを安全に供給するには、以下の方法を使用できます。
+ 特別な CloudFront 署名付き URL または署名付き Cookie を使用してプライベートコンテンツにアクセスするようユーザーに要求します。
+ オリジンサーバー (Amazon S3 やプライベート HTTPサーバーなど) 上のコンテンツに直接アクセスするURLではなく、CloudFront の URLを使用してコンテンツにアクセスするようユーザーに要求します。CloudFront URL を要求する必要はありませんが、ユーザーが署名付き URL や署名付き Cookie で指定された制限をバイパスすることを防ぐため、この方法をお勧めします。

詳細については、「[ファイルへのアクセスを制限する](private-content-overview.md)」を参照してください。

## プライベートコンテンツを提供する方法
<a name="private-content-task-list"></a>

プライベートコンテンツを供給するように CloudFront を構成するには、以下のタスクを実行します。

1. (オプション。ただし、推奨) ユーザーが CloudFront 経由でのみコンテンツにアクセスするようにします。使用する方法は、Amazon S3 を使用するかカスタムオリジンを使用するかによって異なります。
   + **Amazon S3** – 「[Amazon S3 オリジンへのアクセスを制限する](private-content-restricting-access-to-s3.md)」を参照してください。
   + **カスタムオリジン** – 「[カスタムオリジンのファイルへのアクセスを制限する](private-content-overview.md#forward-custom-headers-restrict-access)」を参照してください。

   カスタムオリジンには、Amazon EC2、ウェブサイトエンドポイントとして設定されている Amazon S3 バケット、Elastic Load Balancing、独自の HTTP ウェブサーバーなどがあります。

1. 署名付き URL または署名付き Cookie の作成に使用する*信頼されたキーグループ*または*信頼された署名者*を指定します。信頼されたキーグループを使用することをお勧めします。詳細については、「[署名付き URL と署名付き Cookie を作成できる署名者を指定する](private-content-trusted-signers.md)」を参照してください。

1. 署名付き URL または署名付き Cookie を設定する `Set-Cookie` ヘッダーを使用した、承認されたユーザーからのリクエストに対応するアプリケーションを記述します。以下のいずれかのトピックの手順に従ってください。
   + [署名付き URL を使用する](private-content-signed-urls.md)
   + [署名付き Cookie を使用する](private-content-signed-cookies.md)

   使用する方法が明確でない場合は、「[署名付き URL を使用するか、署名付き Cookie を使用するかを決定する](private-content-choosing-signed-urls-cookies.md)」を参照してください。

**Topics**
+ [

## プライベートコンテンツを提供する方法
](#private-content-task-list)
+ [

# ファイルへのアクセスを制限する
](private-content-overview.md)
+ [

# 署名付き URL と署名付き Cookie を作成できる署名者を指定する
](private-content-trusted-signers.md)
+ [

# 署名付き URL を使用するか、署名付き Cookie を使用するかを決定する
](private-content-choosing-signed-urls-cookies.md)
+ [

# 署名付き URL を使用する
](private-content-signed-urls.md)
+ [

# 署名付き Cookie を使用する
](private-content-signed-cookies.md)
+ [

# Linux コマンドおよび OpenSSL を使用した Base64 エンコードおよび暗号化
](private-content-linux-openssl.md)
+ [

# 署名付き URL の署名を作成するためのコード例
](PrivateCFSignatureCodeAndExamples.md)

# ファイルへのアクセスを制限する
<a name="private-content-overview"></a>

プライベートコンテンツへのユーザーアクセスは 2 つの方法を使用して制御可能です。
+ [CloudFront キャッシュ内のファイルへのアクセスを制限します](#private-content-overview-edge-caches)。
+ 次のいずれかを実行して、オリジン内のファイルへのアクセスを制限します。
  + [Amazon S3 バケットのオリジンアクセスコントロール (OAC) のセットアップ](private-content-restricting-access-to-s3.md)
  + [プライベート HTTP サーバー (カスタムオリジン) のカスタムヘッダーの設定](#forward-custom-headers-restrict-access)

## CloudFront キャッシュ内のファイルへのアクセスを制限する
<a name="private-content-overview-edge-caches"></a>

ユーザーがファイルにアクセスする際に、*署名付き URL* または*署名付き Cookie* の使用が求められるように CloudFront を設定することができます。次に、署名付き URL を作成して認証されたユーザーに配信するか、認証されたユーザーの署名付き Cookie を設定する `Set-Cookie` ヘッダーを送信するアプリケーションを開発します (少数のファイルへの長期的なアクセスを数人のユーザーに付与するために、署名付き URL を手動で作成することもできます)。

ファイルへのアクセスを制御するための署名付き URL または署名付き Cookie を作成するときに、次の制限を指定できます。
+ 最終日時。この日時以降、URL が有効ではなくなります。
+ (オプション) URL が有効になる日時。
+ (オプション) コンテンツへのアクセスに使用可能なコンピュータの IP アドレスまたはアドレス範囲。

署名付き URL または署名付き Cookie では、パブリックとプライベートのキーペアのプライベートキーを使用して、一部がハッシュ化され、署名が行われます。ユーザーが署名付き URL や署名付き Cookie を使用してファイルにアクセスすると、CloudFront は URL や Cookie の署名部分と無署名部分を比較します。これらが一致しない場合、CloudFront はファイルを供給しません。

URL または Cookie の署名には、RSA 2048 または ECDSA 256 プライベートキーを使用する必要があります。

## Amazon S3 バケット内のファイルへのアクセスを制限する
<a name="private-content-overview-s3"></a>

オプションで、Amazon S3 バケット内のコンテンツを保護することで、ユーザーが指定された CloudFront ディストリビューションを介してアクセスできても、Amazon S3 URL を使用して直接アクセスすることはできないように設定できます。これにより、アクセスを制限するコンテンツについては、CloudFront のバイパスと Amazon S3 URL の使用による取得を防止できます。署名付き URL を使用するためにこの手順を実行する必要はありませんが、推奨します。

CloudFront URL を使用してコンテンツにアクセスすることをユーザーに要求するには、次のタスクを実行します。
+ CloudFront に、S3 バケット内のファイルを読み取る*オリジンアクセスコントロール*アクセス許可を付与します。
+ オリジンアクセスコントロールを作成し、CloudFront ディストリビューションに関連付けます。
+ Amazon S3 URL を使用してファイルを読み取るためのアクセス許可を、他のすべてのユーザーから削除します。

詳細については、「[Amazon S3 オリジンへのアクセスを制限する](private-content-restricting-access-to-s3.md)」を参照してください。

## カスタムオリジンのファイルへのアクセスを制限する
<a name="forward-custom-headers-restrict-access"></a>

カスタムオリジンを使用する場合は、カスタムヘッダーをオプションで設定して、アクセスを制限できます。CloudFront がカスタムオリジンからファイルを取得するには、標準の HTTP (または HTTPS) リクエストを使用して CloudFront からファイルにアクセスできる必要があります。しかし、カスタムヘッダーを使用することで、コンテンツへのアクセスをさらに制限して、ユーザーが直接アクセスするのではなく CloudFront を通してのみアクセスできるようにすることができます。署名付き URL を使用するためにこの手順を実行する必要はありませんが、推奨します。

ユーザーに CloudFront を経由してコンテンツにアクセスするよう要求するには、CloudFront ディストリビューションで次の設定を変更します。

**オリジンのカスタムヘッダー**  
カスタムヘッダーがオリジンに転送されるように CloudFront を設定します。「[オリジンリクエストにカスタムヘッダーを追加するように CloudFront を設定する](add-origin-custom-headers.md#add-origin-custom-headers-configure)」を参照してください。

**ビューワープロトコルポリシー**  
ビューワーから CloudFront へのアクセス時に HTTPS の使用が求められるようにディストリビューションを設定します。「[ビューワープロトコルポリシー](DownloadDistValuesCacheBehavior.md#DownloadDistValuesViewerProtocolPolicy)」を参照してください。

**オリジンプロトコルポリシー**  
CloudFront がリクエストをオリジンに転送する際にビューワーと同じプロトコルの使用が求められるように、ディストリビューションを設定します。「[プロトコル (カスタムオリジンのみ)](DownloadDistValuesOrigin.md#DownloadDistValuesOriginProtocolPolicy)」を参照してください。

これらの変更を行った後、CloudFront で送信するように設定したカスタムヘッダーを含むリクエストのみを受け入れるように、カスタムオリジンでアプリケーションを更新します。

**ビューワープロトコルポリシー**と**オリジンプロトコルポリシー**の組み合わせにより、カスタムヘッダーが転送中に暗号化されます。ただし、定期的に以下を実行して、CloudFront がオリジンに転送するカスタムヘッダーをローテーションすることをお勧めします。

1. CloudFront ディストリビューションを更新して、カスタムオリジンへの新しいヘッダーの転送を開始します。

1. アプリケーションを更新して、リクエストが CloudFront からのものであることの確認として新しいヘッダーを受け入れます。

1. 置き換えるヘッダーが今後リクエストに含まれないようにする場合は、アプリケーションを更新して、リクエストが CloudFront からのものであることの確認として古いヘッダーを受け入れないようにします。

# 署名付き URL と署名付き Cookie を作成できる署名者を指定する
<a name="private-content-trusted-signers"></a>

**Topics**
+ [

## 信頼されたキーグループ (推奨) と AWS アカウントのいずれかを選択する
](#choosing-key-groups-or-AWS-accounts)
+ [

## 署名者のキーペアを作成する
](#private-content-creating-cloudfront-key-pairs)
+ [

## プライベートキーの形式を変更する (.NET および Java のみ)
](#private-content-reformatting-private-key)
+ [

## ディストリビューションに署名者を追加する
](#private-content-adding-trusted-signers)
+ [

## キーペアの更新
](#private-content-rotating-key-pairs)

署名付き URL または署名付き Cookie を作成するには、*署名者*が必要です。署名者は、CloudFront で作成した信頼できるキーグループ、または CloudFront のキーペアが含まれる AWS アカウントのいずれかです。署名付き URL と署名付き Cookie が有効な信頼されたキーグループを使用することをお勧めします。詳細については、「[信頼されたキーグループ (推奨) と AWS アカウントのいずれかを選択する](#choosing-key-groups-or-AWS-accounts)」を参照してください。

署名者には 2 つの目的があります。
+ 署名者をディストリビューションに追加するとすぐに、ビューワーからファイルへのアクセスには、署名付き URL または署名付き Cookie の使用が CloudFront によって求められるようになります。
+ 署名付き URL または署名付き Cookie を作成するときは、署名者のキーペアのプライベートキーを使用して URL または Cookie に署名します。制限されたファイルがリクエストされると、CloudFront は URL または Cookie の署名を署名のない URL または Cookie と比較し、改ざんされていないことを確認します。CloudFront は、URL または Cookie が有効であることも確認します。たとえば、有効期限切れ日時が経過していないことを確認します。

署名者を指定するときは、署名者をキャッシュ動作に追加することにより、署名付き URL または署名付き Cookie を必要とするファイルも間接的に指定します。ディストリビューションのキャッシュ動作が 1 つしかない場合、ビューワーはディストリビューション内のファイルへのアクセスに、署名付き URL または署名付き Cookie の使用を求められます。複数のキャッシュ動作を作成して、署名者を一部のキャッシュ動作に追加し、それ以外のキャッシュ動作に追加しなかった場合、ビューワーは一部のファイルへのアクセスに、署名付き URL または署名付き Cookie の使用を求められ、その他のファイルへのアクセスには求められません。

署名付き URL または署名付き Cookie の作成を許可する署名者 (プライベートキー) を指定し、署名者を CloudFront ディストリビューションに追加するには、以下のタスクを実行します。

1. 署名者として、信頼されたキーグループを使用するか、AWS アカウントを使用するかを決定します。信頼されたキーグループを使用することをお勧めします。詳細については、「[信頼されたキーグループ (推奨) と AWS アカウントのいずれかを選択する](#choosing-key-groups-or-AWS-accounts)」を参照してください。

1. ステップ 1 で選択した署名者に対して、パブリックとプライベートのキーペアを作成します。詳細については、「[署名者のキーペアを作成する](#private-content-creating-cloudfront-key-pairs)」を参照してください。

1. 署名付き URL または署名付き Cookie の作成に .NET または Java を使用する場合は、プライベートキーの形式を変更します。詳細については、「[プライベートキーの形式を変更する (.NET および Java のみ)](#private-content-reformatting-private-key)」を参照してください。

1. 署名付き URL または署名付き Cookie を作成するディストリビューションで、署名者を指定します。詳細については、「[ディストリビューションに署名者を追加する](#private-content-adding-trusted-signers)」を参照してください。

## 信頼されたキーグループ (推奨) と AWS アカウントのいずれかを選択する
<a name="choosing-key-groups-or-AWS-accounts"></a>

署名付き URL または署名付き Cookie を使用するには、*署名者*が必要です。署名者は、CloudFront で作成した信頼されたキーグループ、または CloudFront のキーペアを含む AWS アカウントのいずれかです。以下の理由から、信頼されたキーグループを使用することをお勧めします。
+ CloudFront キーグループでは、CloudFront の署名付き URL と署名付き Cookie のパブリックキーを管理するために AWS アカウントのルートユーザーを使用する必要がありません。[AWS のベストプラクティス](https://docs.aws.amazon.com/general/latest/gr/root-vs-iam.html#aws_tasks-that-require-root)では、特に必要なければルートユーザーを使用しないことが推奨されています。
+ CloudFront キーグループを使用すると、CloudFront API を使用して、パブリックキー、キーグループ、および信頼された署名者を管理できます。API を使用して、キーの作成とキーの更新を自動化できます。AWS ルートユーザーを使用する場合は、AWS マネジメントコンソール を使用して CloudFront キーペアを管理する必要があるため、プロセスを自動化することはできません。
+ CloudFront API を使用してキーグループを管理できるため、AWS Identity and Access Management (IAM) の許可ポリシーを使用して、異なるユーザーに許可される操作を制限することもできます。例えば、ユーザーにパブリックキーのアップロードを許可し、削除を禁止することができます。または、ユーザーにパブリックキーの削除を許可するが、許可するのは、多要素認証の使用、特定のネットワークからのリクエストの送信、特定の日時範囲内でのリクエストの送信など、特定の条件が満たされた場合に限ることもできます。
+ CloudFront キーグループを使用すると、より多くのパブリックキーを CloudFront ディストリビューションに関連付けることができるため、パブリックキーの使用方法と管理方法をより柔軟に設定できます。デフォルトでは、最大 4 つのキーグループを 1 つのディストリビューションに関連付けることができ、キーグループには最大 5 つのパブリックキーを含めることができます。

  AWS アカウントのルートユーザーを使用して CloudFront のキーペアを管理する場合は、AWS アカウントあたり最大 2 つのアクティブな CloudFront キーペアしか使用できません。

## 署名者のキーペアを作成する
<a name="private-content-creating-cloudfront-key-pairs"></a>

CloudFront 署名付き URL または署名付き Cookie の作成に使用する各署名者には、パブリックとプライベートのキーペアが必要です。署名者はプライベートキーを使用して URL または Cookie に署名し、CloudFront はパブリックキーを使用して署名を検証します。

キーペアを作成する方法は、信頼されたキーグループを署名者として使用するか (推奨)、CloudFront のキーペアを使用するかによって異なります。詳細については、次のセクションを参照してください。作成するキーペアは、以下の要件を満たしている必要があります。
+ SSH-2 RSA 2048 または ECDSA 256 キーペアである必要があります。
+ base64 エンコードされた PEM 形式である必要があります。

アプリケーションを保護するために、キーペアを定期的に更新することをお勧めします。詳細については、「[キーペアの更新](#private-content-rotating-key-pairs)」を参照してください。

### 信頼されたキーグループのキーペアを作成する (推奨)
<a name="create-key-pair-and-key-group"></a>

信頼されたキーグループのキーペアを作成するには、以下の手順を実行します。

1. パブリックとプライベートのキーペアを作成します。

1. パブリックキーを CloudFront にアップロードします。

1. パブリックキーを CloudFront キーグループに追加します。

詳細については、次の手順を参照してください。<a name="private-content-uploading-cloudfront-public-key-procedure"></a>

**キーペアを作成するには**
**注記**  
以下の手順では、キーペアを作成する方法の一例として OpenSSL を使用します。RSA または ECDSA キーペアを作成する方法は他にも多数あります。

1. 以下のいずれかのコマンド例を実行します。
   + 以下のコマンド例では、OpenSSL を使用して 2,048 ビット長の RSA キーペアを生成し、`private_key.pem` という名前のファイルに保存します。

     ```
     openssl genrsa -out private_key.pem 2048
     ```
   + 以下のコマンド例では、OpenSSL を使用して `prime256v1` 曲線を使用する ECDSA キーペアを生成し、`private_key.pem` という名前のファイルに保存します。

     ```
     openssl ecparam -name prime256v1 -genkey -noout -out privatekey.pem
     ```

1. 生成されるファイルには、パブリックキーとプライベートキーの両方が含まれます。以下のコマンド例では、`private_key.pem` という名前のファイルからパブリックキーを抽出します。

   ```
   openssl rsa -pubout -in private_key.pem -out public_key.pem
   ```

   後で、以下の手順でパブリックキー (`public_key.pem` ファイル内) をアップロードします。

**パブリックキーを CloudFront にアップロードするには**

1. AWS マネジメントコンソール にサインインし、[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home) で CloudFront コンソールを開きます。

1. ナビゲーションメニューで、[**Public keys (パブリックキー)**] を選択します。

1. **[パブリックキーを作成]** を選択します。

1. **[パブリックキーを作成]** ウィンドウで、次の操作を行います。

   1. [**Key name (キー名)**] に、パブリックキーを識別するための名前を入力します。

   1. [**Key value (キー値)**] に、パブリックキーを貼り付けます。前の手順のステップに従った場合、パブリックキーは `public_key.pem` という名前のファイルにあります。パブリックキーの内容をコピーして貼り付けるには、以下の手順を実行します。
      + macOS または Linux コマンドラインで **cat** コマンドを次のように使用します。

        ```
        cat public_key.pem
        ```

        そのコマンドの出力をコピーして、[**Key value (キー値)**] フィールドに貼り付けます。
      + メモ帳 (Windows の場合) やテキストエディット (macOS の場合) などのプレーンテキストエディタで、`public_key.pem` ファイルを開きます。ファイルの内容をコピーし、[**Key value (キー値)**] フィールドに貼り付けます。

   1. (オプション) [**Comment (コメント)**] に、パブリックキーを説明するコメントを追加します。

   完了したら、[**Add (追加)**] を選択します。

1. パブリックキー ID を記録します。この ID は、後で署名付き URL または署名付き Cookie を作成するときに、`Key-Pair-Id` フィールドの値として使用します。

**パブリックキーをキーグループに追加するには**

1.  で CloudFront コンソールを開きます[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)

1. ナビゲーションメニューで、[**Key groups (キーグループ)**] を選択します。

1. [**Add key group (キーグループの追加)**] を選択します。

1. [**Create key group (キーグループの作成)**] ページで、以下の手順を実行します。

   1. [**Key group name (キーグループ名)**] に、キーグループを識別するための名前を入力します。

   1. (オプション) [**Comment (コメント\$1**] に、キーグループを説明するコメントを入力します。

   1. [**Public keys (パブリックキー)**] で、キーグループに追加するパブリックキーを選択してから、[**Add (追加)**] を選択します。キーグループに追加するパブリックキーごとに、このステップを繰り返します。

1. [**Create key group (キーグループの作成)**] を選択します。

1. キーグループ名を記録します。この名前は、後でキーグループを CloudFront ディストリビューションのキャッシュ動作に関連付けるときに使用します。(CloudFront API では、キーグループ ID を使用して、キーグループをキャッシュ動作に関連付けます)。

### CloudFront のキーペアを作成する (非推奨、AWS アカウントのルートユーザーが必要)
<a name="create-key-pair-aws-account"></a>

**重要**  
ここでの手順に従う代わりに、信頼されたキーグループのパブリックキーを作成することをお勧めします。署名付き URL および署名付き Cookie のパブリックキーを作成するための推奨される方法については、「[信頼されたキーグループのキーペアを作成する (推奨)](#create-key-pair-and-key-group)」を参照してください。

CloudFront のキーペアは、次の方法で作成できます。
+ AWS マネジメントコンソールでキーペアを作成し、プライベートキーをダウンロードします。後述の手順を参照してください。
+ OpenSSL などのアプリケーションを使用して RSA キーペアを作成し、パブリックキーを にアップロードしますAWS マネジメントコンソール RSA キーペアの作成の詳細については、「[信頼されたキーグループのキーペアを作成する (推奨)](#create-key-pair-and-key-group)」を参照してください。<a name="private-content-creating-cloudfront-key-pairs-procedure"></a>

**AWS マネジメントコンソール で CloudFront キーペアを作成するには**

1. AWS アカウントのルートユーザーの認証情報を使用して、AWS マネジメントコンソール にサインインします。
**重要**  
IAM ユーザーは CloudFront のキーペアを作成できません。キーペアを作成するには、ルートユーザーの認証情報を使用してサインインする必要があります。

1. アカウント名を選択してから、[**My Security Credentials (セキュリティ認証情報)**] を選択します。

1. [**CloudFront のキーペア**] を選択します。

1. 複数のキーペアが有効になっていないことを確認します。既に 2 つのキーペアが有効になっていると、キーペアを作成できません。

1. [**Create New Key Pair (新しいキーペアの作成)**] を選択します。
**注記**  
独自のキーペアを作成し、公開キーをアップロードすることもできます。CloudFront キーペアは、1024、2048、または 4096 ビットのキーをサポートします。

1. [**Create Key Pair (キーペアの作成)**] ダイアログボックスで、[**Download Private Key File (プライベートキーファイルのダウンロード)**] を選択し、ファイルをコンピュータに保存します。
**重要**  
CloudFront のキーペアのプライベートキーを安全な場所に保存し、必要な管理者だけがそのプライベートキーを読み取ることができるようにファイルのアクセス許可を設定します。別のユーザーがこのプライベートキーを取得すると、そのユーザーは有効な署名付き URL および署名付き Cookie を生成し、コンテンツをダウンロードできます。プライベートキーを再取得することはできません。したがって、プライベートキーを削除したか失った場合は、新しい CloudFront キーペアを作成する必要があります。

1. キーペアのキーペア ID を記録しておきます (AWS マネジメントコンソール では**アクセスキー ID** と呼ばれます)。この情報は、署名付き URL または署名付き Cookie を作成するときに使用します。

## プライベートキーの形式を変更する (.NET および Java のみ)
<a name="private-content-reformatting-private-key"></a>

.NET または Java を使用して署名付き URL または署名付き Cookie を作成する場合、キーペアのプライベートキーをデフォルトの PEM 形式のまま使用して署名を作成することはできません。代わりに、以下の手順を実行します。
+ **.NET Framework** – .NET Framework で使用する XML 形式にプライベートキーを変換します。いくつかのツールを利用できます。
+ **Java** – DER 形式にプライベートキーを変換します。そのための 1 つの方法は、以下の OpenSSL コマンドを使用することです。以下のコマンドで、`private_key.pem` は PEM 形式のプライベートキーを含むファイルの名前であり、`private_key.der` はコマンドの実行後に DER 形式のプライベートキーを含むファイルの名前です。

  ```
  openssl pkcs8 -topk8 -nocrypt -in private_key.pem -inform PEM -out private_key.der -outform DER
  ```

  エンコーダーが正常に機能するように、Bouncy Castle の Java 用暗号 API の JAR をプロジェクトに追加してから Bouncy Castle プロバイダーを追加します。

## ディストリビューションに署名者を追加する
<a name="private-content-adding-trusted-signers"></a>

署名者は、ディストリビューション用の署名付き URL と署名付き Cookie を作成できる、信頼されたキーグループ (推奨) または CloudFront キーペアです。署名付き URL または署名付き Cookie を CloudFront ディストリビューションで使用するには、署名者を指定する必要があります。

署名者はキャッシュ動作に関連付けられています。これにより、同じディストリビューション内で、一部のファイルに署名付き URL または署名付き Cookie を要求し、その他のファイルには要求しないということが可能になります。ディストリビューションでは、対応するキャッシュ動作に関連付けられているファイルにのみ、署名付き URL または Cookie が必要です。

同様に、署名者は、対応するキャッシュ動作に関連付けられているファイルの URL または Cookie にのみ署名できます。例えば、1 つのキャッシュ動作に対して 1 つの署名者があり、別のキャッシュ動作に対して別の署名者がある場合、どちらの署名者も、もう一方のキャッシュ動作に関連付けられたファイルに対して署名付き URL または署名付き Cookie を作成できません。

**重要**  
ディストリビューションに署名者を追加する前に、以下の手順を実行します。  
キャッシュ動作のパスパターンとキャッシュ動作のシーケンスを慎重に定義して、ユーザーにコンテンツへの意図しないアクセスを許可したり、すべてのユーザーを対象としたコンテンツへのアクセスを禁止したりしないようにします。  
たとえば、リクエストが、2 つのキャッシュ動作のパスパターンに一致したと仮定します。最初のキャッシュ動作は署名付き URL または署名付き Cookie を要求しませんが、2 番目のキャッシュ動作はこれらを要求します。ユーザーは署名付き URL または署名付き Cookie を使用せずにファイルにアクセスできます。これは、CloudFront が、最初の一致に関連付けられたキャッシュ動作を処理するためです。  
パスパターンの詳細については、「[パスパターン](DownloadDistValuesCacheBehavior.md#DownloadDistValuesPathPattern)」を参照してください。
コンテンツの配信に既に使用しているディストリビューションの場合は、署名者を追加する前に、署名付き URL と署名付き Cookie の生成を開始する準備ができていることを確認してください。署名者を追加すると、CloudFront は有効な署名付き URL または署名付き Cookie を含まないリクエストを拒否します。

CloudFront コンソールまたは CloudFront API を使用して、署名者をディストリビューションに追加できます。

------
#### [ Console ]

以下の手順では、信頼されたキーグループを署名者として追加する方法を示します。信頼された署名者として AWS アカウントを追加することもできますが、お勧めしません。<a name="private-content-adding-trusted-signers-console-procedure"></a>

**コンソールを使用してディストリビューションに署名者を追加するには**

1. 信頼された署名者として使用するキーグループのキーグループ ID を記録します。詳細については、「[信頼されたキーグループのキーペアを作成する (推奨)](#create-key-pair-and-key-group)」を参照してください。

1.  で CloudFront コンソールを開きます[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)

1. 署名付き URL または署名付き Cookie でファイルを保護するディストリビューションを選択します。
**注記**  
新しいディストリビューションに署名者を追加するには、ディストリビューションを作成するときにステップ 6 で説明したのと同じ設定を指定します。

1. [**Behaviors**] タブを選択します。

1. 署名付き URL または署名付き Cookie で保護するファイルとパスパターンが一致するキャッシュ動作を選択し、[**Edit (編集)**] を選択します。

1. [**Edit Behavior (動作の編集)**] ページで、以下の手順を実行します。

   1. [**Restrict Viewer Access (Use Signed URLs or Signed Cookies) (ビューワーのアクセスを制限 (署名付き URL または署名付き Cookie の使用))**] で、[**はい**] を選択します。

   1. [**Trusted Key Groups or Trusted Signer (信頼されたキーグループまたは信頼された署名者)**] で、[**Trusted Key Groups (信頼されたキーグループ)**] を選択します。

   1. [**Trusted Key Groups (信頼されたキーグループ)**] で、追加するキーグループを選択し、[**Add (追加)**] を選択します。複数のキーグループを追加する場合は、この手順を繰り返します。

1. [**Yes, Edit (はい、編集する)**] を選択して、キャッシュ動作を更新します。

------
#### [ API ]

CloudFront API を使用して、信頼されたキーグループを署名者として追加できます。署名者を既存のディストリビューションまたは新しいディストリビューションに追加できます。どちらの場合も、`TrustedKeyGroups` 要素の値を指定します。

信頼された署名者として AWS アカウントを追加することもできますが、お勧めしません。

*Amazon CloudFront API リファレンス*の以下のトピックを参照してください。
+ **既存のディストリビューションを更新する** – 「[UpdateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateDistribution.html)」
+ **新しいディストリビューションを作成する** – 「[CreateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateDistribution.html)」

------

## キーペアの更新
<a name="private-content-rotating-key-pairs"></a>

署名付き URL と署名付き Cookie のキーペアを定期的に更新 (変更) することをお勧めします。有効期限がまだ切れていない URL または Cookie を無効にすることなく、署名付き URL または署名付き Cookie の作成に使用しているキーペアを更新するには、以下のタスクを実行します。

1. 新しいキーペアを作成し、パブリックキーをキーグループに追加します。詳細については、「[信頼されたキーグループのキーペアを作成する (推奨)](#create-key-pair-and-key-group)」を参照してください。

1. 前の手順で新しいキーグループを作成した場合は、[キーグループを署名者としてディストリビューションに追加](#private-content-adding-trusted-signers)します。
**重要**  
キーグループから既存のパブリックキーを削除したり、ディストリビューションからキーグループを削除したりしないでください。新規追加のみを行ってください。

1. 新しいキーペアのプライベートキーを使用して署名を作成するようにアプリケーションを更新します。新しいプライベートキーで署名された URL または Cookie が機能することを確認します。

1. 以前のプライベートキーを使用して署名付き URL または Cookie の有効期限切れ日時が経過するまで待ちます。次に、古いパブリックキーをキーグループから削除します。ステップ 2 で新しいキーグループを作成した場合は、ディストリビューションから古いキーグループを削除します。

# 署名付き URL を使用するか、署名付き Cookie を使用するかを決定する
<a name="private-content-choosing-signed-urls-cookies"></a>

CloudFront 署名付き URL と署名付き Cookie は同じ基本的な機能を提供します。これらによって、コンテンツにアクセスできるユーザーを制御できます。CloudFront を使用してプライベートコンテンツを供給する場合に、署名付き URL と署名付き Cookie のどちらを使用するかを決定するには、以下の点を考慮します。

次のような場合は、署名付き URL を使用します。
+ 個別のファイル (アプリケーションのインストールダウンロード) へのアクセスを制限する場合。
+ ユーザーが Cookie をサポートしていないクライアント (カスタム HTTP クライアントなど) を使用している場合。

次のような場合は、署名付き Cookie を使用します。
+ 複数の制限されたファイル (HLS 形式の動画のすべてのファイルやウェブサイトの購読者の領域にあるすべてのファイルなど) へのアクセスを提供する場合。
+ 現在の URL を変更したくない場合。

現在署名付き URL を使用していない場合で、署名なし URL に次のクエリ文字列パラメータ含まれる場合、署名付き URL と署名付き Cookie のいずれも使用できません。
+ `Expires`
+ `Policy`
+ `Signature`
+ `Key-Pair-Id`

CloudFront では、これらのクエリ文字列パラメータを含む URL が署名付き URL であると見なされ、署名付き Cookie の確認は行われません。

## 署名付き URL と署名付き Cookie の両方を使用する
<a name="private-content-using-signed-urls-and-cookies"></a>

署名付き URL は署名付き Cookie よりも優先されます。署名付き URL と署名付き Cookie の両方を使用して同じファイルへのアクセスが制御されている場合に、ビューワーが署名付き URL を使用してファイルをリクエストすると、CloudFront は署名付き URL のみに基づいてビューワーにファイルを返すかどうかを決定します。

# 署名付き URL を使用する
<a name="private-content-signed-urls"></a>

署名付き URL には、有効期限切れ日時など、追加の情報も含まれており、コンテンツへのアクセスをより詳細に制御できます。この追加情報は、既定ポリシーまたはカスタムポリシーに基づくポリシーステートメントに含まれます。既定ポリシーとカスタムポリシーの違いを以下の 2 つのセクションで説明します。

**注記**  
既定ポリシーを使用して一部の署名付き URL を作成し、同じディストリビューションで、カスタムポリシーを使用して一部の署名付き URL を作成することができます。

**Topics**
+ [

## 署名付き URL に既定ポリシーとカスタムポリシーのどちらを使用するかを決定する
](#private-content-choosing-canned-custom-policy)
+ [

## 署名付き URL の仕組み
](#private-content-how-signed-urls-work)
+ [

## 署名付き URL の有効期間を決定する
](#private-content-overview-choosing-duration)
+ [

## CloudFront が署名付き URL の有効期限切れの日時を確認するタイミング
](#private-content-check-expiration)
+ [

## サンプルコードおよびサードパーティーツール
](#private-content-overview-sample-code)
+ [

# 既定ポリシーを使用して署名付き URL を作成する
](private-content-creating-signed-url-canned-policy.md)
+ [

# カスタムポリシーを使用して署名付き URL を作成する
](private-content-creating-signed-url-custom-policy.md)

## 署名付き URL に既定ポリシーとカスタムポリシーのどちらを使用するかを決定する
<a name="private-content-choosing-canned-custom-policy"></a>

署名付き URL を作成する場合、URL の有効期間など、署名付き URL で制限を指定する JSON 形式のポリシーステートメントを作成します。既定ポリシーまたはカスタムポリシーのいずれかを使用できます。既定ポリシーとカスタムポリシーの比較を以下に示します。


****  

| 説明 | 既定ポリシー | カスタムポリシー | 
| --- | --- | --- | 
| ポリシーステートメントを複数のファイル用に再利用できる。ポリシーステートメントを再利用するには、`Resource` オブジェクトでワイルドカード文字を使用する必要があります。(詳しくは、「[カスタムポリシーを使用する署名付き URL のポリシーステートメントで指定する値](private-content-creating-signed-url-custom-policy.md#private-content-custom-policy-statement-values)」を参照してください)。 | いいえ | はい | 
| ユーザーがコンテンツへのアクセスを開始できる日時を指定できる。 | いいえ | はい (オプション) | 
| ユーザーがコンテンツにアクセスできなくなる日時を指定できる。 | はい | はい | 
| コンテンツにアクセスできるユーザーの IP アドレスまたは IP アドレス範囲を指定できる。 | いいえ | はい (オプション) | 
| 署名付き URL にポリシーの base64 エンコードされたバージョンが含まれているため、URL が長くなる。 | いいえ | はい | 

*既定*ポリシーを使用して署名付き URL を作成する方法については、「[既定ポリシーを使用して署名付き URL を作成する](private-content-creating-signed-url-canned-policy.md)」を参照してください。

*カスタム*ポリシーを使用して署名付き URL を作成する方法については、「[カスタムポリシーを使用して署名付き URL を作成する](private-content-creating-signed-url-custom-policy.md)」を参照してください。

## 署名付き URL の仕組み
<a name="private-content-how-signed-urls-work"></a>

署名付き URL 用の CloudFront と Amazon S3 の設定方法と、ユーザーが署名付き URL を使用してファイルをリクエストしたときの CloudFront の応答方法の概要を次に示します。

1. CloudFront ディストリビューションで、1 つ以上の信頼されたキーグループを指定します。指定したグループには、CloudFront が URL 署名の検証に使用できるパブリックキーが含まれている必要があります。対応するプライベートキーを使用して URL に署名します。

   CloudFront は、RSA 2048 および ECDSA 256 キー署名を使用した署名 URL をサポートしています。

   詳細については、「[署名付き URL と署名付き Cookie を作成できる署名者を指定する](private-content-trusted-signers.md)」を参照してください。

1. アプリケーションを開発して、ユーザーがコンテンツへのアクセス許可を持つかどうかを決定し、アプリケーションでアクセスを制限するファイルまたは部分用に署名付き URL を作成するかを決定します。詳細については、以下のトピックを参照してください。
   + [既定ポリシーを使用して署名付き URL を作成する](private-content-creating-signed-url-canned-policy.md)
   + [カスタムポリシーを使用して署名付き URL を作成する](private-content-creating-signed-url-custom-policy.md)

1. 署名付き URL を必要とするファイルをユーザーが要求します。

1. アプリケーションは、ファイルにアクセスするための資格がユーザーにあることを検証します。たとえば、ユーザーがサインインしていること、コンテンツへのアクセス料を支払っていること、他のいくつかのアクセス要件を満たしていることを検証します。

1. アプリケーションは署名付き URL を作成してエンドユーザーに返します。

1. 署名付き URL を使用すると、ユーザーはコンテンツのダウンロードやストリーミングができます。

   このステップは自動で実行されます。ユーザーは、コンテンツにアクセスする以外に、何も行う必要はありません。たとえば、ユーザーがウェブブラウザでコンテンツにアクセスすると、アプリケーションは署名付き URL をブラウザに返します。ブラウザは、直ちに、署名付き URL を使用して CloudFront エッジキャッシュ内のファイルにアクセスします。ユーザーからの介入はありません。

1. CloudFront はパブリックキーを使用して署名を検証し、URL が改ざんされていないことを確認します。署名が無効である場合、リクエストは拒否されます。

   署名が有効である場合、CloudFront は URL のポリシーステートメントを参照して (または既定ポリシーを使用している場合はポリシーステートメントを作成して)、リクエストがまだ有効であることを確認します。たとえば、URL の開始日時と終了日時を指定した場合、CloudFront は、アクセスが許可されている期間にユーザーがコンテンツへのアクセスを試みていることを確認します。

   リクエストがポリシーステートメントの要件を満たしている場合、CloudFront は標準の操作を実行します。つまり、ファイルがエッジキャッシュにすでに存在するかどうかを確認し、必要に応じてリクエストをオリジンに転送して、ファイルをユーザーに返します。

**注記**  
署名なし URL にクエリ文字列パラメータが含まれている場合は、署名する URL にそれらのパラメータを含めてください。URL への署名後にその URL にクエリ文字列を追加すると、HTTP 403 ステータスが返されます。

## 署名付き URL の有効期間を決定する
<a name="private-content-overview-choosing-duration"></a>

短期間 (おそらく数分) のみ有効な署名付き URL を使用してプライベートコンテンツを配信できます。このように短期間有効な署名付き URL は、特定の目的で、コンテンツをユーザーにオンザフライで配信する場合に適しています。たとえば、映画レンタルや音楽ダウンロードをカスタマーにオンデマンドで配信する場合に適しています。署名付き URL を短期間だけ有効にする場合、開発したアプリケーションを使用して、署名付き URL を自動生成することが必要になる場合があります。ユーザーがファイルのダウンロードまたはメディアファイルの再生を開始すると、CloudFront は、URL 内の有効期限切れ時刻と現在の時刻を比較して、URL が依然として有効かどうかを判別します。

これよりも有効期間の長い (おそらく数年間の) 署名付き URL を使用して、プライベートコンテンツを配信できます。有効期間の長い署名付き URL は、プライベートコンテンツを既知のユーザーに配信する場合に役立ちます。たとえば、事業計画を投資家に配信したり、教育資料を従業員に配信したりする場合に役立ちます。これらの長期的な署名付き URL を生成するアプリケーションを開発できます。

## CloudFront が署名付き URL の有効期限切れの日時を確認するタイミング
<a name="private-content-check-expiration"></a>

CloudFront は、HTTP リクエスト時に署名付き URL の有効期限切れ日時を確認します。有効期限切れ時刻の直前にクライアントが大きなファイルのダウンロードを開始した場合、ダウンロード中に有効期限切れ時刻が経過してもダウンロードは完了します。TCP 接続が中断し、有効期限切れ時刻が経過した後にクライアントがダウンロードを再開した場合、ダウンロードは失敗します。

クライアントが、ファイルを断片的に取得するレンジ GET を使用した場合、有効期限切れ時刻が経過した後に実行された GET リクエストは失敗します。レンジ GET の詳細については、「[CloudFront がオブジェクトの部分的リクエスト (レンジ GET) を処理する方法](RangeGETs.md)」を参照してください。

## サンプルコードおよびサードパーティーツール
<a name="private-content-overview-sample-code"></a>

署名付き URL の、ハッシュ化および署名されたパートを作成するサンプルコードについては、以下のトピックを参照してください。
+ [Perl を使用して URL 署名を作成する](CreateURLPerl.md)
+ [PHP を使用して URL 署名を作成する](CreateURL_PHP.md)
+ [C\$1 と .NET Framework を使用して URL 署名を作成する](CreateSignatureInCSharp.md)
+ [Java を使用して URL 署名を作成する](CFPrivateDistJavaDevelopment.md)

# 既定ポリシーを使用して署名付き URL を作成する
<a name="private-content-creating-signed-url-canned-policy"></a>

既定ポリシーを使用して署名付き URL を作成するには、以下の手順を実行します。<a name="private-content-creating-signed-url-canned-policy-procedure"></a>

**既定ポリシーを使用して署名付き URL を作成するには**

1. .NET または Java を使用して署名付き URL を作成しており、キーペアのプライベートキーをデフォルトの .pem 形式から .NET または Java 対応の形式に変更していない場合は、それを変換します。詳細については、「[プライベートキーの形式を変更する (.NET および Java のみ)](private-content-trusted-signers.md#private-content-reformatting-private-key)」を参照してください。

1. 以下の値を連結します。この署名付き URL の例に示す形式を使用できます。

   ```
   https://d111111abcdef8.cloudfront.net/image.jpg?color=red&size=medium&Expires=1767290400&Signature=nitfHRCrtziwO2HwPfWw~yYDhUF5EwRunQA-j19DzZrvDh6hQ73lDx~-ar3UocvvRQVw6EkC~GdpGQyyOSKQim-TxAnW7d8F5Kkai9HVx0FIu-5jcQb0UEmatEXAMPLE3ReXySpLSMj0yCd3ZAB4UcBCAqEijkytL6f3fVYNGQI6&Key-Pair-Id=K2JCJMDEHXQW5F
   ```

   すべての空白 (タブと改行文字を含む) を削除します。アプリケーションコード内の文字列にエスケープ文字を含めることが必要になる場合があります。すべての値の型は `String` です。  
**1. *ファイルのベース URL***  
ベース URL は、署名付き URL を使用しなかった場合にファイルへのアクセスに使用する CloudFront URL であり、独自のクエリ文字列パラメータを含みます (ある場合)。前の例で、ベース URL は `https://d111111abcdef8.cloudfront.net/image.jpg` です。ディストリビューション用の URL 形式の詳細については、「[CloudFront でファイルの URL 形式をカスタマイズする](LinkFormat.md)」を参照してください。  
   + 以下の CloudFront URL は、ディストリビューション内のイメージファイルの URL です (CloudFront ドメイン名を使用)。`image.jpg` は `images` ディレクトリにあります。URL 内のファイルへのパスは、HTTP サーバーまたは Amazon S3 バケットのファイルへのパスに一致する必要があります。

     `https://d111111abcdef8.cloudfront.net/images/image.jpg`
   + 以下の CloudFront URL には、クエリ文字列が含まれます。

     `https://d111111abcdef8.cloudfront.net/images/image.jpg?size=large`
   + 以下の CloudFront URL は、ディストリビューション内のイメージファイルの URL です。どちらも代替ドメイン名を使用します。2 番目にはクエリ文字列が含まれています。

     `https://www.example.com/images/image.jpg`

     `https://www.example.com/images/image.jpg?color=red`
   + 以下の CloudFront URL は、代替ドメイン名と HTTPS プロトコルを使用するディストリビューション内のイメージファイルの URL です。

     `https://www.example.com/images/image.jpg`  
** 2. `?` **  
`?` は、クエリパラメータがベース URL の後に続くことを示します。クエリパラメータを指定しない場合でも、`?` を含めます。  
以下のクエリパラメータは任意の順序で指定できます。  
**3. *クエリ文字パラメータ (ある場合*`&`**  
(オプション) 独自のクエリ文字列パラメータを入力できます。これを行うには、各パラメータ間にアンパサンド (`&`) を追加します (例: `color=red&size=medium`)。クエリ文字列パラメータは、URL 内に任意の順序で指定できます。  
クエリ文字列パラメータに `Expires`、`Signature`、または `Key-Pair-Id` という名前を付けることはできません。  
** 4.`Expires=`*Unix 時間形式 (秒単位) および協定世界時 (UTC) の日時***  
URL によるファイルへのアクセスの許可を停止する日付と時刻。  
有効期限切れ日時を Unix 時間形式 (秒単位) および協定世界時 (UTC) で指定します。例えば、このトピックの冒頭にある例に示すように、2026 年 1 月 1 日午前 10:00 UTC は Unix 時間形式で `1767290400` に変換されます。  
エポック時間を使用するには、`9223372036854775807` (2262 年 4 月 11 日金曜日の 23:47:16.854 UTC) 以前の日付に 64 ビット整数を指定します。  
  
UTC の詳細については、[RFC 3339, Date and Time on the Internet: Timestamps](https://tools.ietf.org/html/rfc3339) を参照してください。  
** 5. `&Signature=`*ハッシュ化および署名されたバージョンのポリシーステートメント***  
ハッシュ化され、署名された base64 エンコードバージョンの JSON ポリシーステートメント。詳細については、「[既定ポリシーを使用する署名付き URL の署名を作成する](#private-content-canned-policy-creating-signature)」を参照してください。  
** 6. `&Key-Pair-Id=`*署名の生成に使用しているプライベートキーに対応する CloudFront パブリックキーのパブリックキー ID***  
CloudFront パブリックキーの ID (`K2JCJMDEHXQW5F` など)。パブリックキー ID は、署名付き URL の検証に使用するパブリックキーを CloudFront に通知します。CloudFront は、署名内の情報をポリシーステートメント内の情報と比較して、URL が改ざんされていないことを確認します。  
このパブリックキーは、ディストリビューションの信頼された署名者であるキーグループに属している必要があります。詳細については、「[署名付き URL と署名付き Cookie を作成できる署名者を指定する](private-content-trusted-signers.md)」を参照してください。

## 既定ポリシーを使用する署名付き URL の署名を作成する
<a name="private-content-canned-policy-creating-signature"></a>

既定ポリシーを使用する署名付き URL の署名を作成するには、以下の手順を実行します。

**Topics**
+ [

### 既定ポリシーを使用する署名付き URL のポリシーステートメントを作成する
](#private-content-canned-policy-creating-policy-statement)
+ [

### 既定ポリシーを使用する署名付き URL の署名を作成する
](#private-content-canned-policy-signing-policy-statement)

### 既定ポリシーを使用する署名付き URL のポリシーステートメントを作成する
<a name="private-content-canned-policy-creating-policy-statement"></a>

既定ポリシーを使用して署名付き URL を作成する場合、`Signature` パラメータは、ポリシーステートメントのハッシュ化および署名されたバージョンです。カスタムポリシーを使用する署名付き URL とは異なり、既定ポリシーを使用する署名付き URL では、URL にポリシーステートメントを含めません。ポリシーステートメントを作成するには、以下の手順を実行します。<a name="private-content-canned-policy-creating-policy-statement-procedure"></a>

**既定ポリシーを使用する署名付き URL のポリシーステートメントを作成するには**

1. 以下の JSON 形式および UTF-8 文字エンコードを使用してポリシーステートメントを構築します。すべての句読点および他のリテラル値を、指定されたとおりに正確に含めます。`Resource` および `DateLessThan` パラメータの詳細については、「[既定ポリシーを使用する署名付き URL のポリシーステートメントで指定する値](#private-content-canned-policy-statement-values)」を参照してください。

   ```
   {
       "Statement": [
           {
               "Resource": "base URL or stream name",
               "Condition": {
                   "DateLessThan": {
                       "AWS:EpochTime": ending date and time in Unix time format and UTC
                   }
               }
           }
       ]
   }
   ```

1. ポリシーステートメントからすべての空白 (タブと改行文字を含む) を削除します。アプリケーションコード内の文字列にエスケープ文字を含めることが必要になる場合があります。

#### 既定ポリシーを使用する署名付き URL のポリシーステートメントで指定する値
<a name="private-content-canned-policy-statement-values"></a>

既定ポリシーのポリシーステートメントを作成する場合、以下の値を指定します。

**リソース**  
`Resource` の値は 1 つだけ指定できます。
クエリ文字列 (ある場合) が含まれるベース URL。ただし、CloudFront の `Expires`、`Signature`、および `Key-Pair-Id` パラメータが除外されます。次に例を示します。  
`https://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes`  
次の点に注意してください。  
+ **プロトコル** – 値は `http://` または `https://` で始まっている必要があります。
+ **クエリ文字列パラメータ** – クエリ文字列パラメータがない場合は、疑問符を省略します。
+ **代替ドメイン名** – URL で代替ドメイン名 (CNAME) を指定する場合は、ウェブページまたはアプリケーション内のファイルを参照するときに代替ドメイン名を指定する必要があります。オブジェクトの Amazon S3 URL を指定しないでください。

**DateLessThan**  
URL の有効期限切れ日時。Unix 時間形式 (秒単位) および協定世界時 (UTC) で指定します。例えば、UTC の 2026 年 1 月 1 日午前 10 時 00 分は、Unix 時間形式の 1767290400 に変換されます。  
この値は、署名付き URL 内の `Expires` クエリ文字列パラメータの値と一致する必要があります。値を引用符で囲まないでください。  
詳細については、「[CloudFront が署名付き URL の有効期限切れの日時を確認するタイミング](private-content-signed-urls.md#private-content-check-expiration)」を参照してください。

#### 既定ポリシーを使用する署名付き URL のポリシーステートメントの例
<a name="private-content-canned-policy-creating-policy-statement-example"></a>

署名付き URL 内の既定ポリシーの以下のポリシーステートメントの例を使用すると、ユーザーは、UTC の 2026 年 1 月 1 日午前 10 時 00 分までファイル `https://d111111abcdef8.cloudfront.net/horizon.jpg` にアクセスできます。

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/horizon.jpg?size=large&license=yes",
            "Condition": {
                "DateLessThan": {
                    "AWS:EpochTime": 1767290400
                }
            }
        }
    ]
}
```

### 既定ポリシーを使用する署名付き URL の署名を作成する
<a name="private-content-canned-policy-signing-policy-statement"></a>

署名付き URL の `Signature` パラメータの値を作成するには、「[既定ポリシーを使用する署名付き URL のポリシーステートメントを作成する](#private-content-canned-policy-creating-policy-statement)」で作成したポリシーステートメントをハッシュ化して署名します。

ポリシーステートメントのハッシュ化、署名、およびエンコードを行う方法の詳細および例については、以下の各資料を参照してください。
+ [Linux コマンドおよび OpenSSL を使用した Base64 エンコードおよび暗号化](private-content-linux-openssl.md)
+ [署名付き URL の署名を作成するためのコード例](PrivateCFSignatureCodeAndExamples.md)<a name="private-content-canned-policy-creating-signature-download-procedure"></a>

**オプション 1: 既定ポリシーを使用して署名を作成するには**

1. 「[既定ポリシーを使用する署名付き URL のポリシーステートメントを作成するには](#private-content-canned-policy-creating-policy-statement-procedure)」の手順で作成したポリシーステートメントを、SHA-1 ハッシュ関数と生成した RSA または ECDSA プライベートキーを使用してハッシュ化し、署名します。空白を含まないバージョンのポリシーステートメントを使用します。

   ハッシュ関数に必要なプライベートキーには、対応するパブリックキーがディストリビューション内のアクティブな信頼されたキーグループにあるものを使用してください。
**注記**  
ポリシーステートメントをハッシュ化および署名するための方法は、プログラミング言語およびプラットフォームによって異なります。サンプルコードについては、「[署名付き URL の署名を作成するためのコード例](PrivateCFSignatureCodeAndExamples.md)」を参照してください。

1. ハッシュ化および署名された文字列から、空白 (タブや改行文字を含む) を削除します。

1. MIME base64 エンコーディングを使用して文字列を Base64 エンコードします。詳細については、*RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies* の [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) を参照してください。

1. URL クエリ文字列内の無効な文字を有効な文字で置き換えます。次の表に無効な文字と有効な文字を示します。  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-canned-policy.html)

1. 結果の値を署名付き URL の `&Signature=` の後に付加し、「[既定ポリシーを使用して署名付き URL を作成するには](#private-content-creating-signed-url-canned-policy-procedure)」に戻って、署名付き URL の各パートの連結を終了します。

# カスタムポリシーを使用して署名付き URL を作成する
<a name="private-content-creating-signed-url-custom-policy"></a>

カスタムポリシーを使用して署名付き URL を作成するには、次の手順を実行します。<a name="private-content-creating-signed-url-custom-policy-procedure"></a>

**カスタムポリシーを使用して署名付き URL を作成するには**

1. .NET または Java を使用して署名付き URL を作成しており、キーペアのプライベートキーをデフォルトの .pem 形式から .NET または Java 対応の形式に変更していない場合は、それを変換します。詳細については、「[プライベートキーの形式を変更する (.NET および Java のみ)](private-content-trusted-signers.md#private-content-reformatting-private-key)」を参照してください。

1. 以下の値を連結します。この署名付き URL の例に示す形式を使用できます。

   

   ```
   https://d111111abcdef8.cloudfront.net/image.jpg?color=red&size=medium&Policy=eyANCiAgICEXAMPLEW1lbnQiOiBbeyANCiAgICAgICJSZXNvdXJjZSI6Imh0dHA6Ly9kemJlc3FtN3VuMW0wLmNsb3VkZnJvbnQubmV0L2RlbW8ucGhwIiwgDQogICAgICAiQ29uZGl0aW9uIjp7IA0KICAgICAgICAgIklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIyMDcuMTcxLjE4MC4xMDEvMzIifSwNCiAgICAgICAgICJEYXRlR3JlYXRlclRoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI5Njg2MDE3Nn0sDQogICAgICAgICAiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjEyOTY4NjAyMjZ9DQogICAgICB9IA0KICAgfV0gDQp9DQo&Signature=nitfHRCrtziwO2HwPfWw~yYDhUF5EwRunQA-j19DzZrvDh6hQ73lDx~-ar3UocvvRQVw6EkC~GdpGQyyOSKQim-TxAnW7d8F5Kkai9HVx0FIu-5jcQb0UEmatEXAMPLE3ReXySpLSMj0yCd3ZAB4UcBCAqEijkytL6f3fVYNGQI6&Key-Pair-Id=K2JCJMDEHXQW5F
   ```

   すべての空白 (タブと改行文字を含む) を削除します。アプリケーションコード内の文字列にエスケープ文字を含めることが必要になる場合があります。すべての値の型は `String` です。  
**1. *ファイルのベース URL***  
ベース URL は、署名付き URL を使用しなかった場合にファイルへのアクセスに使用する CloudFront URL であり、独自のクエリ文字列パラメータを含みます (ある場合)。前の例で、ベース URL は `https://d111111abcdef8.cloudfront.net/image.jpg` です。ディストリビューション用の URL 形式の詳細については、「[CloudFront でファイルの URL 形式をカスタマイズする](LinkFormat.md)」を参照してください。  
以下の例は、ディストリビューションで指定する値を示しています。  
   + 以下の CloudFront URL は、ディストリビューション内のイメージファイルの URL です (CloudFront ドメイン名を使用)。`image.jpg` は `images` ディレクトリにあります。URL 内のファイルへのパスは、HTTP サーバーまたは Amazon S3 バケットのファイルへのパスに一致する必要があります。

     `https://d111111abcdef8.cloudfront.net/images/image.jpg`
   + 以下の CloudFront URL には、クエリ文字列が含まれます。

     `https://d111111abcdef8.cloudfront.net/images/image.jpg?size=large`
   + 以下の CloudFront URL は、ディストリビューション内のイメージファイルの URL です。両方の URL で代替ドメイン名が使用されており、2 番目の URL にはクエリ文字列が含まれています。

     `https://www.example.com/images/image.jpg`

     `https://www.example.com/images/image.jpg?color=red`
   + 以下の CloudFront URL は、代替ドメイン名と HTTPS プロトコルを使用するディストリビューション内のイメージファイルの URL です。

     `https://www.example.com/images/image.jpg`  
**2. `?` **  
`?` は、クエリ文字列パラメータがベース URL の後に続くことを示します。クエリパラメータを指定しない場合でも、`?` を含めます。  
以下のクエリパラメータは任意の順序で指定できます。  
**3. *クエリ文字パラメータ (ある場合*`&`**  
(オプション) 独自のクエリ文字列パラメータを入力できます。これを行うには、各パラメータ間にアンパサンド (&) を追加します (例: `color=red&size=medium`)。クエリ文字列パラメータは、URL 内に任意の順序で指定できます。  
クエリ文字列パラメータに `Policy`、`Signature`、または `Key-Pair-Id` という名前を付けることはできません。
独自のパラメータを追加する場合は、各パラメータの後に `&` を付加します (最後のパラメータにも付加します)。  
**4. `Policy=`*ポリシーステートメントの base64 エンコードバージョン***  
空白が削除されて base64 エンコードされた、JSON 形式のポリシーステートメント。詳細については、「[カスタムポリシーを使用する署名付き URL のポリシーステートメントを作成する](#private-content-custom-policy-statement)」を参照してください。  
ポリシーステートメントは、署名付き URL によってユーザーに許可されるアクセスをコントロールします。これには、ファイルの URL、有効期限切れ日時、URL が有効になる日時 (オプション)、ファイルへのアクセスが許可されている IP アドレスまたは IP アドレス範囲 (オプション) が含まれます。  
**5. `&Signature=`*ハッシュ化および署名されたバージョンのポリシーステートメント***  
ハッシュ化され、署名された base64 エンコードバージョンの JSON ポリシーステートメント。詳細については、「[カスタムポリシーを使用する署名付き URL の署名を作成する](#private-content-custom-policy-creating-signature)」を参照してください。  
**6. `&Key-Pair-Id=`*署名の生成に使用しているプライベートキーに対応する CloudFront パブリックキーのパブリックキー ID***  
CloudFront パブリックキーの ID (`K2JCJMDEHXQW5F` など)。パブリックキー ID は、署名付き URL の検証に使用するパブリックキーを CloudFront に通知します。CloudFront は、署名内の情報をポリシーステートメント内の情報と比較して、URL が改ざんされていないことを確認します。  
このパブリックキーは、ディストリビューションの信頼された署名者であるキーグループに属している必要があります。詳細については、「[署名付き URL と署名付き Cookie を作成できる署名者を指定する](private-content-trusted-signers.md)」を参照してください。

## カスタムポリシーを使用する署名付き URL のポリシーステートメントを作成する
<a name="private-content-custom-policy-statement"></a>

カスタムポリシーを使用する署名付き URL のポリシーステートメントを作成するには、以下の手順を実行します。

さまざまな方法でファイルへのアクセスを制御するポリシーステートメントの例については、「[カスタムポリシーを使用する署名付き URL のポリシーステートメントの例](#private-content-custom-policy-statement-examples)」を参照してください。<a name="private-content-custom-policy-creating-policy-procedure"></a>

**カスタムポリシーを使用する署名付き URL のポリシーステートメントを作成するには**

1. 以下の JSON 形式を使用してポリシーステートメントを構築します。小なり記号 (`<`) と大なり記号 (`>`)、およびそれらの中の説明は、独自の値に置き換えます。詳細については、「[カスタムポリシーを使用する署名付き URL のポリシーステートメントで指定する値](#private-content-custom-policy-statement-values)」を参照してください。

   ```
   {
       "Statement": [
           {
               "Resource": "<Optional but recommended: URL of the file>",
               "Condition": {
                   "DateLessThan": {
   	                "AWS:EpochTime": <Required: ending date and time in Unix time format and UTC>
                   },
                   "DateGreaterThan": {
   	                "AWS:EpochTime": <Optional: beginning date and time in Unix time format and UTC>
                   },
                   "IpAddress": {
   	                "AWS:SourceIp": "<Optional: IP address>"
                   }
               }
           }
       ]
   }
   ```

   次の点に注意してください。
   + ポリシーには、1 つのステートメントのみを含めることができます。
   + UTF-8 文字エンコードを使用します。
   + すべての句読点およびパラメータ名を、指定されたとおりに正確に含めます。パラメータ名の省略形は受け付けられません。
   + `Condition` セクションのパラメータの順序は問題ではありません。
   + `Resource`、`DateLessThan`、`DateGreaterThan`、および `IpAddress` の値については、「[カスタムポリシーを使用する署名付き URL のポリシーステートメントで指定する値](#private-content-custom-policy-statement-values)」を参照してください。

1. ポリシーステートメントからすべての空白 (タブと改行文字を含む) を削除します。アプリケーションコード内の文字列にエスケープ文字を含めることが必要になる場合があります。

1. MIME base64 エンコーディングを使用してポリシーステートメントを Base64 エンコードします。詳細については、*RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies* の [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) を参照してください。

1. URL クエリ文字列内の無効な文字を有効な文字で置き換えます。次の表に無効な文字と有効な文字を示します。  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html)

1. 結果の値を署名付き URL の `Policy=` の後に付加します。

1. ポリシーステートメントのハッシュ化、署名、および base64 エンコードを行って、署名付き URL の署名を作成します。詳細については、「[カスタムポリシーを使用する署名付き URL の署名を作成する](#private-content-custom-policy-creating-signature)」を参照してください。

### カスタムポリシーを使用する署名付き URL のポリシーステートメントで指定する値
<a name="private-content-custom-policy-statement-values"></a>

カスタムポリシーのポリシーステートメントを作成する場合、以下の値を指定します。

**リソース**  
クエリ文字列 (ある場合) が含まれる URL。ただし、CloudFront の `Policy`、`Signature`、および `Key-Pair-Id` パラメータが除外されます。例えば、次のようになります。  
`https://d111111abcdef8.cloudfront.net/images/horizon.jpg\?size=large&license=yes`  
`Resource` の URL の値は 1 つだけ指定できます。  
ポリシーで、`Resource` パラメータを省略できますが、その場合、署名付き URL を持つすべてのユーザーが、署名付き URL の作成に使用するキーペアに関連付けられた*あらゆる*ディストリビューションの*すべての*ファイルにアクセスできることになります。
次の点に注意してください。  
+ **プロトコル** – 値は `http://`、`https://`、または `*://` で始まっている必要があります。
+ **クエリ文字列パラメータ** - URL にクエリ文字列パラメータがある場合は、バックスラッシュ文字 (`\`) を使用してクエリ文字列の最初の疑問符 (`?`) をエスケープします。例えば、次のようになります。

  `https://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes`
+ **ワイルドカード文字** – ポリシーの URL にはワイルドカード文字を使用できます。次のワイルドカード文字がサポートされています。
  + アスタリスク (`*`) は、0 個以上の文字に一致します
  + 疑問符 (`?`) は、1 つの文字に一致します

  CloudFront がポリシー内の URL を HTTP リクエスト内の URL と照合すると、ポリシー内の URL は次のように 4 つのセクション (プロトコル、ドメイン、パス、クエリ文字列) に分割されます。

  `[protocol]://[domain]/[path]\?[query string]`

  ポリシーの URL にワイルドカード文字を使用する場合、ワイルドカードマッチングはワイルドカードを含むセクションの境界内でのみ適用されます。例えば、次のようなポリシーの URL を考えてみます。

  `https://www.example.com/hello*world`

  この例では、アスタリスクワイルドカード (`*`) はパスセクション内にのみ適用されるため、URL `https://www.example.com/helloworld` や `https://www.example.com/hello-world` には一致しますが、URL `https://www.example.net/hello?world` には一致しません。

  ワイルドカードマッチングのセクションの境界には、次の例外が適用されます。
  + パスセクションの末尾にアスタリスクがある場合、クエリ文字列セクションにアスタリスクが付いていることを意味します。例えば、`http://example.com/hello*` と `http://example.com/hello*\?*` は同じです。
  + ドメインセクションの末尾にアスタリスクがある場合、パスセクションとクエリ文字列セクションの両方にアスタリスクが付いていることを意味します。例えば、`http://example.com*` と `http://example.com*/*\?*` は同じです。
  + ポリシーの URL では、プロトコルセクションを省略し、ドメインセクションをアスタリスクで始めることができます。その場合、プロトコルセクションは暗黙的にアスタリスクに設定されます。例えば、ポリシーの URL `*example.com` は `*://*example.com/` と同等です。
  + アスタリスク (`"Resource": "*"`) 単独の場合は、どの URL にも一致します。

  例えば、ポリシーの値 `https://d111111abcdef8.cloudfront.net/*game_download.zip*` は、次の URL すべてに一致します。
  + `https://d111111abcdef8.cloudfront.net/game_download.zip`
  + `https://d111111abcdef8.cloudfront.net/example_game_download.zip?license=yes`
  + `https://d111111abcdef8.cloudfront.net/test_game_download.zip?license=temp`
+ **代替ドメイン名** – ポリシーの URL で代替ドメイン名 (CNAME) を指定する場合、HTTP リクエストはウェブページまたはアプリケーション内の代替ドメイン名を使用する必要があります。ポリシーのファイルの Amazon S3 URL を指定しないでください。

**DateLessThan**  
URL の有効期限切れ日時。Unix 時間形式 (秒単位) および協定世界時 (UTC) で指定します。ポリシーでは、値を引用符で囲まないでください。UTC の詳細については、「[Date and Time on the Internet: Timestamps](https://tools.ietf.org/html/rfc3339)」を参照してください。  
たとえば、UTC の 2023 年 1 月 31 日午前 10 時 00 分は、Unix 時間形式の 1675159200 に変換されます。  
これは、`Condition` セクションにおける唯一の必須パラメータです。CloudFront では、プライベートコンテンツへの永久的なアクセスがユーザーに許可されることのないよう、この値の指定が要求されます。  
詳細については、[CloudFront が署名付き URL の有効期限切れの日時を確認するタイミング](private-content-signed-urls.md#private-content-check-expiration)を参照してください。

**DateGreaterThan (オプション)**  
オプションの URL 開始日時。Unix 時間形式 (秒単位) および協定世界時 (UTC) で指定します。ユーザーは、指定された日時が過ぎるまでファイルにアクセスできません。値を引用符で囲まないでください。

**IpAddress (オプション)**  
HTTP リクエストを実行するクライアントの IP アドレス。次の点に注意してください。  
+ ファイルへのアクセスをすべての IP アドレスに許可するには、`IpAddress` パラメータを省略します。
+ IP アドレスまたは IP アドレス範囲を 1 つ指定できます。2 つの別々の範囲のどちらかにクライアントの IP アドレスが入っている場合にアクセスを許可するようなポリシーを使用することはできません。
+ 1 つの IP アドレスからのアクセスを許可するには、以下のように指定します。

  `"`*IPv4 IP アドレス*`/32"`
+ IP アドレス範囲は標準の IPv4 CIDR 形式 (`192.0.2.0/24` など) で指定する必要があります。詳細については、「[Classless Inter-domain Routing (CIDR): The Internet Address Assignment and Aggregation Plan](https://tools.ietf.org/html/rfc4632)」を参照してください。
**重要**  
IPv6 形式の IP アドレス (例: 2001:0db8:85a3::8a2e:0370:7334) はサポートされていません。

  `IpAddress` を含むカスタムポリシーを使用する場合、ディストリビューションで IPv6 は有効にしません。一部のコンテンツへのアクセスを IP アドレスによって制限し、他のコンテンツで IPv6 リクエストをサポートする場合、2 つのディストリビューションを作成します。詳細については、トピック「[すべてのディストリビューション設定リファレンス](distribution-web-values-specify.md)」の「[IPv6 を有効にする (ビューワーリクエスト)](DownloadDistValuesGeneral.md#DownloadDistValuesEnableIPv6)」を参照してください。

## カスタムポリシーを使用する署名付き URL のポリシーステートメントの例
<a name="private-content-custom-policy-statement-examples"></a>

以下のポリシーステートメントの例は、特定のファイル、ディレクトリ内のすべてのファイル、またはキーペア ID に関連付けられたすべてのファイルへのアクセスを制御する方法を示しています。また、この例は、個々の IP アドレスまたは IP アドレス範囲からのアクセスを制御する方法、および指定された日時以降にユーザーが署名付き URL を使用することを禁止する方法も示しています。

これらの例のいずれかをコピーして貼り付ける場合は、すべての空白 (タブと改行文字を含む) を削除し、値を独自の値に置き換えて、右の中かっこ (`}`) の後に改行文字を含めます。

詳細については、「[カスタムポリシーを使用する署名付き URL のポリシーステートメントで指定する値](#private-content-custom-policy-statement-values)」を参照してください。

**Topics**
+ [

### ポリシーステートメントの例: IP アドレス範囲から 1 つのファイルにアクセスする
](#private-content-custom-policy-statement-example-one-object)
+ [

### ポリシーステートメントの例: IP アドレス範囲からディレクトリ内のすべてのファイルにアクセスする
](#private-content-custom-policy-statement-example-all-objects)
+ [

### ポリシーステートメントの例: キーペア ID に関連付けられたすべてのファイルに 1 つの IP アドレスからアクセスする
](#private-content-custom-policy-statement-example-one-ip)

### ポリシーステートメントの例: IP アドレス範囲から 1 つのファイルにアクセスする
<a name="private-content-custom-policy-statement-example-one-object"></a>

次の署名付き URL 内のカスタムポリシーの例では、UTC の 2023 年 1 月 31 日午前 10 時 00 分まで、範囲 `192.0.2.0/24` の IP アドレスから、ユーザーがファイル `https://d111111abcdef8.cloudfront.net/game_download.zip` にアクセスできることを指定しています。

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/game_download.zip",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.0/24"
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1675159200
                }
            }
        }
    ]
}
```

### ポリシーステートメントの例: IP アドレス範囲からディレクトリ内のすべてのファイルにアクセスする
<a name="private-content-custom-policy-statement-example-all-objects"></a>

以下のカスタムポリシーの例では、`Resource` パラメータのアスタリスクワイルドカード文字 (`*`) が示すとおり、`training` ディレクトリ内のあらゆるファイルを対象とする署名付き URL を作成できます。UTC の 2023 年 1 月 31 日午前 10 時 00 分まで、範囲 `192.0.2.0/24` の IP アドレスから、ユーザーはファイルにアクセスできます。

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/training/*",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.0/24"
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1675159200
                }
            }
        }
    ]
}
```

このポリシーを使用する各署名付き URL には、次のように、特定のファイルを識別する URL があります。

`https://d111111abcdef8.cloudfront.net/training/orientation.pdf`

### ポリシーステートメントの例: キーペア ID に関連付けられたすべてのファイルに 1 つの IP アドレスからアクセスする
<a name="private-content-custom-policy-statement-example-one-ip"></a>

以下のカスタムポリシーの例では、`Resource` パラメータのアスタリスクワイルドカード文字 (`*`) が示すとおり、あらゆるディストリビューションに関連付けられたあらゆるファイルを対象とする署名付き URL を作成できます。署名付き URL には、`http://` ではなく `https://` プロトコルを使用する必要があります。ユーザーは IP アドレス `192.0.2.10/32` を使用する必要があります。(CIDR 表記の値 `192.0.2.10/32` は 1 つの IP アドレス `192.0.2.10` を参照します)。ファイルは、UTC の 2023 年 1 月 31 日午前 10 時 00 分から UTC の 2023 年 2 月 2 日午前 10 時 00 分まで使用できます。

```
{
    "Statement": [
       {
            "Resource": "https://*",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.10/32"
                },
                "DateGreaterThan": {
                    "AWS:EpochTime": 1675159200
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1675332000
                }
            }
        }
    ]
}
```

このポリシーを使用する各署名付き URL には、次のように、特定の CloudFront ディストリビューション内の特定のファイルを識別する URL があります。

`https://d111111abcdef8.cloudfront.net/training/orientation.pdf`

署名付き URL にはキーペア ID も含まれます。キーペア ID は、URL に指定されたディストリビューション (d111111abcdef8.cloudfront.net) 内の信頼されたキーグループに関連付けられる必要があります。

## カスタムポリシーを使用する署名付き URL の署名を作成する
<a name="private-content-custom-policy-creating-signature"></a>

カスタムポリシーを使用する署名付き URL の署名は、ハッシュ化、署名、および base64 エンコードが行われたバージョンのポリシーステートメントです。カスタムポリシーの署名を作成するには、以下の手順を実行します。

ポリシーステートメントのハッシュ化、署名、およびエンコードを行う方法の詳細および例については、以下の各資料を参照してください。
+ [Linux コマンドおよび OpenSSL を使用した Base64 エンコードおよび暗号化](private-content-linux-openssl.md)
+ [署名付き URL の署名を作成するためのコード例](PrivateCFSignatureCodeAndExamples.md)<a name="private-content-custom-policy-creating-signature-download-procedure"></a>

**オプション 1: カスタムポリシーを使用して署名を作成するには**

1. 「[カスタムポリシーを使用する署名付き URL のポリシーステートメントを作成するには](#private-content-custom-policy-creating-policy-procedure)」の手順で作成した JSON ポリシーステートメントを、SHA-1 ハッシュ関数と生成した RSA または ECDSA プライベートキーを使用してハッシュ化し、署名します。空白は含まれていないが、まだ base64 エンコードされていないバージョンのポリシーステートメントを使用します。

   ハッシュ関数に必要なプライベートキーには、対応するパブリックキーがディストリビューション内のアクティブな信頼されたキーグループにあるものを使用してください。
**注記**  
ポリシーステートメントをハッシュ化および署名するための方法は、プログラミング言語およびプラットフォームによって異なります。サンプルコードについては、「[署名付き URL の署名を作成するためのコード例](PrivateCFSignatureCodeAndExamples.md)」を参照してください。

1. ハッシュ化および署名された文字列から、空白 (タブや改行文字を含む) を削除します。

1. MIME base64 エンコーディングを使用して文字列を Base64 エンコードします。詳細については、*RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies* の [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) を参照してください。

1. URL クエリ文字列内の無効な文字を有効な文字で置き換えます。次の表に無効な文字と有効な文字を示します。  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html)

1. 結果の値を署名付き URL の `&Signature=` の後に付加し、「[カスタムポリシーを使用して署名付き URL を作成するには](#private-content-creating-signed-url-custom-policy-procedure)」に戻って、署名付き URL の各パートの連結を終了します。

# 署名付き Cookie を使用する
<a name="private-content-signed-cookies"></a>

CloudFront 署名付き Cookie を使用すると、現在の URL を変更したくない場合や、複数の制限付きファイル (ウェブサイトの購読者の領域にあるすべてのファイルなど) へのアクセスを提供する場合に、誰がコンテンツにアクセスできるかを制御できます。このトピックでは、署名付き Cookie を使用する際の考慮事項と、既定ポリシーとカスタムポリシーを使用するように署名付き Cookie を設定する方法について説明します。

**Topics**
+ [

## 署名付き Cookie に既定ポリシーを使用するか、カスタムポリシーを使用するかを決定する
](#private-content-choosing-canned-custom-cookies)
+ [

## 署名付き Cookie の仕組み
](#private-content-how-signed-cookies-work)
+ [

## 署名付き Cookie の悪用を防止する
](#private-content-signed-cookie-misuse)
+ [

## CloudFront が署名付き Cookie の有効期限切れ日時を確認するタイミング
](#private-content-check-expiration-cookie)
+ [

## サンプルコードおよびサードパーティーツール
](#private-content-overview-sample-code-cookies)
+ [

# 既定ポリシーを使用して署名付き Cookie を設定する
](private-content-setting-signed-cookie-canned-policy.md)
+ [

# カスタムポリシーを使用して署名付き Cookie を設定する
](private-content-setting-signed-cookie-custom-policy.md)
+ [

# PHP を使用して署名付き cookie を作成する
](signed-cookies-PHP.md)

## 署名付き Cookie に既定ポリシーを使用するか、カスタムポリシーを使用するかを決定する
<a name="private-content-choosing-canned-custom-cookies"></a>

署名付き Cookie を作成する場合、Cookie の有効期間など、署名付き Cookie で制限を指定する JSON 形式のポリシーステートメントを作成します。既定ポリシーまたはカスタムポリシーを使用できます。次の表では、既定ポリシーとカスタムポリシーを比較しています。


****  

| 説明 | 既定ポリシー | カスタムポリシー | 
| --- | --- | --- | 
| ポリシーステートメントを複数のファイル用に再利用できる。ポリシーステートメントを再利用するには、`Resource` オブジェクトでワイルドカード文字を使用する必要があります。(詳しくは、「[署名付き Cookie のカスタムポリシーのポリシーステートメントで指定する値](private-content-setting-signed-cookie-custom-policy.md#private-content-custom-policy-statement-cookies-values)」を参照してください)。 | いいえ | はい | 
| ユーザーがコンテンツへのアクセスを開始できる日時を指定できる | いいえ | はい (オプション) | 
| ユーザーがコンテンツにアクセスできなくなる日時を指定できる | はい | はい | 
| コンテンツにアクセスできるユーザーの IP アドレスまたは IP アドレス範囲を指定できる | いいえ | はい (オプション) | 

既定ポリシーを使用して署名付き Cookie を作成する方法については、「[既定ポリシーを使用して署名付き Cookie を設定する](private-content-setting-signed-cookie-canned-policy.md)」を参照してください。

カスタムポリシーを使用して署名付き Cookie を作成する方法については、「[カスタムポリシーを使用して署名付き Cookie を設定する](private-content-setting-signed-cookie-custom-policy.md)」を参照してください。

## 署名付き Cookie の仕組み
<a name="private-content-how-signed-cookies-work"></a>

ここでは、署名付き Cookie 用に CloudFront を設定する方法と、ユーザーが署名付き Cookie を含むリクエストを送信した場合の CloudFront の応答の概要を示します。

1. CloudFront ディストリビューションで、1 つ以上の信頼されたキーグループを指定します。指定したグループには、CloudFront が URL 署名の検証に使用できるパブリックキーが含まれている必要があります。対応するプライベートキーを使用して URL に署名します。

   詳細については、「[署名付き URL と署名付き Cookie を作成できる署名者を指定する](private-content-trusted-signers.md)」を参照してください。

1. ユーザーがコンテンツにアクセスできるかどうかを判断し、アクセスできる場合は、3 つの `Set-Cookie` ヘッダーをビューワーに送信するアプリケーションを開発します (各 `Set-Cookie` ヘッダーには名前と値のペアを 1 つだけ含めることができ、CloudFront 署名付き Cookie では 3 つの名前と値のペアが必要です)。ビューワーがプライベートコンテンツをリクエストする前に、ビューワーに `Set-Cookie` ヘッダーを送信する必要があります。Cookie の有効期限を短く設定した場合、ユーザーがアクセスを続行できるように、以降のリクエストに対してさらに 3 つの `Set-Cookie` ヘッダーを送信することもできます。

   通常、CloudFront ディストリビューションには少なくとも 2 つのキャッシュ動作があります。認証を必要としないものと、認証を必要とするものです。サイトのセキュリティで保護された部分のエラーページには、ログインページへのリダイレクタまたはリンクが含まれます。

   Cookie に基づいてファイルをキャッシュするようにディストリビューションを設定している場合、CloudFront は署名付き Cookie の属性に基づいて個別のファイルをキャッシュしません。

1. ユーザーがウェブサイトにサインインし、コンテンツに対して支払いをするか、またはその他のアクセスの要件を満たします。

1. アプリケーションは、レスポンスで `Set-Cookie` ヘッダーを返し、ビューワーは名前と値のペアを格納します。

1. ユーザーがファイルをリクエストします。

   ユーザーのブラウザまたはその他のビューワーは、ステップ 4 の名前と値のペアを取得し、リクエストの `Cookie` ヘッダーに追加します。これが署名付き Cookie です。

1. CloudFront はパブリックキーを使用して、署名付き Cookie の署名を検証し、Cookie が改ざんされていないことを確認します。署名が無効である場合、リクエストは拒否されます。

   Cookie の署名が有効である場合、CloudFront は Cookie のポリシーステートメントを参照して (または既定ポリシーを使用している場合はポリシーステートメントを作成して)、リクエストがまだ有効であることを確認します。たとえば、Cookie の開始日時と終了日時が指定されていれば、CloudFront は、アクセスが許可されている期間にユーザーがコンテンツへのアクセスを試みていることを確認します。

   リクエストがポリシーステートメントの要件を満たしている場合、CloudFront は制限されていないコンテンツの場合と同様にコンテンツを供給します。つまり、ファイルがエッジキャッシュにすでに存在するかどうかを確認し、必要に応じてリクエストをオリジンに転送して、ファイルをユーザーに返します。

## 署名付き Cookie の悪用を防止する
<a name="private-content-signed-cookie-misuse"></a>

`Set-Cookie` ヘッダーで `Domain` パラメータを指定する場合、同一ルートドメイン名を使用するユーザーによる潜在的なアクセスを低減できる、最も厳密な値を指定します。たとえば、apex.example.com は、特に example.com を制御しない場合は、example.com よりも優先されます。これによって、ユーザーが example.com のコンテンツにアクセスすることを防止できます。

この種類の攻撃を防ぐには、以下の作業を行います。
+ `Expires` ヘッダーでセッション Cookie が作成されるように、`Max-Age` および `Set-Cookie` Cookie 属性を除外します。セッション Cookie は、ユーザーがブラウザを閉じたときに自動的に削除されるため、ユーザーがコンテンツに不正アクセスする可能性が低くなります。
+ ビューワーがリクエストに Cookie を含める場合に Cookie が暗号化されるように、`Secure` 属性を含めます。
+ 可能な場合、カスタムポリシーを使用してビューワーの IP アドレスを含めます。
+ `CloudFront-Expires` 属性では、ユーザーがコンテンツにアクセスできるようにする期間に基づいて、最短で適切な有効期限の時刻を指定します。

## CloudFront が署名付き Cookie の有効期限切れ日時を確認するタイミング
<a name="private-content-check-expiration-cookie"></a>

署名付き Cookie がまだ有効であるかどうかを確認するために、CloudFront は HTTP リクエスト時に、Cookie の有効期限切れ日時を確認します。有効期限切れ時刻の直前にクライアントが大きなファイルのダウンロードを開始した場合、ダウンロード中に有効期限切れ時刻が経過してもダウンロードは完了します。TCP 接続が中断し、有効期限切れ時刻が経過した後にクライアントがダウンロードを再開した場合、ダウンロードは失敗します。

クライアントが、ファイルを断片的に取得するレンジ GET を使用した場合、有効期限切れ時刻が経過した後に実行された GET リクエストは失敗します。レンジ GET の詳細については、「[CloudFront がオブジェクトの部分的リクエスト (レンジ GET) を処理する方法](RangeGETs.md)」を参照してください。

## サンプルコードおよびサードパーティーツール
<a name="private-content-overview-sample-code-cookies"></a>

プライベートコンテンツ用のサンプルコードは、署名付き URL の署名を作成する方法のみを示しています。ただし、署名付き Cookie の署名を作成するプロセスは非常によく似ており、サンプルコードの多くの部分は関連しています。詳細については、以下の各トピックを参照してください。
+ [Perl を使用して URL 署名を作成する](CreateURLPerl.md)
+ [PHP を使用して URL 署名を作成する](CreateURL_PHP.md)
+ [C\$1 と .NET Framework を使用して URL 署名を作成する](CreateSignatureInCSharp.md)
+ [Java を使用して URL 署名を作成する](CFPrivateDistJavaDevelopment.md)

# 既定ポリシーを使用して署名付き Cookie を設定する
<a name="private-content-setting-signed-cookie-canned-policy"></a>

既定ポリシーを使用して署名付き Cookie を設定するには、以下のステップを実行します。署名を作成するには、「[既定ポリシーを使用する署名付き Cookie の署名を作成する](#private-content-canned-policy-signature-cookies)」を参照してください。<a name="private-content-setting-signed-cookie-canned-policy-procedure"></a>

**既定ポリシーを使用して署名付き Cookie を設定するには**

1. .NET または Java を使用して署名付き Cookie を作成しており、キーペアのプライベートキーをデフォルトの .pem 形式から .NET または Java 対応の形式に変更していない場合は、それを変換します。詳細については、「[プライベートキーの形式を変更する (.NET および Java のみ)](private-content-trusted-signers.md#private-content-reformatting-private-key)」を参照してください。

1. 承認されたビューワーに 3 つの `Set-Cookie` ヘッダーを送信するアプリケーションをプログラムします。各 `Set-Cookie` ヘッダーには名前と値のペアを 1 つだけ含めることができ、CloudFront 署名付き Cookie では 3 つの名前と値のペアが必要であるため、3 つの `Set-Cookie` ヘッダーが必要です。名前と値のペアは、`CloudFront-Expires`、`CloudFront-Signature`、および `CloudFront-Key-Pair-Id` です。アクセスを制御するファイルに対してユーザーが最初のリクエストを行う前に、値がビューワーに存在している必要があります。
**注記**  
一般的に、`Expires` 属性と `Max-Age` 属性を除外することをお勧めします。これらの属性を除外すると、ユーザーがブラウザを閉じたときに、ブラウザで Cookie が削除されるため、ユーザーがコンテンツに不正アクセスする可能性が低くなります。詳細については、「[署名付き Cookie の悪用を防止する](private-content-signed-cookies.md#private-content-signed-cookie-misuse)」を参照してください。

   **Cookie の属性の名前では、大文字と小文字が区別されます**。

   改行は、属性を判読しやすくするためにのみ含まれています。

   ```
   Set-Cookie: 
   CloudFront-Expires=date and time in Unix time format (in seconds) and Coordinated Universal Time (UTC); 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   
   Set-Cookie: 
   CloudFront-Signature=hashed and signed version of the policy statement; 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   
   Set-Cookie: 
   CloudFront-Key-Pair-Id=public key ID for the CloudFront public key whose corresponding private key you're using to generate the signature; 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   ```  
**(オプション) `Domain`**  
リクエストされたファイルのドメイン名。`Domain` 属性を指定しない場合、デフォルト値は URL のドメイン名で、指定されたドメイン名にのみ適用され、サブドメインには適用されません。`Domain` 属性を指定する場合、サブドメインにも適用されます。ドメイン名の先頭のドット (例えば、`Domain=.example.com`) はオプションです。さらに、`Domain` 属性を指定する場合は、URL のドメイン名と `Domain` 属性の値が一致している必要があります。  
CloudFront がディストリビューションに割り当てたドメイン名 (d111111abcdef8.cloudfront.net など) を指定することはできますが、\$1.cloudfront.net をドメイン名として指定することはできません。  
URL で代替ドメイン名 (example.com など) を使用する場合は、`Domain` 属性を指定するかどうかにかかわらず、代替ドメイン名をディストリビューションに追加する必要があります。詳細については、トピック「[すべてのディストリビューション設定リファレンス](distribution-web-values-specify.md)」の「[代替ドメイン名 (CNAME)](DownloadDistValuesGeneral.md#DownloadDistValuesCNAME)」を参照してください。  
**(オプション) `Path`**  
リクエストされたファイルのパス。`Path` 属性を指定しない場合、デフォルト値は URL のパスです。  
**`Secure`**  
リクエストを送信する前に、ビューワーが Cookie を暗号化することを要求します。Cookie の属性を中間者攻撃から保護するために、HTTPS 接続で `Set-Cookie` ヘッダーを送信することをお勧めします。  
**`HttpOnly`**  
ブラウザ (サポートされている場合) が Cookie 値とどのようにやり取りするかを定義します。`HttpOnly` では、Cookie 値は JavaScript からアクセスできません。この予防策は、クロスサイトスクリプティング (XSS) 攻撃の軽減に役立ちます。詳細については、「[HTTP Cookie の使用](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)」を参照してください。  
**`CloudFront-Expires`**  
有効期限切れ日時を Unix 時間形式 (秒単位) および協定世界時 (UTC) で指定します。例えば、UTC の 2026 年 1 月 1 日午前 10 時 00 分は、Unix 時間形式の 1767290400 に変換されます。  
エポック時間を使用するには、`9223372036854775807` (2262 年 4 月 11 日金曜日の 23:47:16.854 UTC) 以前の日付に 64 ビット整数を指定します。  
UTC の詳細については、*RFC 3339, Date and Time on the Internet: Timestamps* ([https://tools.ietf.org/html/rfc3339](https://tools.ietf.org/html/rfc3339)) を参照してください。  
**`CloudFront-Signature`**  
ハッシュ化され、署名された base64 エンコードバージョンの JSON ポリシーステートメント。詳細については、「[既定ポリシーを使用する署名付き Cookie の署名を作成する](#private-content-canned-policy-signature-cookies)」を参照してください。  
**`CloudFront-Key-Pair-Id`**  
CloudFront パブリックキーの ID (`K2JCJMDEHXQW5F` など)。パブリックキー ID は、署名付き URL の検証に使用するパブリックキーを CloudFront に通知します。CloudFront は、署名内の情報をポリシーステートメント内の情報と比較して、URL が改ざんされていないことを確認します。  
このパブリックキーは、ディストリビューションの信頼された署名者であるキーグループに属している必要があります。詳細については、「[署名付き URL と署名付き Cookie を作成できる署名者を指定する](private-content-trusted-signers.md)」を参照してください。

以下は、ファイルの URL のディストリビューションに関連付けられたドメイン名を使用する場合の、1 つの署名付き Cookie の `Set-Cookie` ヘッダーの例です。

```
Set-Cookie: CloudFront-Expires=1426500000; Domain=d111111abcdef8.cloudfront.net; Path=/images/*; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=yXrSIgyQoeE4FBI4eMKF6ho~CA8_; Domain=d111111abcdef8.cloudfront.net; Path=/images/*; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=d111111abcdef8.cloudfront.net; Path=/images/*; Secure; HttpOnly
```

以下は、ファイルの URL に代替ドメイン名 example.org を使用している場合の、1 つの署名付き Cookie の `Set-Cookie` ヘッダーの例です。

```
Set-Cookie: CloudFront-Expires=1426500000; Domain=example.org; Path=/images/*; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=yXrSIgyQoeE4FBI4eMKF6ho~CA8_; Domain=example.org; Path=/images/*; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=example.org; Path=/images/*; Secure; HttpOnly
```

URL で代替ドメイン名 (example.com など) を使用する場合は、`Domain` 属性を指定するかどうかにかかわらず、代替ドメイン名をディストリビューションに追加する必要があります。詳細については、トピック「[すべてのディストリビューション設定リファレンス](distribution-web-values-specify.md)」の「[代替ドメイン名 (CNAME)](DownloadDistValuesGeneral.md#DownloadDistValuesCNAME)」を参照してください。

## 既定ポリシーを使用する署名付き Cookie の署名を作成する
<a name="private-content-canned-policy-signature-cookies"></a>

既定ポリシーを使用する署名付き Cookie の署名を作成するには、次の手順を実行します。

**Topics**
+ [

### 既定ポリシーを使用する署名付き Cookie のポリシーステートメントを作成する
](#private-content-canned-policy-statement-cookies)
+ [

### 既定ポリシーを使用する署名付き Cookie の署名を作成するためのポリシーステートメントに署名する
](#private-content-canned-policy-cookies-signing-policy-statement)

### 既定ポリシーを使用する署名付き Cookie のポリシーステートメントを作成する
<a name="private-content-canned-policy-statement-cookies"></a>

既定ポリシーを使用する署名付き Cookie を設定した場合、`CloudFront-Signature` 属性は、ポリシーステートメントのハッシュ化および署名されたバージョンです。カスタムポリシーを使用する署名付き Cookie とは異なり、既定ポリシーを使用する署名付き Cookie では、`Set-Cookie` ヘッダーにポリシーステートメントを含めません。ポリシーステートメントを作成するには、以下の手順を実行します。<a name="private-content-canned-policy-statement-cookies-procedure"></a>

**既定ポリシーを使用する署名付き Cookie のポリシーステートメントを作成するには**

1. 以下の JSON 形式および UTF-8 文字エンコードを使用してポリシーステートメントを構築します。すべての句読点および他のリテラル値を、指定されたとおりに正確に含めます。`Resource` および `DateLessThan` パラメータの詳細については、「[署名付き Cookie の既定ポリシーのポリシーステートメントで指定する値](#private-content-canned-policy-statement-cookies-values)」を参照してください。

   ```
   {
       "Statement": [
           {
               "Resource": "base URL or stream name",
               "Condition": {
                   "DateLessThan": {
                       "AWS:EpochTime": ending date and time in Unix time format and UTC
                   }
               }
           }
       ]
   }
   ```

1. ポリシーステートメントからすべての空白 (タブと改行文字を含む) を削除します。アプリケーションコード内の文字列にエスケープ文字を含めることが必要になる場合があります。

#### 署名付き Cookie の既定ポリシーのポリシーステートメントで指定する値
<a name="private-content-canned-policy-statement-cookies-values"></a>

既定ポリシーのポリシーステートメントを作成する場合、以下の値を指定します。

**リソース**  
クエリ文字列 (存在する場合) を含むベース URL。以下に例を示します。  
`https://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes`  
`Resource` の日付形式は 1 つだけ指定できます。  
次の点に注意してください。  
+ **プロトコル** – 値は `http://` または `https://` で始まっている必要があります。
+ **クエリ文字列パラメータ** – クエリ文字列パラメータがない場合は、疑問符を省略します。
+ **代替ドメイン名** – URL で代替ドメイン名 (CNAME) を指定する場合は、ウェブページまたはアプリケーション内のファイルを参照するときに代替ドメイン名を指定する必要があります。ファイルの Amazon S3 URL を指定しないでください。

**DateLessThan**  
URL の有効期限切れ日時。Unix 時間形式 (秒単位) および協定世界時 (UTC) で指定します。値を引用符で囲まないでください。  
たとえば、UTC の 2015 年 3 月 16 日午前 10 時 00 分は、UNIX 時間形式の 1426500000 に変換されます。  
この値は、`CloudFront-Expires` ヘッダーの `Set-Cookie` 属性の値と一致する必要があります。値を引用符で囲まないでください。  
詳細については、「[CloudFront が署名付き Cookie の有効期限切れ日時を確認するタイミング](private-content-signed-cookies.md#private-content-check-expiration-cookie)」を参照してください。

#### 既定ポリシーのポリシーステートメントの例
<a name="private-content-canned-policy-cookies-sample-policy-statement"></a>

署名付き Cookie 内で以下のポリシーステートメントの例を使用すると、ユーザーは、UTC の 2015 年 3 月 16 日午前 10 時 00 分までファイル `https://d111111abcdef8.cloudfront.net/horizon.jpg` にアクセスできます。

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/horizon.jpg?size=large&license=yes",
            "Condition": {
                "DateLessThan": {
                    "AWS:EpochTime": 1426500000
                }
            }
        }
    ]
}
```

### 既定ポリシーを使用する署名付き Cookie の署名を作成するためのポリシーステートメントに署名する
<a name="private-content-canned-policy-cookies-signing-policy-statement"></a>

`CloudFront-Signature` ヘッダーの `Set-Cookie` 属性の値を作成するには、「[既定ポリシーを使用する署名付き Cookie のポリシーステートメントを作成するには](#private-content-canned-policy-statement-cookies-procedure)」で作成したポリシーステートメントをハッシュ化して署名します。

ポリシーステートメントのハッシュ化、署名、およびエンコードを行う方法の詳細および例については、以下のトピックを参照してください。
+ [Linux コマンドおよび OpenSSL を使用した Base64 エンコードおよび暗号化](private-content-linux-openssl.md)
+ [署名付き URL の署名を作成するためのコード例](PrivateCFSignatureCodeAndExamples.md)<a name="private-content-canned-policy-cookie-creating-signature-procedure"></a>

**既定ポリシーを使用して署名付き Cookie の署名を作成するには**

1. 「[既定ポリシーを使用する署名付き Cookie のポリシーステートメントを作成するには](#private-content-canned-policy-statement-cookies-procedure)」の手順で作成したポリシーステートメントを、SHA-1 ハッシュ関数と RSA を使用してハッシュ化し、署名します。空白を含まないバージョンのポリシーステートメントを使用します。

   ハッシュ関数に必要なプライベートキーには、対応するパブリックキーがディストリビューション内のアクティブな信頼されたキーグループにあるものを使用してください。
**注記**  
ポリシーステートメントをハッシュ化および署名するための方法は、プログラミング言語およびプラットフォームによって異なります。サンプルコードについては、「[署名付き URL の署名を作成するためのコード例](PrivateCFSignatureCodeAndExamples.md)」を参照してください。

1. ハッシュ化および署名された文字列から、空白 (タブや改行文字を含む) を削除します。

1. MIME base64 エンコーディングを使用して文字列を Base64 エンコードします。詳細については、*RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies* の [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) を参照してください。

1. URL クエリ文字列内の無効な文字を有効な文字で置き換えます。次の表に無効な文字と有効な文字を示します。  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-canned-policy.html)

1. 結果の値を、`Set-Cookie` の名前と値のペアの `CloudFront-Signature` ヘッダーに含めます。次に、「[既定ポリシーを使用して署名付き Cookie を設定するには](#private-content-setting-signed-cookie-canned-policy-procedure)」に戻り、`Set-Cookie` の `CloudFront-Key-Pair-Id` ヘッダーを追加します。

# カスタムポリシーを使用して署名付き Cookie を設定する
<a name="private-content-setting-signed-cookie-custom-policy"></a>

カスタムポリシーを使用する署名付き Cookie を設定するには、以下の手順を実行します。<a name="private-content-setting-signed-cookie-custom-policy-procedure"></a>

**カスタムポリシーを使用して署名付き Cookie を設定するには**

1. .NET または Java を使用して署名付き URL を作成しており、キーペアのプライベートキーをデフォルトの .pem 形式から .NET または Java 対応の形式に変更していない場合は、それを変換します。詳細については、「[プライベートキーの形式を変更する (.NET および Java のみ)](private-content-trusted-signers.md#private-content-reformatting-private-key)」を参照してください。

1. 承認されたビューワーに 3 つの `Set-Cookie` ヘッダーを送信するアプリケーションをプログラムします。各 `Set-Cookie` ヘッダーには名前と値のペアを 1 つだけ含めることができ、CloudFront 署名付き Cookie では 3 つの名前と値のペアが必要であるため、3 つの `Set-Cookie` ヘッダーが必要です。名前と値のペアは、`CloudFront-Policy`、`CloudFront-Signature`、および `CloudFront-Key-Pair-Id` です。アクセスを制御するファイルに対してユーザーが最初のリクエストを行う前に、値がビューワーに存在している必要があります。
**注記**  
一般的に、`Expires` 属性と `Max-Age` 属性を除外することをお勧めします。これにより、ユーザーがブラウザを閉じたときに、ブラウザで Cookie が削除されるため、ユーザーがコンテンツに不正アクセスする可能性が低くなります。詳細については、「[署名付き Cookie の悪用を防止する](private-content-signed-cookies.md#private-content-signed-cookie-misuse)」を参照してください。

   **Cookie の属性の名前では、大文字と小文字が区別されます**。

   改行は、属性を判読しやすくするためにのみ含まれています。

   ```
   Set-Cookie: 
   CloudFront-Policy=base64 encoded version of the policy statement; 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   
   
   Set-Cookie: 
   CloudFront-Signature=hashed and signed version of the policy statement; 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   
   Set-Cookie: 
   CloudFront-Key-Pair-Id=public key ID for the CloudFront public key whose corresponding private key you're using to generate the signature; 
   Domain=optional domain name; 
   Path=/optional directory path; 
   Secure; 
   HttpOnly
   ```  
**(オプション) `Domain`**  
リクエストされたファイルのドメイン名。`Domain` 属性を指定しない場合、デフォルト値は URL のドメイン名で、指定されたドメイン名にのみ適用され、サブドメインには適用されません。`Domain` 属性を指定する場合、サブドメインにも適用されます。ドメイン名の先頭のドット (例えば、`Domain=.example.com`) はオプションです。さらに、`Domain` 属性を指定する場合は、URL のドメイン名と `Domain` 属性の値が一致している必要があります。  
CloudFront がディストリビューションに割り当てたドメイン名 (d111111abcdef8.cloudfront.net など) を指定することはできますが、\$1.cloudfront.net をドメイン名として指定することはできません。  
URL で代替ドメイン名 (example.com など) を使用する場合は、`Domain` 属性を指定するかどうかにかかわらず、代替ドメイン名をディストリビューションに追加する必要があります。詳細については、トピック「[すべてのディストリビューション設定リファレンス](distribution-web-values-specify.md)」の「[代替ドメイン名 (CNAME)](DownloadDistValuesGeneral.md#DownloadDistValuesCNAME)」を参照してください。  
**(オプション) `Path`**  
リクエストされたファイルのパス。`Path` 属性を指定しない場合、デフォルト値は URL のパスです。  
**`Secure`**  
リクエストを送信する前に、ビューワーが Cookie を暗号化することを要求します。Cookie の属性を中間者攻撃から保護するために、HTTPS 接続で `Set-Cookie` ヘッダーを送信することをお勧めします。  
**`HttpOnly`**  
ビューワーが HTTP または HTTPS リクエストでのみ Cookie を送信することを要求します。  
**`CloudFront-Policy`**  
空白が削除されて base64 エンコードされた、JSON 形式のポリシーステートメント。詳細については、「[カスタムポリシーを使用する署名付き Cookie の署名を作成する](#private-content-custom-policy-signature-cookies)」を参照してください。  
ポリシーステートメントは、署名付き Cookie によってユーザーに許可されるアクセスをコントロールします。これには、ユーザーがアクセスできるファイル、有効期限切れ日時、URL が有効になる日時 (オプション)、ファイルへのアクセスが許可されている IP アドレスまたは IP アドレス範囲 (オプション) が含まれます。  
**`CloudFront-Signature`**  
ハッシュ化され、署名された base64 エンコードバージョンの JSON ポリシーステートメント。詳細については、「[カスタムポリシーを使用する署名付き Cookie の署名を作成する](#private-content-custom-policy-signature-cookies)」を参照してください。  
**`CloudFront-Key-Pair-Id`**  
CloudFront パブリックキーの ID (`K2JCJMDEHXQW5F` など)。パブリックキー ID は、署名付き URL の検証に使用するパブリックキーを CloudFront に通知します。CloudFront は、署名内の情報をポリシーステートメント内の情報と比較して、URL が改ざんされていないことを確認します。  
このパブリックキーは、ディストリビューションの信頼された署名者であるキーグループに属している必要があります。詳細については、「[署名付き URL と署名付き Cookie を作成できる署名者を指定する](private-content-trusted-signers.md)」を参照してください。

## カスタムポリシーの `Set-Cookie` ヘッダーの例
<a name="example-set-cookie-headers-custom-policy"></a>

以下の `Set-Cookie` ヘッダーペアの例を参照してください。

代替ドメイン名 (example.org など) を URL で使用する場合は、`Domain` 属性を指定するかどうかにかかわらず、代替ドメイン名をディストリビューションに追加する必要があります。詳細については、「[すべてのディストリビューション設定リファレンス](distribution-web-values-specify.md)」トピックの「[代替ドメイン名 (CNAME)](DownloadDistValuesGeneral.md#DownloadDistValuesCNAME)」を参照してください。

**Example 例 1**  
ディストリビューションに関連するドメイン名をファイルの URL で使用している場合、1 つの署名付き Cookie で `Set-Cookie` ヘッダーを使用できます。  

```
Set-Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__; Domain=d111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=dtKhpJ3aUYxqDIwepczPiDb9NXQ_; Domain=d111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=d111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
```

**Example 例 2**  
代替ドメイン名 (example.org) をファイルの URL で使用している場合、1 つの署名付き Cookie で `Set-Cookie` ヘッダーを使用できます。  

```
Set-Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__; Domain=example.org; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=dtKhpJ3aUYxqDIwepczPiDb9NXQ_; Domain=example.org; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=example.org; Path=/; Secure; HttpOnly
```

**Example 例 3**  
ディストリビューションに関連するドメイン名をファイルの URL で使用している場合、1 つの署名付きリクエストで `Set-Cookie` ヘッダーペアを使用できます。  

```
Set-Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__; Domain=d111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=dtKhpJ3aUYxqDIwepczPiDb9NXQ_; Domain=d111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=dd111111abcdef8.cloudfront.net; Path=/; Secure; HttpOnly
```

**Example 例 4**  
ディストリビューションに関連付けられた代替ドメイン名をファイルの URL で使用している場合、1 つの署名付きリクエストで `Set-Cookie` ヘッダーペアを使用できます。  

```
Set-Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QxMTExMTFhYmNkZWY4LmNsb3VkZnJvbnQubmV0L2dhbWVfZG93bmxvYWQuemlwIiwiQ29uZGl0aW9uIjp7IklwQWRkcmVzcyI6eyJBV1M6U291cmNlSXAiOiIxOTIuMC4yLjAvMjQifSwiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0MjY1MDAwMDB9fX1dfQ__; Domain=example.org; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Signature=dtKhpJ3aUYxqDIwepczPiDb9NXQ_; Domain=example.org; Path=/; Secure; HttpOnly
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F; Domain=example.org; Path=/; Secure; HttpOnly
```

## 既定ポリシーを使用する署名付き Cookie のポリシーステートメントを作成する
<a name="private-content-custom-policy-statement-cookies"></a>

カスタムポリシーのポリシーステートメントを作成するには、以下の手順を実行します。さまざまな方法でファイルへのアクセスを制御するポリシーステートメントのいくつかの例については、「[カスタムポリシーを使用する署名付き Cookie のポリシーステートメントの例](#private-content-custom-policy-statement-signed-cookies-examples)」を参照してください。<a name="private-content-custom-policy-statement-cookies-procedure"></a>

**カスタムポリシーを使用する署名付き Cookie のポリシーステートメントを作成するには**

1. 以下の JSON 形式を使用してポリシーステートメントを構築します。

   ```
   {
       "Statement": [
           {
               "Resource": "URL of the file",
               "Condition": {
                   "DateLessThan": {
                       "AWS:EpochTime":required ending date and time in Unix time format and UTC
                   },
                   "DateGreaterThan": {
                       "AWS:EpochTime":optional beginning date and time in Unix time format and UTC
                   },
                   "IpAddress": {
                       "AWS:SourceIp": "optional IP address"
                   }
               }
           }
       ]
   }
   ```

   次の点に注意してください。
   + 1 つのステートメントのみを含めることができます。
   + UTF-8 文字エンコードを使用します。
   + すべての句読点およびパラメータ名を、指定されたとおりに正確に含めます。パラメータ名の省略形は受け付けられません。
   + `Condition` セクションのパラメータの順序は問題ではありません。
   + `Resource`、`DateLessThan`、`DateGreaterThan`、および `IpAddress` の値については、「[署名付き Cookie のカスタムポリシーのポリシーステートメントで指定する値](#private-content-custom-policy-statement-cookies-values)」を参照してください。

1. ポリシーステートメントからすべての空白 (タブと改行文字を含む) を削除します。アプリケーションコード内の文字列にエスケープ文字を含めることが必要になる場合があります。

1. MIME base64 エンコーディングを使用してポリシーステートメントを Base64 エンコードします。詳細については、*RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies* の [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) を参照してください。

1. URL クエリ文字列内の無効な文字を有効な文字で置き換えます。次の表に無効な文字と有効な文字を示します。  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-custom-policy.html)

1. 結果の値を、`Set-Cookie` ヘッダーの `CloudFront-Policy=` の後に含めます。

1. ポリシーステートメントのハッシュ化、署名、および base64 エンコードを行って、`Set-Cookie` 用に `CloudFront-Signature` ヘッダーの署名を作成します。詳細については、「[カスタムポリシーを使用する署名付き Cookie の署名を作成する](#private-content-custom-policy-signature-cookies)」を参照してください。

### 署名付き Cookie のカスタムポリシーのポリシーステートメントで指定する値
<a name="private-content-custom-policy-statement-cookies-values"></a>

カスタムポリシーのポリシーステートメントを作成する場合、以下の値を指定します。

**リソース**  
クエリ文字列 (存在する場合) を含むベース URL。  
`https://d111111abcdef8.cloudfront.net/images/horizon.jpg?size=large&license=yes`  
`Resource` パラメータを省略した場合、ユーザーは、署名付き URL の作成に使用するキーペアに関連付けられたあらゆるディストリビューションに関連付けられるすべてのファイルにアクセスできます。
`Resource` の日付形式は 1 つだけ指定できます。  
次の点に注意してください。  
+ **プロトコル** – 値は `http://` または `https://` で始まっている必要があります。
+ **クエリ文字列パラメータ** – クエリ文字列パラメータがない場合は、疑問符を省略します。
+ **ワイルドカード** – 0 個以上の文字に一致するワイルドカード文字 (\$1)、または 1 つの文字に一致するワイルドカード文字 (?) を使用できます。文字列のどこにでも含めることができます。次に例を示します。この値は、

  `https://d111111abcdef8.cloudfront.net/*game_download.zip*`

  たとえば、次のファイルを含みます。
  + `https://d111111abcdef8.cloudfront.net/game_download.zip`
  + `https://d111111abcdef8.cloudfront.net/example_game_download.zip?license=yes`
  + `https://d111111abcdef8.cloudfront.net/test_game_download.zip?license=temp`
+ **代替ドメイン名** – URL で代替ドメイン名 (CNAME) を指定する場合は、ウェブページまたはアプリケーション内のファイルを参照するときに代替ドメイン名を指定する必要があります。ファイルの Amazon S3 URL を指定しないでください。

**DateLessThan**  
URL の有効期限切れ日時。Unix 時間形式 (秒単位) および協定世界時 (UTC) で指定します。値を引用符で囲まないでください。  
たとえば、UTC の 2015 年 3 月 16 日午前 10 時 00 分は、UNIX 時間形式の 1426500000 に変換されます。  
詳細については、「[CloudFront が署名付き Cookie の有効期限切れ日時を確認するタイミング](private-content-signed-cookies.md#private-content-check-expiration-cookie)」を参照してください。

**DateGreaterThan (オプション)**  
オプションの URL 開始日時。Unix 時間形式 (秒単位) および協定世界時 (UTC) で指定します。ユーザーは、指定された日時が過ぎるまでファイルにアクセスできません。値を引用符で囲まないでください。

**IpAddress (オプション)**  
GET リクエストを実行するクライアントの IP アドレス。次の点に注意してください。  
+ ファイルへのアクセスをすべての IP アドレスに許可するには、`IpAddress` パラメータを省略します。
+ IP アドレスまたは IP アドレス範囲を 1 つ指定できます。たとえば、2 つの別々の範囲のどちらかにクライアントの IP アドレスが入っている場合にアクセスを許可するようなポリシーを設定することはできません。
+ 1 つの IP アドレスからのアクセスを許可するには、以下のように指定します。

  `"`*IPv4 IP アドレス*`/32"`
+ IP アドレス範囲は標準の IPv4 CIDR 形式 (`192.0.2.0/24` など) で指定する必要があります。詳細については、*RFC 4632, Classless Inter-domain Routing (CIDR): The Internet Address Assignment and Aggregation Plan* ([https://tools.ietf.org/html/rfc4632](https://tools.ietf.org/html/rfc4632)) を参照してください。
**重要**  
IPv6 形式の IP アドレス (例: 2001:0db8:85a3::8a2e:0370:7334) はサポートされていません。

  `IpAddress` を含むカスタムポリシーを使用する場合、ディストリビューションで IPv6 は有効にしません。一部のコンテンツへのアクセスを IP アドレスによって制限し、他のコンテンツで IPv6 リクエストをサポートする場合、2 つのディストリビューションを作成します。詳細については、トピック「[すべてのディストリビューション設定リファレンス](distribution-web-values-specify.md)」の「[IPv6 を有効にする (ビューワーリクエスト)](DownloadDistValuesGeneral.md#DownloadDistValuesEnableIPv6)」を参照してください。

## カスタムポリシーを使用する署名付き Cookie のポリシーステートメントの例
<a name="private-content-custom-policy-statement-signed-cookies-examples"></a>

以下のポリシーステートメントの例は、特定のファイル、ディレクトリ内のすべてのファイル、またはキーペア ID に関連付けられたすべてのファイルへのアクセスを制御する方法を示しています。また、この例は、個々の IP アドレスまたは IP アドレス範囲からのアクセスを制御する方法、および指定された日時以降にユーザーが署名付き Cookie を使用することを禁止する方法も示しています。

これらの例のいずれかをコピーして貼り付ける場合は、すべての空白 (タブと改行文字を含む) を削除し、値を独自の値で置き換え、右の中かっこ ( \$1 ) の後に改行文字を含めます。

詳細については、「[署名付き Cookie のカスタムポリシーのポリシーステートメントで指定する値](#private-content-custom-policy-statement-cookies-values)」を参照してください。

**Topics**
+ [

### ポリシーステートメントの例: IP アドレス範囲から 1 つのファイルにアクセスする
](#private-content-custom-policy-statement-signed-cookies-example-one-object)
+ [

### ポリシーステートメントの例: IP アドレス範囲からディレクトリ内のすべてのファイルにアクセスする
](#private-content-custom-policy-statement-signed-cookies-example-all-objects)
+ [

### ポリシーステートメントの例: キーペア ID に関連付けられたすべてのファイルに 1 つの IP アドレスからアクセスする
](#private-content-custom-policy-statement-signed-cookies-example-one-ip)

### ポリシーステートメントの例: IP アドレス範囲から 1 つのファイルにアクセスする
<a name="private-content-custom-policy-statement-signed-cookies-example-one-object"></a>

次の署名付き Cookie 内のカスタムポリシーの例では、UTC の 2023 年 1 月 1 日午前 10 時 00 分まで、範囲 `192.0.2.0/24` の IP アドレスから、ユーザーがファイル `https://d111111abcdef8.cloudfront.net/game_download.zip` にアクセスできることを指定しています。

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/game_download.zip",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.0/24"
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1767290400
                }
            }
        }
    ]
}
```

### ポリシーステートメントの例: IP アドレス範囲からディレクトリ内のすべてのファイルにアクセスする
<a name="private-content-custom-policy-statement-signed-cookies-example-all-objects"></a>

以下のカスタムポリシーの例では、`training` パラメータの \$1 ワイルドカード文字が示すとおり、`Resource` ディレクトリ内のあらゆるファイルを対象とする署名付き Cookie を作成できます。UTC の 2013 年 1 月 1 日午前 10 時 00 分まで、範囲 `192.0.2.0/24` の IP アドレスから、ユーザーはファイルにアクセスできます。

```
{
    "Statement": [
        {
            "Resource": "https://d111111abcdef8.cloudfront.net/training/*",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.0/24"
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1767290400
                }
            }
        }
    ]
}
```

このポリシーを使用する各署名付き Cookie には、たとえば次のように、特定のファイルを識別するベース URL が含まれます。

`https://d111111abcdef8.cloudfront.net/training/orientation.pdf`

### ポリシーステートメントの例: キーペア ID に関連付けられたすべてのファイルに 1 つの IP アドレスからアクセスする
<a name="private-content-custom-policy-statement-signed-cookies-example-one-ip"></a>

以下のカスタムポリシーの例では、`Resource` パラメータの \$1 ワイルドカード文字が示すとおり、あらゆるディストリビューションに関連付けられたあらゆるファイルを対象とする署名付き Cookie を設定できます。ユーザーは IP アドレス `192.0.2.10/32` を使用する必要があります。(CIDR 表記の値 `192.0.2.10/32` は 1 つの IP アドレス `192.0.2.10` を参照します)。ファイルは、UTC の 2013 年 1 月 1 日午前 10 時 00 分から UTC の 2013 年 1 月 2 日午前 10 時 00 分まで使用できます。

```
{
    "Statement": [
        {
            "Resource": "https://*",
            "Condition": {
                "IpAddress": {
                    "AWS:SourceIp": "192.0.2.10/32"
                },
                "DateGreaterThan": {
                    "AWS:EpochTime": 1767290400
                },
                "DateLessThan": {
                    "AWS:EpochTime": 1767376800
                }
            }
        }
    ]
}
```

このポリシーを含める各署名付き Cookie には、たとえば次のように、特定の CloudFront ディストリビューション内の特定のファイルを識別するベース URL が含まれます。

`https://d111111abcdef8.cloudfront.net/training/orientation.pdf`

署名付き Cookie にはキーペア ID も含まれます。キーペア ID は、ベース URL に指定されたディストリビューション (d111111abcdef8.cloudfront.net) 内の信頼されたキーグループに関連付けられる必要があります。

## カスタムポリシーを使用する署名付き Cookie の署名を作成する
<a name="private-content-custom-policy-signature-cookies"></a>

カスタムポリシーを使用する署名付き Cookie の署名は、ハッシュ化、署名、および base64 エンコードが行われたバージョンのポリシーステートメントです。

ポリシーステートメントのハッシュ化、署名、およびエンコードを行う方法の詳細および例については、以下の各資料を参照してください。
+ [Linux コマンドおよび OpenSSL を使用した Base64 エンコードおよび暗号化](private-content-linux-openssl.md)
+ [署名付き URL の署名を作成するためのコード例](PrivateCFSignatureCodeAndExamples.md)<a name="private-content-custom-policy-signature-cookies-procedure"></a>

**カスタムポリシーを使用して署名付き Cookie の署名を作成するには**

1. 「[カスタムポリシーを使用する署名付き URL のポリシーステートメントを作成するには](private-content-creating-signed-url-custom-policy.md#private-content-custom-policy-creating-policy-procedure)」の手順で作成した JSON ポリシーステートメントを、SHA-1 ハッシュ関数と RSA を使用してハッシュ化し、署名します。空白は含まれていないが、まだ base64 エンコードされていないバージョンのポリシーステートメントを使用します。

   ハッシュ関数に必要なプライベートキーには、対応するパブリックキーがディストリビューション内のアクティブな信頼されたキーグループにあるものを使用してください。
**注記**  
ポリシーステートメントをハッシュ化および署名するための方法は、プログラミング言語およびプラットフォームによって異なります。サンプルコードについては、「[署名付き URL の署名を作成するためのコード例](PrivateCFSignatureCodeAndExamples.md)」を参照してください。

1. ハッシュ化および署名された文字列から、空白 (タブや改行文字を含む) を削除します。

1. MIME base64 エンコーディングを使用して文字列を Base64 エンコードします。詳細については、*RFC 2045, MIME (Multipurpose Internet Mail Extensions) Part One: Format of Internet Message Bodies* の [Section 6.8, Base64 Content-Transfer-Encoding](https://tools.ietf.org/html/rfc2045#section-6.8) を参照してください。

1. URL クエリ文字列内の無効な文字を有効な文字で置き換えます。次の表に無効な文字と有効な文字を示します。  
****    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-custom-policy.html)

1. 結果の値を、`Set-Cookie` の名前と値のペアの `CloudFront-Signature=` ヘッダーに含めて、「[カスタムポリシーを使用して署名付き Cookie を設定するには](#private-content-setting-signed-cookie-custom-policy-procedure)」に戻り、`Set-Cookie` の `CloudFront-Key-Pair-Id` ヘッダーを追加します。

# PHP を使用して署名付き cookie を作成する
<a name="signed-cookies-PHP"></a>

次のコード例は、動画へのリンクを作成するという点で [PHP を使用して URL 署名を作成する](CreateURL_PHP.md) の例に似ています。ただし、コード内の URL に署名する代わりに、この例では `create_signed_cookies()` 関数を使用して cookie に署名します。クライアント側のプレイヤーは、cookie を使用して CloudFront ディストリビューションへの各リクエストを認証します。

このアプローチは、HTTP ライブストリーミング (HLS) や HTTP 経由の動的アダプティブストリーミング (DASH) などのコンテンツをストリーミングする場合に便利です。この場合、クライアントはマニフェスト、セグメント、および関連する再生アセットを取得するために複数のリクエストを行う必要があります。署名付き cookie を使用することで、クライアントはセグメントごとに新しい署名付き URL を生成することなく、各リクエストを認証できます。

**注記**  
URL 署名の作成は、署名付き cookie を使用してプライベートコンテンツを提供するプロセスの一環にすぎません。詳細については、「[署名付き Cookie を使用する](private-content-signed-cookies.md)」を参照してください。



**Topics**
+ [

## RSA SHA-1 署名を作成する
](#create-rsa-sha-1signature-cookies)
+ [

## 署名付き cookie を作成する
](#create-the-signed-cookie)
+ [

## 完全なコード
](#full-code-signed-cookies)

以下のセクションでは、コード例を個別のパートに分解します。完全な[コードサンプル](#full-code-signed-cookies)は以下にあります。

## RSA SHA-1 署名を作成する
<a name="create-rsa-sha-1signature-cookies"></a>

このコード例では、次の操作を行います。

1. 関数 `rsa_sha1_sign` は、ポリシーステートメントをハッシュ化して署名します。必要な引数は、ポリシーステートメントと、ディストリビューションの信頼されたキーグループにあるパブリックキーに対応するプライベートキーです。

1. 次に、`url_safe_base64_encode` 関数で、URL で使用可能なバージョンの署名を作成します。

   ```
   function rsa_sha1_sign($policy, $private_key_filename) {
       $signature = "";
       $fp = fopen($private_key_filename, "r");
       $priv_key = fread($fp, 8192);
       fclose($fp);
       $pkeyid = openssl_get_privatekey($priv_key);
       openssl_sign($policy, $signature, $pkeyid);
       openssl_free_key($pkeyid);
       return $signature;
   }
   
   function url_safe_base64_encode($value) {
       $encoded = base64_encode($value);
       return str_replace(
           array('+', '=', '/'),
           array('-', '_', '~'),
           $encoded);
   }
   ```

## 署名付き cookie を作成する
<a name="create-the-signed-cookie"></a>

次のコードコンストラクトは、cookie 属性として `CloudFront-Expires`、`CloudFront-Signature`、`CloudFront-Key-Pair-Id` を使用して署名付き cookie を作成します。このコードでは、カスタムポリシーを使用します。

```
function create_signed_cookies($resource, $private_key_filename, $key_pair_id, $expires, $client_ip = null) {
    $policy = array(
        'Statement' => array(
            array(
                'Resource' => $resource,
                'Condition' => array(
                    'DateLessThan' => array('AWS:EpochTime' => $expires)
                )
            )
        )
    );

    if ($client_ip) {
        $policy['Statement'][0]['Condition']['IpAddress'] = array('AWS:SourceIp' => $client_ip . '/32');
    }

    $policy = json_encode($policy);
    $encoded_policy = url_safe_base64_encode($policy);
    $signature = rsa_sha1_sign($policy, $private_key_filename);
    $encoded_signature = url_safe_base64_encode($signature);

    return array(
        'CloudFront-Policy' => $encoded_policy,
        'CloudFront-Signature' => $encoded_signature,
        'CloudFront-Key-Pair-Id' => $key_pair_id
    );
}
```

詳細については、「[カスタムポリシーを使用して署名付き Cookie を設定する](private-content-setting-signed-cookie-custom-policy.md)」を参照してください。

## 完全なコード
<a name="full-code-signed-cookies"></a>

次のコードサンプルでは、PHP で CloudFront 署名付き cookie を作成する詳細な方法を示します。完全な例については、[demo-php.zip](samples/demo-php.zip) ファイルからダウンロードできます。

次の例では、`$policy Condition` エレメントを変更して、IPv4 アドレス範囲と IPv6 アドレス範囲の両方を許可できます。例については、「Amazon Simple Storage Service ユーザーガイド」の「[IAM ポリシーでの IPv6 アドレスの使用](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ipv6-access.html#ipv6-access-iam)」を参照してください。**

```
<?php

function rsa_sha1_sign($policy, $private_key_filename) {
    $signature = "";
    $fp = fopen($private_key_filename, "r");
    $priv_key = fread($fp, 8192);
    fclose($fp);
    $pkeyid = openssl_get_privatekey($priv_key);
    openssl_sign($policy, $signature, $pkeyid);
    openssl_free_key($pkeyid);
    return $signature;
}

function url_safe_base64_encode($value) {
    $encoded = base64_encode($value);
    return str_replace(
        array('+', '=', '/'),
        array('-', '_', '~'),
        $encoded);
}

function create_signed_cookies($resource, $private_key_filename, $key_pair_id, $expires, $client_ip = null) {
    $policy = array(
        'Statement' => array(
            array(
                'Resource' => $resource,
                'Condition' => array(
                    'DateLessThan' => array('AWS:EpochTime' => $expires)
                )
            )
        )
    );

    if ($client_ip) {
        $policy['Statement'][0]['Condition']['IpAddress'] = array('AWS:SourceIp' => $client_ip . '/32');
    }

    $policy = json_encode($policy);
    $encoded_policy = url_safe_base64_encode($policy);
    $signature = rsa_sha1_sign($policy, $private_key_filename);
    $encoded_signature = url_safe_base64_encode($signature);

    return array(
        'CloudFront-Policy' => $encoded_policy,
        'CloudFront-Signature' => $encoded_signature,
        'CloudFront-Key-Pair-Id' => $key_pair_id
    );
}



$private_key_filename = '/home/test/secure/example-priv-key.pem';
$key_pair_id = 'K2JCJMDEHXQW5F';
$base_url = 'https://d1234.cloudfront.net';

$expires = time() + 3600; // 1 hour from now

// Get the viewer real IP from the x-forward-for header as $_SERVER['REMOTE_ADDR'] will return viewer facing IP. An alternative option is to use CloudFront-Viewer-Address header. Note that this header is a trusted CloudFront immutable header. Example format: IP:PORT ("CloudFront-Viewer-Address": "1.2.3.4:12345")
$client_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];


// For HLS manifest and segments (using wildcard)
$hls_resource = $base_url . '/sign/*';
$signed_cookies = create_signed_cookies($hls_resource, $private_key_filename, $key_pair_id, $expires, $client_ip);

// Set the cookies
$cookie_domain = parse_url($base_url, PHP_URL_HOST);
foreach ($signed_cookies as $name => $value) {
    setcookie($name, $value, $expires, '/', $cookie_domain, true, true);
}

?>

<!DOCTYPE html>
<html>
<head>
    <title>CloudFront Signed HLS Stream with Cookies</title>
</head>
<body>
    <h1>Amazon CloudFront Signed HLS Stream with Cookies</h1>
    <h2>Expires at <?php echo gmdate('Y-m-d H:i:s T', $expires); ?> only viewable by IP <?php echo $client_ip; ?></h2>
    
    <div id='hls-video'>
        <video id="video" width="640" height="360" controls></video>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
    <script>
        var video = document.getElementById('video');
        var manifestUrl = '<?php echo $base_url; ?>/sign/manifest.m3u8';
        
        if (Hls.isSupported()) {
            var hls = new Hls();
            hls.loadSource(manifestUrl);
            hls.attachMedia(video);
        }
        else if (video.canPlayType('application/vnd.apple.mpegurl')) {
            video.src = manifestUrl;
        }
    </script>
</body>
</html>
```

署名付き cookie を使用する代わりに、署名付き URL を使用できます。詳細については、「[PHP を使用して URL 署名を作成する](CreateURL_PHP.md)」を参照してください。

# Linux コマンドおよび OpenSSL を使用した Base64 エンコードおよび暗号化
<a name="private-content-linux-openssl"></a>

次の Linux コマンドラインのコマンドおよび OpenSSL を使用して、ポリシーステートメントをハッシュ化して署名します。次に、署名を base64 エンコードし、URL クエリ文字列パラメータでの無効な文字を有効な文字置き換えます。

OpenSSL の詳細については、「」にアクセスしてください[https://www.openssl.org](https://www.openssl.org)

```
cat policy | tr -d "\n" | tr -d " \t\n\r" | openssl sha1 -sign private_key.pem | openssl base64 -A | tr -- '+=/' '-_~'
```

上記のコマンドでは:
+ `cat` が `policy` ファイルを読み取ります。
+ `tr -d "\n" | tr -d " \t\n\r"` は、`cat` によって追加された空白や改行文字を削除します。
+ OpenSSL は、SHA-1 を使用してファイルをハッシュし、プライベートキーファイル `private_key.pem` を使用して署名します。プライベートキー署名は、RSA 2048 または ECDSA 256 のいずれかです。
+ OpenSSL は、ハッシュされ、署名されたポリシーステートメントを base64 でエンコードします。
+ `tr` は、URL クエリ文字列パラメータの無効な文字を有効な文字で置き換えます。

署名の作成方法を示すコード例については、「[署名付き URL の署名を作成するためのコード例](PrivateCFSignatureCodeAndExamples.md)」を参照してください。

# 署名付き URL の署名を作成するためのコード例
<a name="PrivateCFSignatureCodeAndExamples"></a>

このセクションには、署名付き URL の署名の作成方法を示す、ダウンロード可能なアプリケーションの例が含まれます。例は、Perl、PHP、C\$1、および Java で使用できます。任意の例を使用して、署名付き URL を作成できます。Perl スクリプトは Linux および macOS プラットフォームで実行されます。PHP の例は、PHP が実行されているあらゆるサーバーで動作します。C\$1 の例では、.NET Framework が使用されます。

JavaScript (Node.js) のコードサンプルについては、AWS デベロッパーブログの「[Creating Amazon CloudFront Signed URLs in Node.js](https://aws.amazon.com/blogs/developer/creating-amazon-cloudfront-signed-urls-in-node-js/)」を参照してください。

Python のコードサンプルについては、「AWS SDK for Python (Boto3) API リファレンス」の「[Generate a signed URL for Amazon CloudFront](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudfront.html#examples)」と、Boto3 GitHub リポジトリにある「[こちらのサンプルコード](https://github.com/boto/boto3/blob/develop/boto3/examples/cloudfront.rst)」を参照してください。

**Topics**
+ [

# Perl を使用して URL 署名を作成する
](CreateURLPerl.md)
+ [

# PHP を使用して URL 署名を作成する
](CreateURL_PHP.md)
+ [

# C\$1 と .NET Framework を使用して URL 署名を作成する
](CreateSignatureInCSharp.md)
+ [

# Java を使用して URL 署名を作成する
](CFPrivateDistJavaDevelopment.md)

# Perl を使用して URL 署名を作成する
<a name="CreateURLPerl"></a>

このセクションには、プライベートコンテンツの署名を作成するために使用できる Linux/Mac プラットフォームの Perl スクリプトが含まれます。署名を作成するには、コマンドライン引数に CloudFront URL、署名者のプライベートキーへのパス、キー ID、および URL の有効期限切れ日付を指定して、スクリプトを実行します。このツールでは、署名付き URL のデコードを行うこともできます。

**注記**  
URL 署名の作成は、署名付き URL を使用してプライベートコンテンツを供給するためのプロセスの 1 パートにすぎません。エンドツーエンドの処理の詳細については、「[署名付き URL を使用する](private-content-signed-urls.md)」を参照してください。

**Topics**
+ [

## 署名付き URL を作成する Perl スクリプトのソース
](#CreateURLPerlScriptSource)

## 署名付き URL を作成する Perl スクリプトのソース
<a name="CreateURLPerlScriptSource"></a>

次の Perl ソースコードを使用して、CloudFront の署名付き URL を作成できます。コード内のコメントに、コマンドラインスイッチおよびこのツールの各種機能の情報が含まれています。

```
#!/usr/bin/perl -w

# Copyright 2008 Amazon Technologies, Inc.  Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. You may obtain a copy of the License at:
#
# https://aws.amazon.com/apache2.0
#
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and limitations under the License.

=head1 cfsign.pl

cfsign.pl - A tool to generate and verify Amazon CloudFront signed URLs

=head1 SYNOPSIS

This script uses an existing RSA key pair to sign and verify Amazon CloudFront signed URLs

View the script source for details as to which CPAN packages are required beforehand. 

For help, try:

cfsign.pl --help

URL signing examples:

cfsign.pl --action encode --url https://images.my-website.com/gallery1.zip --policy sample_policy.json --private-key privkey.pem --key-pair-id mykey

cfsign.pl --action encode --url https://images.my-website.com/gallery1.zip --expires 1257439868 --private-key privkey.pem --key-pair-id mykey

URL decode example:

cfsign.pl --action decode --url "http//mydist.cloudfront.net/?Signature=AGO-PgxkYo99MkJFHvjfGXjG1QDEXeaDb4Qtzmy85wqyJjK7eKojQWa4BCRcow__&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovLypicmFkbS5qcGciLCJDb25kaXRpb24iOnsiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjEwLjUyLjE3LjkvMCJ9LCJEYXRlR3JlYXRlclRoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI1MjUyMDgzMH19fV19Cg__&Key-Pair-Id=mykey"


To generate an RSA key pair, you can use openssl and the following commands:

# Generate a 2048 bit key pair
openssl genrsa -out private-key.pem 2048
openssl rsa -in private-key.pem -pubout -out public-key.pem


=head1 OPTIONS

=over 8

=item B<--help>

Print a help message and exits.

=item B<--action> [action]

The action to execute.  action can be one of:

  encode - Generate a signed URL (using a canned policy or a user policy)
  decode - Decode a signed URL

=item B<--url>

The URL to en/decode

=item B<--stream>

The stream to en/decode

=item B<--private-key>

The path to your private key.

=item B<--key-pair-id>

The key pair identifier.

=item B<--policy>

The CloudFront policy document.

=item B<--expires>

The Unix epoch time when the URL is to expire. If both this option and
the --policy option are specified, --policy will be used. Otherwise, this 
option alone will use a canned policy.

=back

=cut

use strict;
use warnings;

# you might need to use CPAN to get these modules.
# run perl -MCPAN -e "install <module>" to get them.
# The openssl command line will also need to be in your $PATH.
use File::Temp qw/tempfile/;
use File::Slurp;
use Getopt::Long;
use IPC::Open2;
use MIME::Base64 qw(encode_base64 decode_base64);
use Pod::Usage;
use URI;

my $CANNED_POLICY 
    = '{"Statement":[{"Resource":"<RESOURCE>","Condition":{"DateLessThan":{"AWS:EpochTime":<EXPIRES>}}}]}';

my $POLICY_PARAM      = "Policy";
my $EXPIRES_PARAM     = "Expires";
my $SIGNATURE_PARAM   = "Signature";
my $KEY_PAIR_ID_PARAM = "Key-Pair-Id";

my $verbose = 0;
my $policy_filename = "";
my $expires_epoch = 0;
my $action = "";
my $help = 0;
my $key_pair_id = "";
my $url = "";
my $stream = "";
my $private_key_filename = "";

my $result = GetOptions("action=s"      => \$action,
                        "policy=s"      => \$policy_filename,
                        "expires=i"     => \$expires_epoch,
                        "private-key=s" => \$private_key_filename,
                        "key-pair-id=s" => \$key_pair_id,
                        "verbose"       => \$verbose,
                        "help"          => \$help,
                        "url=s"         => \$url,
                        "stream=s"      => \$stream,
                    );

if ($help or !$result) {
    pod2usage(1);
    exit;
}

if ($url eq "" and $stream eq "") {
    print STDERR "Must include a stream or a URL to encode or decode with the --stream or --url option\n";
    exit;
}

if ($url ne "" and $stream ne "") {
    print STDERR "Only one of --url and --stream may be specified\n";
    exit;
}

if ($url ne "" and !is_url_valid($url)) {
    exit;
}

if ($stream ne "") {
    exit unless is_stream_valid($stream);

    # The signing mechanism is identical, so from here on just pretend we're
    # dealing with a URL
    $url = $stream;
} 

if ($action eq "encode") {
    # The encode action will generate a private content URL given a base URL, 
    # a policy file (or an expires timestamp) and a key pair id parameter
    my $private_key;
    my $public_key;
    my $public_key_file;
    
    my $policy;
    if ($policy_filename eq "") {
        if ($expires_epoch == 0) {
            print STDERR "Must include policy filename with --policy argument or an expires" . 
                          "time using --expires\n";            
        }
        
        $policy = $CANNED_POLICY;
        $policy =~ s/<EXPIRES>/$expires_epoch/g;
        $policy =~ s/<RESOURCE>/$url/g;
    } else {
        if (! -e $policy_filename) {
            print STDERR "Policy file $policy_filename does not exist\n";
            exit;
        }
        $expires_epoch = 0; # ignore if set
        $policy = read_file($policy_filename);
    }

    if ($private_key_filename eq "") {
        print STDERR "You must specific the path to your private key file with --private-key\n";
        exit;
    }

    if (! -e $private_key_filename) {
        print STDERR "Private key file $private_key_filename does not exist\n";
        exit;
    }

    if ($key_pair_id eq "") {
        print STDERR "You must specify a key pair id with --key-pair-id\n";
        exit;
    }

    my $encoded_policy = url_safe_base64_encode($policy);
    my $signature = rsa_sha1_sign($policy, $private_key_filename);
    my $encoded_signature = url_safe_base64_encode($signature);

    my $generated_url = create_url($url, $encoded_policy, $encoded_signature, $key_pair_id, $expires_epoch);


    if ($stream ne "") {
        print "Encoded stream (for use within a swf):\n" . $generated_url . "\n";
        print "Encoded and escaped stream (for use on a webpage):\n" .  escape_url_for_webpage($generated_url) . "\n"; 
    } else {
        print "Encoded URL:\n" . $generated_url . "\n";
    }
} elsif ($action eq "decode") {
    my $decoded = decode_url($url);
    if (!$decoded) {
        print STDERR "Improperly formed URL\n";
        exit;
    }

    print_decoded_url($decoded);
} else {
    # No action specified, print help.  But only if this is run as a program (caller will be empty)
    pod2usage(1) unless caller();
}

# Decode a private content URL into its component parts
sub decode_url {
    my $url = shift;

    if ($url =~ /(.*)\?(.*)/) {
        my $base_url = $1;
        my $params = $2;

        my @unparsed_params = split(/&/, $params);
        my %params = ();
        foreach my $param (@unparsed_params) {
            my ($key, $val) = split(/=/, $param);
            $params{$key} = $val;
        }

        my $encoded_signature = "";
        if (exists $params{$SIGNATURE_PARAM}) {
            $encoded_signature = $params{"Signature"};
        } else {
            print STDERR "Missing Signature URL parameter\n";
            return 0;
        }

        my $encoded_policy = "";
        if (exists $params{$POLICY_PARAM}) {
            $encoded_policy = $params{$POLICY_PARAM};
        } else {
            if (!exists $params{$EXPIRES_PARAM}) {
                print STDERR "Either the Policy or Expires URL parameter needs to be specified\n";
                return 0;    
            }
            
            my $expires = $params{$EXPIRES_PARAM};
            
            my $policy = $CANNED_POLICY;
            $policy =~ s/<EXPIRES>/$expires/g;
            
            my $url_without_cf_params = $url;
            $url_without_cf_params =~ s/$SIGNATURE_PARAM=[^&]*&?//g;
            $url_without_cf_params =~ s/$POLICY_PARAM=[^&]*&?//g;
            $url_without_cf_params =~ s/$EXPIRES_PARAM=[^&]*&?//g;
            $url_without_cf_params =~ s/$KEY_PAIR_ID_PARAM=[^&]*&?//g;
            
            if ($url_without_cf_params =~ /(.*)\?$/) {
                $url_without_cf_params = $1;
            }
            
            $policy =~ s/<RESOURCE>/$url_without_cf_params/g;
            
            $encoded_policy = url_safe_base64_encode($policy);
        }

        my $key = "";
        if (exists $params{$KEY_PAIR_ID_PARAM}) {
            $key = $params{$KEY_PAIR_ID_PARAM};
        } else {
            print STDERR "Missing $KEY_PAIR_ID_PARAM parameter\n";
            return 0;
        }

        my $policy = url_safe_base64_decode($encoded_policy);

        my %ret = ();
        $ret{"base_url"} = $base_url;
        $ret{"policy"} = $policy;
        $ret{"key"} = $key;

        return \%ret;
    } else {
        return 0;
    }
}

# Print a decoded URL out
sub print_decoded_url {
    my $decoded = shift;

    print "Base URL: \n" . $decoded->{"base_url"} . "\n";
    print "Policy: \n" . $decoded->{"policy"} . "\n";
    print "Key: \n" . $decoded->{"key"} . "\n";
}

# Encode a string with base 64 encoding and replace some invalid URL characters
sub url_safe_base64_encode {
    my ($value) = @_;

    my $result = encode_base64($value);
    $result =~ tr|+=/|-_~|;

    return $result;
}

# Decode a string with base 64 encoding.  URL-decode the string first
# followed by reversing any special character ("+=/") translation.
sub url_safe_base64_decode {
    my ($value) = @_;

    $value =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
    $value =~ tr|-_~|+=/|;

    my $result = decode_base64($value);

    return $result;
}

# Create a private content URL
sub create_url {
    my ($path, $policy, $signature, $key_pair_id, $expires) = @_;
    
    my $result;
    my $separator = $path =~ /\?/ ? '&' : '?';
    if ($expires) {
        $result = "$path$separator$EXPIRES_PARAM=$expires&$SIGNATURE_PARAM=$signature&$KEY_PAIR_ID_PARAM=$key_pair_id";
    } else {
        $result = "$path$separator$POLICY_PARAM=$policy&$SIGNATURE_PARAM=$signature&$KEY_PAIR_ID_PARAM=$key_pair_id";
    }
    $result =~ s/\n//g;

    return $result;
}

# Sign a document with given private key file.
# The first argument is the document to sign
# The second argument is the name of the private key file
sub rsa_sha1_sign {
    my ($to_sign, $pvkFile) = @_;
    print "openssl sha1 -sign $pvkFile $to_sign\n";

    return write_to_program($pvkFile, $to_sign);
}

# Helper function to write data to a program
sub write_to_program {
my ($keyfile, $data) = @_;
unlink "temp_policy.dat" if (-e "temp_policy.dat");
unlink "temp_sign.dat" if (-e "temp_sign.dat");

write_file("temp_policy.dat", $data);

system("openssl dgst -sha1 -sign \"$keyfile\" -out temp_sign.dat temp_policy.dat");

my $output = read_file("temp_sign.dat");

    return $output;
}

# Read a file into a string and return the string
sub read_file {
    my ($file) = @_;

    open(INFILE, "<$file") or die("Failed to open $file: $!");
    my $str = join('', <INFILE>);
    close INFILE;

    return $str;
}

sub is_url_valid {
    my ($url) = @_;

    # HTTP distributions start with http[s]:// and are the correct thing to sign
    if ($url =~ /^https?:\/\//) {
        return 1;
    } else {
        print STDERR "CloudFront requires absolute URLs for HTTP distributions\n";
        return 0;
    }
}

sub is_stream_valid {
    my ($stream) = @_;

    if ($stream =~ /^rtmp:\/\// or $stream =~ /^\/?cfx\/st/) {
        print STDERR "Streaming distributions require that only the stream name is signed.\n";
        print STDERR "The stream name is everything after, but not including, cfx/st/\n";
        return 0;
    } else {
        return 1;
    }
}

# flash requires that the query parameters in the stream name are url
# encoded when passed in through javascript, etc.  This sub handles the minimal
# required url encoding.
sub escape_url_for_webpage {
    my ($url) = @_;

    $url =~ s/\?/%3F/g;
    $url =~ s/=/%3D/g;
    $url =~ s/&/%26/g;

    return $url;
}

1;
```

# PHP を使用して URL 署名を作成する
<a name="CreateURL_PHP"></a>

PHP を実行するすべてのウェブサーバーでは、この PHP サンプルコードを使用して、CloudFront のプライベートディストリビューション用のポリシーステートメントと署名を作成できます。この完全なサンプルでは、CloudFront ストリーミングを使用してビデオストリームを再生する署名付き URL リンクが含まれた、実際に動作するウェブページを作成します。完全な例については、[demo-php.zip](samples/demo-php.zip) ファイルからダウンロードできます。

**注意事項**  
URL 署名の作成は、署名付き URL を使用してプライベートコンテンツを供給するためのプロセスの 1 パートにすぎません。プロセス全体の詳細については、「[署名付き URL を使用する](private-content-signed-urls.md)」を参照してください。
AWS SDK for PHP の `UrlSigner` クラスを使用して署名付き URL を作成することもできます。詳細については、*AWS SDK for PHP API リファレンス*の「[Class UrlSigner](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.CloudFront.UrlSigner.html)」を参照してください。

**Topics**
+ [

## RSA SHA-1 署名を作成する
](#sample-rsa-sign)
+ [

## 既定ポリシーを作成する
](#sample-canned-policy)
+ [

## カスタムポリシーを作成するには
](#sample-custom-policy)
+ [

## 完全なサンプルコード
](#full-example)

以下のセクションでは、コード例を個別のパートに分解します。「[完全なサンプルコード](#full-example)」は以下にあります。

## RSA SHA-1 署名を作成する
<a name="sample-rsa-sign"></a>

このコード例では、次の操作を行います。
+ 関数 `rsa_sha1_sign` は、ポリシーステートメントをハッシュ化して署名します。必要な引数は、ポリシーステートメントと、ディストリビューションの信頼されたキーグループにあるパブリックキーに対応するプライベートキーです。
+ 次に、`url_safe_base64_encode` 関数で、URL で使用可能なバージョンの署名を作成します。

```
function rsa_sha1_sign($policy, $private_key_filename) {
    $signature = "";

    // load the private key
    $fp = fopen($private_key_filename, "r");
    $priv_key = fread($fp, 8192);
    fclose($fp);
    $pkeyid = openssl_get_privatekey($priv_key);

    // compute signature
    openssl_sign($policy, $signature, $pkeyid);

    // free the key from memory
    openssl_free_key($pkeyid);

    return $signature;
}

function url_safe_base64_encode($value) {
    $encoded = base64_encode($value);
    // replace unsafe characters +, = and / with 
    // the safe characters -, _ and ~
    return str_replace(
        array('+', '=', '/'),
        array('-', '_', '~'),
        $encoded);
}
```

次のコードスニペットでは、`get_canned_policy_stream_name()` 関数と `get_custom_policy_stream_name()` 関数を使用して既定ポリシーとカスタムポリシーを作成します。CloudFront は、これらのポリシーを使用して、有効期限を指定するとともに、動画をストリーミングするための URL を作成します。

次に、既定ポリシーまたはカスタムポリシーを使用して、コンテンツへのアクセスを管理する方法を決定できます。どちらを選択するかの詳細については、「[署名付き URL に既定ポリシーとカスタムポリシーのどちらを使用するかを決定する](private-content-signed-urls.md#private-content-choosing-canned-custom-policy)」セクションを参照してください。

## 既定ポリシーを作成する
<a name="sample-canned-policy"></a>

以下のサンプルコードでは、署名用の*既定*ポリシーステートメントを作成します。

**注記**  
`$expires` 変数は、文字列ではなく整数である必要がある日時スタンプです。

```
function get_canned_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $expires) {
    // this policy is well known by CloudFront, but you still need to sign it, since it contains your parameters
    $canned_policy = '{"Statement":[{"Resource":"' . $video_path . '","Condition":{"DateLessThan":{"AWS:EpochTime":'. $expires . '}}}]}';
    // the policy contains characters that cannot be part of a URL, so we base64 encode it
    $encoded_policy = url_safe_base64_encode($canned_policy);
    // sign the original policy, not the encoded version
    $signature = rsa_sha1_sign($canned_policy, $private_key_filename);
    // make the signature safe to be included in a URL
    $encoded_signature = url_safe_base64_encode($signature);

    // combine the above into a stream name
    $stream_name = create_stream_name($video_path, null, $encoded_signature, $key_pair_id, $expires);
    // URL-encode the query string characters
    return $stream_name;
}
```

既定ポリシーの詳細については、「[既定ポリシーを使用して署名付き URL を作成する](private-content-creating-signed-url-canned-policy.md)」を参照してください。

## カスタムポリシーを作成するには
<a name="sample-custom-policy"></a>

以下のサンプルコードでは、署名用の*カスタム*ポリシーステートメントを作成します。

```
function get_custom_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $policy) {
    // the policy contains characters that cannot be part of a URL, so we base64 encode it
    $encoded_policy = url_safe_base64_encode($policy);
    // sign the original policy, not the encoded version
    $signature = rsa_sha1_sign($policy, $private_key_filename);
    // make the signature safe to be included in a URL
    $encoded_signature = url_safe_base64_encode($signature);

    // combine the above into a stream name
    $stream_name = create_stream_name($video_path, $encoded_policy, $encoded_signature, $key_pair_id, null);
    // URL-encode the query string characters
    return $stream_name;
}
```

カスタムポリシーの詳細については、「[カスタムポリシーを使用して署名付き URL を作成する](private-content-creating-signed-url-custom-policy.md)」を参照してください。

## 完全なサンプルコード
<a name="full-example"></a>

次のコードサンプルでは、PHP で CloudFront 署名付き URL を作成する詳細な方法を示します。完全な例については、[demo-php.zip](samples/demo-php.zip) ファイルからダウンロードできます。

次の例では、`$policy` `Condition` エレメントを変更して、IPv4 アドレス範囲と IPv6 アドレス範囲の両方を許可できます。例については、「Amazon Simple Storage Service ユーザーガイド」の「[IAM ポリシーでの IPv6 アドレスの使用](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ipv6-access.html#ipv6-access-iam)」を参照してください。**

```
<?php

function rsa_sha1_sign($policy, $private_key_filename) {
    $signature = "";

    // load the private key
    $fp = fopen($private_key_filename, "r");
    $priv_key = fread($fp, 8192);
    fclose($fp);
    $pkeyid = openssl_get_privatekey($priv_key);

    // compute signature
    openssl_sign($policy, $signature, $pkeyid);

    // free the key from memory
    openssl_free_key($pkeyid);

    return $signature;
}

function url_safe_base64_encode($value) {
    $encoded = base64_encode($value);
    // replace unsafe characters +, = and / with the safe characters -, _ and ~
    return str_replace(
        array('+', '=', '/'),
        array('-', '_', '~'),
        $encoded);
}

function create_stream_name($stream, $policy, $signature, $key_pair_id, $expires) {
    $result = $stream;
    // if the stream already contains query parameters, attach the new query parameters to the end
    // otherwise, add the query parameters
    $separator = strpos($stream, '?') == FALSE ? '?' : '&';
    // the presence of an expires time means we're using a canned policy
    if($expires) {
        $result .= $separator . "Expires=" . $expires . "&Signature=" . $signature . "&Key-Pair-Id=" . $key_pair_id;
    }
    // not using a canned policy, include the policy itself in the stream name
    else {
        $result .= $separator . "Policy=" . $policy . "&Signature=" . $signature . "&Key-Pair-Id=" . $key_pair_id;
    }

    // new lines would break us, so remove them
    return str_replace('\n', '', $result);
}


function get_canned_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $expires) {
    // this policy is well known by CloudFront, but you still need to sign it, since it contains your parameters
    $canned_policy = '{"Statement":[{"Resource":"' . $video_path . '","Condition":{"DateLessThan":{"AWS:EpochTime":'. $expires . '}}}]}';
    // the policy contains characters that cannot be part of a URL, so we base64 encode it
    $encoded_policy = url_safe_base64_encode($canned_policy);
    // sign the original policy, not the encoded version
    $signature = rsa_sha1_sign($canned_policy, $private_key_filename);
    // make the signature safe to be included in a URL
    $encoded_signature = url_safe_base64_encode($signature);

    // combine the above into a stream name
    $stream_name = create_stream_name($video_path, null, $encoded_signature, $key_pair_id, $expires);
    // URL-encode the query string characters
    return $stream_name;
}

function get_custom_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $policy) {
    // the policy contains characters that cannot be part of a URL, so we base64 encode it
    $encoded_policy = url_safe_base64_encode($policy);
    // sign the original policy, not the encoded version
    $signature = rsa_sha1_sign($policy, $private_key_filename);
    // make the signature safe to be included in a URL
    $encoded_signature = url_safe_base64_encode($signature);

    // combine the above into a stream name
    $stream_name = create_stream_name($video_path, $encoded_policy, $encoded_signature, $key_pair_id, null);
    // URL-encode the query string characters
    return $stream_name;
}


// Path to your private key.  Be very careful that this file is not accessible
// from the web!

$private_key_filename = '/home/test/secure/example-priv-key.pem';
$key_pair_id = 'K2JCJMDEHXQW5F';

// Make sure you have "Restrict viewer access" enabled on this path behaviour and using the above Trusted key groups (recommended).
$video_path = 'https://example.com/secure/example.mp4';

$expires = time() + 300; // 5 min from now
$canned_policy_stream_name = get_canned_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $expires);

// Get the viewer real IP from the x-forward-for header as $_SERVER['REMOTE_ADDR'] will return viewer facing IP. An alternative option is to use CloudFront-Viewer-Address header. Note that this header is a trusted CloudFront immutable header. Example format: IP:PORT ("CloudFront-Viewer-Address": "1.2.3.4:12345")
$client_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$policy =
'{'.
    '"Statement":['.
        '{'.
            '"Resource":"'. $video_path . '",'.
            '"Condition":{'.
                '"IpAddress":{"AWS:SourceIp":"' . $client_ip . '/32"},'.
                '"DateLessThan":{"AWS:EpochTime":' . $expires . '}'.
            '}'.
        '}'.
    ']' .
    '}';
$custom_policy_stream_name = get_custom_policy_stream_name($video_path, $private_key_filename, $key_pair_id, $policy);

?>

<html>

<head>
    <title>CloudFront</title>
</head>

<body>
    <h1>Amazon CloudFront</h1>
    <h2>Canned Policy</h2>
    <h3>Expires at <?php echo gmdate('Y-m-d H:i:s T', $expires); ?></h3>
    <br />

    <div id='canned'>The canned policy video will be here: <br>
    
        <video width="640" height="360" autoplay muted controls>
        <source src="<?php echo $canned_policy_stream_name; ?>" type="video/mp4">
        Your browser does not support the video tag.
        </video>
    </div>

    <h2>Custom Policy</h2>
    <h3>Expires at <?php echo gmdate('Y-m-d H:i:s T', $expires); ?> only viewable by IP <?php echo $client_ip; ?></h3>
    <div id='custom'>The custom policy video will be here: <br>

         <video width="640" height="360" autoplay muted controls>
         <source src="<?php echo $custom_policy_stream_name; ?>" type="video/mp4">
         Your browser does not support the video tag.
        </video>
    </div> 

</body>

</html>
```

その他の URL 署名の例については、以下のトピックを参照してください。
+ [Perl を使用して URL 署名を作成する](CreateURLPerl.md)
+ [C\$1 と .NET Framework を使用して URL 署名を作成する](CreateSignatureInCSharp.md)
+ [Java を使用して URL 署名を作成する](CFPrivateDistJavaDevelopment.md)

署名 URL を使用して署名を作成する代わりに、署名付き cookie を使用できます。詳細については、「[PHP を使用して署名付き cookie を作成する](signed-cookies-PHP.md)」を参照してください。

# C\$1 と .NET Framework を使用して URL 署名を作成する
<a name="CreateSignatureInCSharp"></a>

このセクションの C\$1 の例では、既定およびカスタムのポリシーステートメントを使用して CloudFront プライベートディストリビューションの署名を作成する方法を示すサンプルアプリケーションを実装します。これらの例には、.NET アプリケーションに便利な [AWS SDK for .NET](https://aws.amazon.com/sdkfornet) に基づくユーティリティ関数が含まれています。

SDK for .NET を使用して署名付き URL と署名付き Cookie を作成することもできます。*SDK for .NET API リファレンス*で、以下のトピックを参照してください。
+ **署名付き URL** – [AmazonCloudFrontUrlSigner](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudFront/TCloudFrontUrlSigner.html) 
+ **署名付き Cookie** – [AmazonCloudFrontCookieSigner](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CloudFront/TCloudFrontCookieSigner.html) 

コードをダウンロードするには、[C\$1 による署名コード](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/samples/AWS_PrivateCF_Distributions.zip)にアクセスしてください。

**注意事項**  
`AmazonCloudFrontUrlSigner` および `AmazonCloudFrontCookieSigner` クラスは別のパッケージに移動しました。使用の詳細については、「*AWS SDK for .NET (V4) デベロッパーガイド*」の「[CookieSigner と UrlSigner](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html#net-dg-v4-CookieSigner-UrlSigner)」を参照してください。
URL 署名の作成は、署名付き URL を使用してプライベートコンテンツを供給するためのプロセスの 1 パートにすぎません。詳細については、「[署名付き URL を使用する](private-content-signed-urls.md)」を参照してください。署名付き Cookie の使用の詳細については、「[署名付き Cookie を使用する](private-content-signed-cookies.md)」を参照してください。

## .NET Framework で RSA キーを使用する
<a name="rsa-key-sdk-net"></a>

.NET Framework で RSA キーを使用するには、AWS 提供の .pem ファイルを .NET Framework が使用する XML 形式に変換する必要があります。

変換後、RSA プライベートキーファイルの形式は以下のようになります。

**Example : XML .NET Framework 形式の RSA プライベートキー**  <a name="RSAPrivateKeyXML.NETFrameworkFormat"></a>

```
<RSAKeyValue>
  <Modulus>
    wO5IvYCP5UcoCKDo1dcspoMehWBZcyfs9QEzGi6Oe5y+ewGr1oW+vB2GPB
    ANBiVPcUHTFWhwaIBd3oglmF0lGQljP/jOfmXHUK2kUUnLnJp+oOBL2NiuFtqcW6h/L5lIpD8Yq+NRHg
    Ty4zDsyr2880MvXv88yEFURCkqEXAMPLE=
  </Modulus>
  <Exponent>AQAB</Exponent>
  <P>
    5bmKDaTz
    npENGVqz4Cea8XPH+sxt+2VaAwYnsarVUoSBeVt8WLloVuZGG9IZYmH5KteXEu7fZveYd9UEXAMPLE==
  </P>
  <Q>
    1v9l/WN1a1N3rOK4VGoCokx7kR2SyTMSbZgF9IWJNOugR/WZw7HTnjipO3c9dy1Ms9pUKwUF4
    6d7049EXAMPLE==
  </Q>
  <DP>
    RgrSKuLWXMyBH+/l1Dx/I4tXuAJIrlPyo+VmiOc7b5NzHptkSHEPfR9s1
    OK0VqjknclqCJ3Ig86OMEtEXAMPLE==
  </DP>
  <DQ>
    pjPjvSFw+RoaTu0pgCA/jwW/FGyfN6iim1RFbkT4
    z49DZb2IM885f3vf35eLTaEYRYUHQgZtChNEV0TEXAMPLE==
  </DQ>
  <InverseQ>
    nkvOJTg5QtGNgWb9i
    cVtzrL/1pFEOHbJXwEJdU99N+7sMK+1066DL/HSBUCD63qD4USpnf0myc24in0EXAMPLE==</InverseQ>
  <D>
      Bc7mp7XYHynuPZxChjWNJZIq+A73gm0ASDv6At7F8Vi9r0xUlQe/v0AQS3ycN8QlyR4XMbzMLYk
      3yjxFDXo4ZKQtOGzLGteCU2srANiLv26/imXA8FVidZftTAtLviWQZBVPTeYIA69ATUYPEq0a5u5wjGy
      UOij9OWyuEXAMPLE=
   </D>
</RSAKeyValue>
```

## C\$1 における既定ポリシーの署名方法
<a name="canned-policy-signed-url-net"></a>

以下の C\$1 コードは、以下を実行して、既定ポリシーを使用する署名付き URL を作成します。
+ ポリシーステートメントを作成する。
+ SHA1 を使用してポリシーステートメントをハッシュ化し、RSA とプライベートキー (信頼されたキーグループにあるパブリックキーに対応するもの) を使用して、結果に署名します。
+ ハッシュ化および署名されたポリシーステートメントを base64 エンコードし、特殊文字を置き換えて文字列を URL リクエストパラメータとして使用できるようにする。
+ 値を連結する。

完全な実装については、[C\$1 による署名コード](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/samples/AWS_PrivateCF_Distributions.zip)の例を参照してください。

**注記**  
CloudFront にパブリックキーをアップロードすると、`keyId` が返されます。詳細については、「![\[6\]](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/images/callouts/6.png)[ &Key-Pair-Id](private-content-creating-signed-url-canned-policy.md)」を参照してください。

**Example : C\$1 における既定ポリシーの署名方法**  <a name="ExampleCannedPolicySigningMethod-CSharp"></a>

```
public static string ToUrlSafeBase64String(byte[] bytes)
{
    return System.Convert.ToBase64String(bytes)
        .Replace('+', '-')
        .Replace('=', '_')
        .Replace('/', '~');
}

public static string CreateCannedPrivateURL(string urlString, 
    string durationUnits, string durationNumber, string pathToPolicyStmnt, 
    string pathToPrivateKey, string keyId)
{
    // args[] 0-thisMethod, 1-resourceUrl, 2-seconds-minutes-hours-days 
    // to expiration, 3-numberOfPreviousUnits, 4-pathToPolicyStmnt, 
    // 5-pathToPrivateKey, 6-keyId

    TimeSpan timeSpanInterval = GetDuration(durationUnits, durationNumber);

    // Create the policy statement.
    string strPolicy = CreatePolicyStatement(pathToPolicyStmnt,
        urlString, 
        DateTime.Now, 
        DateTime.Now.Add(timeSpanInterval), 
        "0.0.0.0/0");
    if ("Error!" == strPolicy) return "Invalid time frame." + 
        "Start time cannot be greater than end time.";

    // Copy the expiration time defined by policy statement.
    string strExpiration = CopyExpirationTimeFromPolicy(strPolicy);

    // Read the policy into a byte buffer.
    byte[] bufferPolicy = Encoding.ASCII.GetBytes(strPolicy);

    // Initialize the SHA1CryptoServiceProvider object and hash the policy data.
    using (SHA1CryptoServiceProvider 
        cryptoSHA1 = new SHA1CryptoServiceProvider())
    {
        bufferPolicy = cryptoSHA1.ComputeHash(bufferPolicy);

        // Initialize the RSACryptoServiceProvider object.
        RSACryptoServiceProvider providerRSA = new RSACryptoServiceProvider();
        XmlDocument xmlPrivateKey = new XmlDocument();

        // Load your private key, which you created by converting your 
        // .pem file to the XML format that the .NET framework uses.  
        // Several tools are available. 
        xmlPrivateKey.Load(pathToPrivateKey);

        // Format the RSACryptoServiceProvider providerRSA and 
        // create the signature.
        providerRSA.FromXmlString(xmlPrivateKey.InnerXml);
        RSAPKCS1SignatureFormatter rsaFormatter = 
            new RSAPKCS1SignatureFormatter(providerRSA);
        rsaFormatter.SetHashAlgorithm("SHA1");
        byte[] signedPolicyHash = rsaFormatter.CreateSignature(bufferPolicy);

        // Convert the signed policy to URL-safe base64 encoding and 
        // replace unsafe characters + = / with the safe characters - _ ~
        string strSignedPolicy = ToUrlSafeBase64String(signedPolicyHash);

        // Concatenate the URL, the timestamp, the signature, 
        // and the key pair ID to form the signed URL.
        return urlString + 
            "?Expires=" + 
            strExpiration + 
            "&Signature=" + 
            strSignedPolicy + 
            "&Key-Pair-Id=" + 
            keyId;
    }
}
```

## C\$1 におけるカスタムポリシーの署名方法
<a name="custom-policy-signed-url-net"></a>

以下の C\$1 コードは、以下の手順を実行して、カスタムポリシーを使用する署名付き URL を作成します。

1. ポリシーステートメントを作成する。

1. ポリシーステートメントを Base64 エンコードし、特殊文字を置き換えて文字列を URL リクエストパラメータとして使用できるようにする。

1. SHA1 を使用してポリシーステートメントをハッシュ化し、RSA とプライベートキー (信頼されたキーグループにあるパブリックキーに対応するもの) を使用して、結果を暗号化します。

1. ハッシュ化されたポリシーステートメントを base64 エンコードし、特殊文字を置き換えて文字列を URL リクエストパラメータとして使用できるようにする。

1. 値を連結する。

完全な実装については、[C\$1 による署名コード](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/samples/AWS_PrivateCF_Distributions.zip)の例を参照してください。

**注記**  
CloudFront にパブリックキーをアップロードすると、`keyId` が返されます。詳細については、「![\[6\]](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/images/callouts/6.png)[ &Key-Pair-Id](private-content-creating-signed-url-canned-policy.md)」を参照してください。

**Example : C\$1 におけるカスタムポリシーの署名方法**  <a name="ExampleCustomPolicySigningMethod-CSharp"></a>

```
public static string ToUrlSafeBase64String(byte[] bytes)
{
    return System.Convert.ToBase64String(bytes)
        .Replace('+', '-')
        .Replace('=', '_')
        .Replace('/', '~');
}

public static string CreateCustomPrivateURL(string urlString, 
    string durationUnits, string durationNumber, string startIntervalFromNow, 
    string ipaddress, string pathToPolicyStmnt, string pathToPrivateKey, 
    string keyId)
{
    // args[] 0-thisMethod, 1-resourceUrl, 2-seconds-minutes-hours-days 
    // to expiration, 3-numberOfPreviousUnits, 4-starttimeFromNow, 
    // 5-ip_address, 6-pathToPolicyStmt, 7-pathToPrivateKey, 8-keyId

    TimeSpan timeSpanInterval = GetDuration(durationUnits, durationNumber);
    TimeSpan timeSpanToStart = GetDurationByUnits(durationUnits, 
        startIntervalFromNow);
    if (null == timeSpanToStart) 
        return "Invalid duration units." + 
            "Valid options: seconds, minutes, hours, or days";
            
    string strPolicy = CreatePolicyStatement(
        pathToPolicyStmnt, urlString, DateTime.Now.Add(timeSpanToStart), 
        DateTime.Now.Add(timeSpanInterval), ipaddress);

    // Read the policy into a byte buffer.
    byte[] bufferPolicy = Encoding.ASCII.GetBytes(strPolicy);

    // Convert the policy statement to URL-safe base64 encoding and 
    // replace unsafe characters + = / with the safe characters - _ ~

    string urlSafePolicy = ToUrlSafeBase64String(bufferPolicy);

    // Initialize the SHA1CryptoServiceProvider object and hash the policy data.
    byte[] bufferPolicyHash;
    using (SHA1CryptoServiceProvider cryptoSHA1 = 
        new SHA1CryptoServiceProvider())
    {
        bufferPolicyHash = cryptoSHA1.ComputeHash(bufferPolicy);

        // Initialize the RSACryptoServiceProvider object.
        RSACryptoServiceProvider providerRSA = new RSACryptoServiceProvider();
        XmlDocument xmlPrivateKey = new XmlDocument();

        // Load your private key, which you created by converting your 
        // .pem file to the XML format that the .NET framework uses.  
        // Several tools are available. 
        xmlPrivateKey.Load(pathToPrivateKey);

        // Format the RSACryptoServiceProvider providerRSA 
        // and create the signature.
        providerRSA.FromXmlString(xmlPrivateKey.InnerXml);
        RSAPKCS1SignatureFormatter RSAFormatter = 
            new RSAPKCS1SignatureFormatter(providerRSA);
        RSAFormatter.SetHashAlgorithm("SHA1");
        byte[] signedHash = RSAFormatter.CreateSignature(bufferPolicyHash);

        // Convert the signed policy to URL-safe base64 encoding and 
        // replace unsafe characters + = / with the safe characters - _ ~
        string strSignedPolicy = ToUrlSafeBase64String(signedHash);

        return urlString + 
            "?Policy=" + 
            urlSafePolicy + 
            "&Signature=" + 
            strSignedPolicy + 
            "&Key-Pair-Id=" + 
            keyId;
    }
}
```

## 署名生成のためのユーティリティメソッド
<a name="utility-methods-signed-url"></a>

以下のメソッドは、ファイルからポリシーステートメントを取得し、署名生成の期間を解析します。

**Example : 署名生成のためのユーティリティメソッド**  <a name="UtilityMethodsForSignatureGeneration"></a>

```
public static string CreatePolicyStatement(string policyStmnt, 
   string resourceUrl, 
   DateTime startTime, 
   DateTime endTime, 
   string ipAddress)
   
{
   // Create the policy statement.
   FileStream streamPolicy = new FileStream(policyStmnt, FileMode.Open, FileAccess.Read);
   using (StreamReader reader = new StreamReader(streamPolicy))
   {
      string strPolicy = reader.ReadToEnd();

      TimeSpan startTimeSpanFromNow = (startTime - DateTime.Now);
      TimeSpan endTimeSpanFromNow = (endTime - DateTime.Now);
      TimeSpan intervalStart = 
         (DateTime.UtcNow.Add(startTimeSpanFromNow)) - 
         new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
      TimeSpan intervalEnd = 
         (DateTime.UtcNow.Add(endTimeSpanFromNow)) - 
         new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

      int startTimestamp = (int)intervalStart.TotalSeconds; // START_TIME
      int endTimestamp = (int)intervalEnd.TotalSeconds;  // END_TIME

      if (startTimestamp > endTimestamp)
         return "Error!";

      // Replace variables in the policy statement.
      strPolicy = strPolicy.Replace("RESOURCE", resourceUrl);
      strPolicy = strPolicy.Replace("START_TIME", startTimestamp.ToString());
      strPolicy = strPolicy.Replace("END_TIME", endTimestamp.ToString());
      strPolicy = strPolicy.Replace("IP_ADDRESS", ipAddress);
      strPolicy = strPolicy.Replace("EXPIRES", endTimestamp.ToString());
      return strPolicy;
   }   
}

public static TimeSpan GetDuration(string units, string numUnits)
{
   TimeSpan timeSpanInterval = new TimeSpan();
   switch (units)
   {
      case "seconds":
         timeSpanInterval = new TimeSpan(0, 0, 0, int.Parse(numUnits));
         break;
      case "minutes":
         timeSpanInterval = new TimeSpan(0, 0, int.Parse(numUnits), 0);
         break;
      case "hours":
         timeSpanInterval = new TimeSpan(0, int.Parse(numUnits), 0 ,0);
         break;
      case "days":
         timeSpanInterval = new TimeSpan(int.Parse(numUnits),0 ,0 ,0);
         break;
      default:
         Console.WriteLine("Invalid time units;" + 
            "use seconds, minutes, hours, or days");
         break;
   }
   return timeSpanInterval;
}

private static TimeSpan GetDurationByUnits(string durationUnits, 
   string startIntervalFromNow)
{
   switch (durationUnits)
   {
      case "seconds":
         return new TimeSpan(0, 0, int.Parse(startIntervalFromNow));
      case "minutes":
         return new TimeSpan(0, int.Parse(startIntervalFromNow), 0);
      case "hours":
         return new TimeSpan(int.Parse(startIntervalFromNow), 0, 0);
      case "days":
         return new TimeSpan(int.Parse(startIntervalFromNow), 0, 0, 0);
      default:
         return new TimeSpan(0, 0, 0, 0);
   }
}

public static string CopyExpirationTimeFromPolicy(string policyStatement)
{
   int startExpiration = policyStatement.IndexOf("EpochTime");
   string strExpirationRough = policyStatement.Substring(startExpiration + 
      "EpochTime".Length);
   char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
         
   List<char> listDigits = new List<char>(digits);
   StringBuilder buildExpiration = new StringBuilder(20);
         
   foreach (char c in strExpirationRough)
   {
      if (listDigits.Contains(c))
         buildExpiration.Append(c);
   }
   return buildExpiration.ToString();   
}
```

関連情報
+ [Perl を使用して URL 署名を作成する](CreateURLPerl.md)
+ [PHP を使用して URL 署名を作成する](CreateURL_PHP.md)
+ [Java を使用して URL 署名を作成する](CFPrivateDistJavaDevelopment.md)

# Java を使用して URL 署名を作成する
<a name="CFPrivateDistJavaDevelopment"></a>

次のコード例に加えて、AWS SDK for Java (バージョン 1) の[`CloudFrontUrlSigner` ユーティリティクラス](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/cloudfront/CloudFrontUrlSigner.html)を使用して [CloudFront の署名付き URL](private-content-signed-urls.md) を作成することもできます。

その他の例については、「AWS SDK コードサンプルコードライブラリ」の「[AWS SDK を使用して署名付き URL と Cookie を作成する](https://docs.aws.amazon.com/code-library/latest/ug/cloudfront_example_cloudfront_CloudFrontUtilities_section.html)」を参照してください。**

**注記**  
署名付き URL の作成は、[CloudFront を使用してプライベートコンテンツを供給する](PrivateContent.md)プロセスの一部にすぎません。プロセス全体の詳細については、「[署名付き URL を使用する](private-content-signed-urls.md)」を参照してください。

以下の例は、CloudFront の署名付き URL の作成方法を示しています。

**Example Java のポリシーおよび署名暗号化メソッド**  <a name="ExampleJavaPolicyAndSignatureEncryptionMethods"></a>

```
package org.example;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import software.amazon.awssdk.services.cloudfront.CloudFrontUtilities;
import software.amazon.awssdk.services.cloudfront.model.CannedSignerRequest;
import software.amazon.awssdk.services.cloudfront.url.SignedUrl;

public class Main {

    public static void main(String[] args) throws Exception {
        CloudFrontUtilities cloudFrontUtilities = CloudFrontUtilities.create();
        Instant expirationDate = Instant.now().plus(7, ChronoUnit.DAYS);
        String resourceUrl = "https://a1b2c3d4e5f6g7.cloudfront.net";
        String keyPairId = "K1UA3WV15I7JSD";
        CannedSignerRequest cannedRequest = CannedSignerRequest.builder()
                .resourceUrl(resourceUrl)
                .privateKey(new java.io.File("/path/to/private_key.pem").toPath())
                .keyPairId(keyPairId)
                .expirationDate(expirationDate)
                .build();
        SignedUrl signedUrl = cloudFrontUtilities.getSignedUrlWithCannedPolicy(cannedRequest);
        String url = signedUrl.url();
        System.out.println(url);

    }
}
```

次の資料も参照してください:
+ [Perl を使用して URL 署名を作成する](CreateURLPerl.md)
+ [PHP を使用して URL 署名を作成する](CreateURL_PHP.md)
+ [C\$1 と .NET Framework を使用して URL 署名を作成する](CreateSignatureInCSharp.md)