Java™セキュリティの概要

1はじめに

Java™プラットフォームは、セキュリティを重視して設計されました。その中核では、Java言語自体が型保証されており、自動ガベージ・コレクションを提供してアプリケーション・コードの堅牢性を強化しています。安全なクラス・ロードおよび検証メカニズムによって、正当なJavaコードのみが実行されます。

Javaプラットフォームの初期バージョンでは、パブリック・ネットワークからダウンロードされたJavaアプレットなど、潜在的に信頼されないコードを実行するための安全な環境を作成しました。プラットフォームが発展し、その配備範囲が拡大するにつれて、Javaセキュリティ・アーキテクチャは増加するサービス・セットをサポートするために進化しました。現在、アーキテクチャには、アプリケーション・プログラミング・インタフェース(API)、ツール、および一般的に使用されるセキュリティ・アルゴリズム、メカニズム、プロトコルの実装の、大規模なセットが含まれています。これにより、アプリケーションを記述するための包括的なセキュリティ・フレームワークを開発者に提供し、ユーザーまたは管理者にアプリケーションを安全に管理するための一連のツールを提供しています。

JavaセキュリティAPIは、広範な領域に及びます。暗号化および公開キーインフラストラクチャ(PKI)インタフェースは、安全なアプリケーションを開発するための基盤となります。認証およびアクセス制御を実行するためのインタフェースにより、アプリケーションは、保護されたリソースへの承認されていないアクセスから保護できます。

APIでは、アルゴリズムおよびその他のセキュリティ・サービスについて、複数の相互運用可能な実装が可能です。サービスはプロバイダに実装され、プロバイダはアプリケーションがセキュリティ・サービスの実装を意識せずに簡単に取得できるようにする標準インタフェースによって、Javaプラットフォームにプラグインされます。これにより、開発者は、複雑なセキュリティ・メカニズムを実際に実装する方法ではなく、セキュリティをアプリケーションに統合する方法に重点を置くことができます。

Javaプラットフォームには、基本的なセキュリティ・サービスを実装する多数のプロバイダが含まれています。追加のカスタム・プロバイダをインストールすることも可能です。これにより、開発者は新しいセキュリティ・メカニズムでプラットフォームを拡張できます。

このドキュメントでは、セキュアな言語機能からセキュリティAPI、ツールおよび組込みプロバイダ・サービスにいたるまで、Javaプラットフォームのセキュリティの概要について説明し、該当する場合には、主要なパッケージおよびクラスについて説明します。このドキュメントは、Java(tm) SE version 8に基づいています。

2 Java言語セキュリティおよびバイト・コード検証

Java言語は、型保証されるように設計されており、簡単に使用できます。自動メモリー管理、ガベージ・コレクション、および配列の範囲チェックを備えています。これにより、開発者の全体的なプログラミングの負荷を軽減し、見つかりにくいプログラミング・エラーの減少および安全で堅牢なコードを実現します。

また、Java言語は、異なるアクセス修飾子を定義してJavaクラス、メソッド、およびフィールドに割り当てることができるため、開発者はクラス実装へのアクセスを必要に応じて制限できます。特に、この言語はprivateprotectedpublic、およびpackage (指定されない場合)の4つの異なるアクセス・レベルを定義します。もっともオープンなアクセス指定子はpublicで、アクセスはすべての人に許可されます。アクセスをもっとも制限する修飾子はprivateで、アクセスはprivateメンバー(メソッドなど)が定義された特定のクラス以外では許可されません。protected修飾子は、任意のサブクラス、または同じパッケージ内のほかのクラスへのアクセスを許可します。packageレベルのアクセスは、同じパッケージ内のクラスへのアクセスのみを許可します。

コンパイラは、Javaプログラムをマシンに依存しないバイト・コード表現に変換します。正当なバイト・コードのみがJava Runtimeで実行されるように、バイトコード・ベリファイアが呼び出されます。これは、バイト・コードがJava言語仕様に準拠しており、Javaの言語規則または名前空間制限に違反していないことをチェックします。ベリファイアは、メモリー管理違反、スタック・アンダーフローまたはオーバーフロー、および不正な型キャストもチェックします。バイト・コードが検証されると、Java Runtimeはそれらの実行を準備します。

3基本的なセキュリティ・アーキテクチャ

Javaプラットフォームでは、暗号化、公開キーインフラストラクチャ、認証、安全な通信、アクセス制御など、主要なセキュリティ分野に渡る一連のAPIが定義されています。これらのAPIによって、開発者はアプリケーション・コードにセキュリティを簡単に統合できます。これらは、次の方針に基づいて設計されました。

実装の独立性
アプリケーションでセキュリティを実装する必要はありません。Javaプラットフォームからセキュリティ・サービスを要求できます。セキュリティ・サービスはプロバイダ(次を参照)に実装されています。プロバイダは、標準インタフェースによってJavaプラットフォームにプラグインされます。アプリケーションは、複数の独立したプロバイダにセキュリティ機能を依存する場合があります。
実装の相互運用性
プロバイダは、アプリケーション間で相互運用できます。具体的には、アプリケーションは特定のプロバイダにバインドされず、プロバイダは特定のアプリケーションにバインドされません。
アルゴリズムの拡張性
Javaプラットフォームには、現在広く使用されている基本的なセキュリティ・サービスを実装する多数の組込みプロバイダが含まれています。ただし、一部のアプリケーションは、まだ実装されていない普及しつつある規格や独自のサービスに依存している場合があります。Javaプラットフォームは、そのようなサービスを実装するカスタム・プロバイダのインストールをサポートします。

セキュリティ・プロバイダ

java.security.Providerクラスは、セキュリティ・プロバイダの概念をJavaプラットフォームでカプセル化します。プロバイダの名前を指定し、実装するセキュリティ・サービスを一覧します。複数のプロバイダが同時に構成される場合があり、それらは優先順に一覧されます。セキュリティ・サービスが要求されると、そのサービスを実装する、優先順位がいちばん高いプロバイダが選択されます。

アプリケーションは、関連するgetInstanceメソッドによって、基盤となるプロバイダからセキュリティ・サービスを取得します。たとえば、メッセージ・ダイジェストの作成は、プロバイダから利用可能なサービスの1つのタイプを表します。(セクション4では、メッセージ・ダイジェストおよびその他の暗号化サービスについて説明します。)アプリケーションは、java.security.MessageDigestクラスでgetInstanceメソッドを呼び出して、SHA-256など、特定のメッセージ・ダイジェスト・アルゴリズムの実装を取得します。

MessageDigest md = MessageDigest.getInstance("SHA-256");

プログラムはオプションで、次に示すようにプロバイダ名を指定して、特定のプロバイダから実装を要求する場合があります。

MessageDigest md = 
    MessageDigest.getInstance("SHA-256", "ProviderC");

図1および図2は、SHA-256メッセージ・ダイジェスト実装を要求するための、これらのオプションを示しています。どちらの図も、メッセージ・ダイジェスト・アルゴリズムを実装する3つのプロバイダを示しています。プロバイダは、左から右への優先順位(1から3)で並べられています。図1では、アプリケーションはプロバイダ名を指定せずにSHA-256アルゴリズム実装を要求しています。プロバイダが優先順位に従って検索され、その特定のアルゴリズムを提供する最初のプロバイダであるProviderBから実装が返されます。図2では、アプリケーションは特定のプロバイダであるProviderCからSHA-256アルゴリズム実装を要求しています。この場合は、優先順位の高いプロバイダであるProviderBもSHA-256実装を提供していても、指定されたプロバイダから実装が返されます。

プロバイダ名を指定せずにSHA-256アルゴリズムを要求しているアプリケーションを示す図 特定のプロバイダからSHA-256アルゴリズムを要求しているアプリケーションを示す図
図1プロバイダ検索 図2特定のプロバイダの要求

OracleのJavaプラットフォームの実装には、アプリケーションによって使用できる基本的なセキュリティ・サービスを実装する、多数の事前に構成されたデフォルト・プロバイダが含まれています。Javaプラットフォームのほかのベンダーの実装には、ベンダー固有のセキュリティ・サービスのセットをカプセル化した、異なるプロバイダのセットが含まれている場合があります。このドキュメントで組込みのデフォルト・プロバイダに言及する場合は、Oracleの実装で利用可能なプロバイダを指しています。

さまざまなセキュリティ領域(暗号化、認証など)に関する以降の各セクションには、デフォルト・プロバイダによって提供される関連サービスの説明が含まれています。付録Cの表に、すべてのデフォルト・プロバイダがまとめられています。

ファイルの位置

このドキュメントで説明されているJavaセキュリティの特定の側面(プロバイダの構成など)は、セキュリティ・プロパティを設定することによってカスタマイズできます。セキュリティ・プロパティ・ファイルでセキュリティ・プロパティを静的に設定できます。このファイルは、デフォルトでは、Java(tm) Runtime Environment (JRE)がインストールされているディレクトリのlib/securityディレクトリにあるjava.securityファイルです。セキュリティ・プロパティは、java.securityパッケージ内のSecurityクラスの適切なメソッドを呼び出すことによって、動的に設定することもできます。

このドキュメントで説明されているツールおよびコマンドは、すべて~jre/binディレクトリにあります。~jreは、JREがインストールされているディレクトリを表します。セクション5で説明するcacertsファイルは、~jre/lib/securityにあります。

4暗号化

Java暗号化アーキテクチャは、Javaプラットフォームの暗号化機能へのアクセスおよび開発のためのフレームワークです。次のような、さまざまな暗号化サービスのAPIが含まれています。

歴史的な理由(輸出規制)により、暗号化APIは2つの別個のパッケージに編成されています。java.securityパッケージには、輸出規制の対象ではないクラス(SignatureMessageDigestなど)が含まれています。javax.cryptoパッケージには、輸出規制の対象のクラス(CipherKeyAgreementなど)が含まれています。

暗号化インタフェースはプロバイダ・ベースであり、複数の相互運用性のある暗号化実装が可能です。ソフトウェアで暗号化操作を行うプロバイダもあれば、スマートカード・デバイスやハードウェア暗号化アクセラレータなどのハードウェア・トークン上で暗号化操作を行うプロバイダもあります。輸出規制の対象のサービスを実装するプロバイダには、デジタル署名を行う必要があります。

Javaプラットフォームには、最も一般的に使用される暗号化アルゴリズムの多くのための組込みプロバイダが含まれています。それらは、RSA、DSAおよびECDSA署名アルゴリズム、AES暗号化アルゴリズム、SHA-2メッセージ・ダイジェスト・アルゴリズム、Diffie-Hellman (DH)およびElliptic Curve Diffie-Hellman (ECDH)キー協定アルゴリズムなどです。組込みプロバイダの大部分は、Javaコードで暗号化アルゴリズムを実装しています。

Javaプラットフォームには、ネイティブPKCS#11 (v2.x)トークンへのブリッジとして機能する組込みプロバイダも含まれています。このプロバイダはSunPKCS11という名前であり、JavaアプリケーションはPKCS#11に準拠するトークンに存在する暗号化サービスにシームレスにアクセスできます。

Windowsでは、JavaプラットフォームにネイティブMicrosoft CryptoAPIへのブリッジとして機能する組込みプロバイダが含まれています。このプロバイダはSunMSCAPIという名前であり、JavaアプリケーションはCryptoAPIを介してWindowsの暗号化サービスにシームレスにアクセスできます。

5公開キーインフラストラクチャ

公開キー・インフラストラクチャ(PKI)は、公開キー暗号方式に基づいて情報のセキュアな交換を可能にするフレームワークに対して使用される用語です。(人や組織などの)識別情報のデジタル証明書へのバインドを可能にし、証明書の信頼性を検証する手段を提供します。PKIには、キー、証明書、公開キー暗号化および信頼できる証明書発行局(CA)が含まれます。CAは、証明書を生成してデジタル署名を行います。

Javaプラットフォームには、X.509デジタル証明書と証明書失効リスト(CRL)のAPIおよびプロバイダ・サポート、PKIXに準拠した証明書パスの構築および検証が含まれています。PKIに関係するクラスは、java.securityおよびjava.security.certパッケージ内にあります。

キーおよび証明書ストレージ

Javaプラットフォームは、キーストアおよび証明書ストアを使用して、暗号化キーおよび証明書の長期にわたる永続的なストレージを提供します。具体的には、java.security.KeyStoreクラスがキーストアを表し、java.security.cert.CertStoreクラスが証明書ストアを表します。キーストアは、(たとえば、証明書パス検証中に使用される)暗号化キーまたは信頼できる証明書、あるいはその両方のセキュアなリポジトリです。証明書ストアは、関連がなく通常は信頼されない証明書が含まれるため非常に大きくなる可能性がある公開リポジトリです。CertStoreはCRLを格納する場合もあります。

KeyStoreCertStoreの実装は、タイプによって区別されます。Javaプラットフォームには、標準のPKCS11PKCS12キーストア・タイプ(その実装は、RSA Securityの対応するPKCS仕様に準拠する)が含まれています。さらに、JKS (「Java Key Store」を表す)と呼ばれる独自のファイルベースのキーストア・タイプとDKS (「Domain Key Store」)と呼ばれるタイプも含まれます。DKSは単一の論理キーストアとして存在するキーストアのコレクションです。

Javaプラットフォームには、特別な組込みJKSキーストアcacertsが含まれています。このキーストアには、既知の信頼できるCAの多数の証明書が含まれています。keytoolユーティリティでは、cacertsに含まれている証明書を一覧できます(セクション10のセキュリティ機能のドキュメントのリンクを参照)。

「暗号化」セクション(セクション4)で説明されているSunPKCS11プロバイダには、PKCS11 KeyStore実装が含まれています。つまり、安全なハードウェア(スマート・カードなど)に存在するキーまたは証明書は、KeyStore APIによってJavaアプリケーションからアクセスおよび使用できます。スマート・カードのキーがデバイスを離れることは許可されない場合があります。このような場合、KeyStore APIから返されるjava.security.Keyオブジェクト参照は、単純にキーの参照になる(つまり、実際のキー・データは含まれない)ことがあります。このようなKeyオブジェクトは、実際のキーが存在するデバイスでの暗号化操作の実行にのみ使用できます。

Javaプラットフォームには、LDAP証明書ストア・タイプ(LDAPディレクトリに格納されている証明書へのアクセス用)、およびメモリー内のCollection証明書ストア・タイプ(java.util.Collectionオブジェクトで管理されている証明書へのアクセス用)も含まれています。

PKIツール

キー、証明書、およびキー・ストアを操作するための2つの組込みツールがあります。

keytoolは、キーストアの作成および管理に使用します。次のことが可能です。

jarsignerツールは、JARファイルへの署名、または署名付きJARファイルの署名の検証に使用します。Java ARchive (JAR)ファイル形式を使用すると、複数のファイルを1つのファイルに統合できます。JARファイルには、主にアプレットおよびアプリケーションに関連したクラス・ファイルおよび補助リソースが含まれています。コードにデジタル署名する場合は、最初にkeytoolを使用して適切なキーおよび証明書をキー・ストアに生成またはインポートし(それらがまだ存在しない場合)、次に、jarツールを使用してコードをJARファイル内に配置し、最後にjarsignerツールを使用してJARファイルに署名します。jarsignerツールは、キー・ストアにアクセスし、JARファイルの署名または署名付きJARファイルの署名の検証に必要なキーおよび証明書を見つけます。注: jarsignerは、オプションでタイムスタンプを含む署名を生成できます。JARファイルの署名を検証するシステム(Java Plug-inなど)は、タイムスタンプをチェックして、証明書が最新であることを要求するかわりに、証明書が有効な間に署名されたJARファイルを受け入れることができます。証明書は、通常1年で期限切れになります。配備されたJARファイルにJARファイルの作成者が毎年再署名すると考えるのは妥当ではありません。

6認証

認証とは、ユーザーのアイデンティティを判別するプロセスのことです。Java Runtime Environmentのコンテキストでは、実行中のJavaプログラムのユーザーを識別するプロセスのことです。このプロセスは、「暗号化」セクション(セクション4)で説明したサービスに依存する場合があります。

Javaプラットフォームは、アプリケーションがプラガブルなログイン・モジュールによってユーザー認証を実行できるようにするAPIを提供します。アプリケーションはLoginContextクラス(javax.security.auth.loginパッケージ内)を呼び出し、このクラスは構成を参照します。構成は、実際の認証を実行するために使用するログイン・モジュール(javax.security.auth.spi.LoginModuleインタフェースの実装)を指定します。

アプリケーションは、標準のLoginContext APIと通信するだけなので、基盤となるプラグイン・モジュールから独立したままの状態を維持できます。アプリケーションでは、新規または更新されたモジュールをプラグインとして使用でき、アプリケーションを変更する必要はありません。図3は、アプリケーションと基盤となるログイン・モジュールの間の独立性を示しています。

アプリケーションとログイン・モジュールの間の独立性を示す図

図3認証フレームワークにプラグインする認証ログイン・モジュール

ログイン・モジュールはJavaプラットフォームで構成できるプラガブルなコンポーネントですが、セキュリティ・プロバイダを介してプラグインされません。したがって、セクション3で説明されているプロバイダ検索モデルには従いません。代わりに、図に示したように、ログイン・モジュールは固有の構成によって管理されます。

Javaプラットフォームは、次の組み込みLoginModuleを提供します。これらはすべて、com.sun.security.auth.moduleパッケージ内にあります。

認証は、2つのピア間のセキュアな通信チャネルの確立プロセス中に実現することもできます。Javaプラットフォームは、多数の標準通信プロトコルの実装を提供します。これについては、次のセクションで説明します。

7安全な通信

ネットワークを通じてやり取りされるデータには、意図された受信者以外の人もアクセスできます。データにパスワードやクレジット・カード番号などの個人情報が含まれる場合、権限のない者がデータを理解できないよう、手段を講じる必要があります。また、適切な相手にデータを送信し、意図的であるかどうかにかかわらず、通信中にデータが変更されないようにすることも重要です。

暗号化はセキュアな通信に必要な基盤を形成し、セクション4で説明しています。Javaプラットフォームは、多くの標準のセキュアな通信プロトコルにAPIのサポートとプロバイダ実装も提供します。

SSL/TLS

Javaプラットフォームは、SSLおよびTLSプロトコルのAPIおよび実装を提供しています。データ暗号化、メッセージの整合性、サーバー認証だけでなく、オプションでクライアント認証の機能も含まれています。アプリケーションは、SSL/TLSを使用して、TCP/IP上のHTTPなど、任意のアプリケーション・プロトコル上の2つのピア間でセキュアなデータのやり取りを実現できます。

javax.net.ssl.SSLSocketクラスは、通常のストリーム・ソケット(java.net.Socket)上でSSL/TLSサポートをカプセル化するネットワーク・ソケットを表します。一部のアプリケーションは、別のデータ・トランスポート抽象化(New-I/Oなど)を使用する場合があります。javax.net.ssl.SSLEngineクラスを使用して、SSL/TLSパケットを生成および消費できます。

Javaプラットフォームには、プラガブルな(プロバイダ・ベースの)キー・マネージャおよびトラスト・マネージャの概念をサポートするAPIも含まれています。キー・マネージャjavax.net.ssl.KeyManagerクラスによってカプセル化され、認証の実行に使用されるキーを管理します。トラスト・マネージャTrustManagerクラス(同じパッケージ内)によってカプセル化され、管理するキーストア内の証明書に基づいて信頼できる人を決定します。

Javaプラットフォームには、次のSSL/TLSプロトコルを実装する組込みプロバイダが含まれています。

SASL

Simple Authentication and Security Layer (SASL)は、認証およびオプションでクライアント・アプリケーションとサーバー・アプリケーション間のセキュリティ層の確立を行うプロトコルを指定するインターネット標準です。SASLは、認証データの交換方法を定義しますが、そのデータの内容は指定しません。認証データの内容およびセマンティックスを指定する特定の認証メカニズムが適合できるフレームワークです。さまざまなセキュリティ・レベルおよび配備シナリオ用にインターネット・コミュニティによって定義された、多数の標準SASLメカニズムがあります。

Java SASL APIは、SASLメカニズムを使用するアプリケーション用のクラスおよびインタフェースを定義します。これは、メカニズムに依存しないように定義されています。APIを使用するアプリケーションを、特定のSASLメカニズムの使用に固定する必要はありません。アプリケーションは、必要なセキュリティ機能に基づいて、使用するメカニズムを選択できます。このAPIは、クライアントとサーバーの両方のアプリケーションをサポートしています。javax.security.sasl.Saslクラスを使用して、SaslClientおよびSaslServerオブジェクトを作成します。

SASLメカニズムの実装は、プロバイダ・パッケージで提供されます。各プロバイダは、1つ以上のSASLメカニズムをサポートする場合があり、標準プロバイダ・アーキテクチャによって登録されて呼び出されます。

Javaプラットフォームには、次のSASLメカニズムを実装する組込みプロバイダが含まれています。

GSS-APIおよびKerberos

Javaプラットフォームには、Generic Security Service Application Programming Interface (GSS-API)用のJava言語バインディングを持つAPIが含まれています。GSS-APIにより、アプリケーション・プログラマは、様々な基盤となるセキュリティ・メカニズム上のセキュリティ・サービスに統一されたアクセスができます。Java GSS-APIでは現在Kerberos v5メカニズムを使用する必要があり、Javaプラットフォームにはこのメカニズムの組込み実装が含まれています。現時点では、追加のメカニズムをプラグインすることはできません。注: セクション6で説明されているKrb5LoginModuleをGSS Kerberosメカニズムとともに使用できます。

Javaプラットフォームには、Simple and Protected GSSAPI Negotiation Mechanism (SPNEGO) GSS-APIメカニズムの組込み実装も含まれています。

2つのアプリケーションがJava GSS-APIを利用して安全にメッセージを交換するには、事前にジョイント・セキュリティ・コンテキストを確立しておく必要があります。コンテキストは、共有状態の情報(暗号化キーなどを含む)をカプセル化します。両方のアプリケーションが、org.ietf.jgss.GSSContextオブジェクトを作成および使用して、セキュリティ・コンテキストを構成する共有情報の確立および保守を行います。セキュリティ・コンテキストが確立されると、安全なメッセージ交換を準備するために使用できます。

Java GSS APIはorg.ietf.jgssパッケージ内にあります。Javaプラットフォームは、KerberosPrincipalKerberosTicketKerberosKeyKeyTabなど、基本的なKerberosクラスも定義します。これらはjavax.security.auth.kerberosパッケージ内にあります。

8アクセス制御

Javaプラットフォームのアクセス制御アーキテクチャは、機密リソース(ローカル・ファイルなど)または機密アプリケーション・コード(クラス内のメソッドなど)へのアクセスを保護します。すべてのアクセス制御の決定は、java.lang.SecurityManagerクラスによって表されるセキュリティ・マネージャが仲介します。アクセス制御チェックを有効にするには、SecurityManagerをJava Runtimeにインストールする必要があります。

SecurityManagerがインストールされていると、JavaアプレットおよびJava(tm) Web Startアプリケーションは自動的に実行されます。ただし、javaコマンドによって実行されるローカル・アプリケーションは、SecurityManagerがインストールされていてもデフォルトでは実行されません。ローカル・アプリケーションをSecurityManagerで実行するには、アプリケーション自体がsetSecurityManagerメソッド(java.lang.Systemクラス内)によってプログラムでそれを設定するか、またはコマンド行で-Djava.security.manager引数を使用してjavaを呼び出す必要があります。

アクセス権

Javaコードがクラス・ローダーによってJava Runtimeにロードされると、クラス・ローダーは次の情報をそのコードに自動的に関連付けます。

この情報は、コードが信頼されないネットワークからダウンロードされたか(アプレットなど)、ファイル・システムからロードされたか(ローカル・アプリケーションなど)に関係なく、コードに関連付けられます。コードのロード元の場所はURLで表され、コード署名者は署名者の証明書チェーンによって表され、デフォルトのアクセス権はjava.security.Permissionオブジェクトによって表されます。

ダウンロードされたコードに自動的に付与されるデフォルトのアクセス権には、コードの出所であるホストへのネットワーク接続を行う機能が含まれています。ローカル・ファイル・システムからロードされたコードに自動的に付与されるデフォルトのアクセス権には、コードの出所であるディレクトリおよびそのディレクトリのサブディレクトリからファイルを読み取る機能が含まれています。

コードを実行しているユーザーのアイデンティティは、クラス・ローディング時に利用できません。アプリケーション・コードで、(たとえば、セクション6で説明されているように)必要に応じてエンド・ユーザーを認証する必要があります。ユーザーが認証されると、javax.security.auth.SubjectクラスのdoAsメソッドを呼び出すことによって、アプリケーションはそのユーザーを実行コードに動的に関連付けることができます。

Policy

前述したように、限定されたデフォルトのアクセス権がクラス・ローダーによってコードに付与されます。管理者は、セキュリティ・ポリシーによって、追加のコード・アクセス権を柔軟に管理できます。

Javaプラットフォームは、セキュリティ・ポリシーの概念をjava.security.Policyクラスにカプセル化します。Java RuntimeにインストールされるPolicyオブジェクトはいつでも1つのみです。Policyオブジェクトの基本的な役割は、保護されたリソースへのアクセスがコード(ロード元の場所、署名者、および実行者によって特徴付けられる)に許可されるかどうかを決定することです。Policyオブジェクトがこの決定を行う方法は、実装によって異なります。たとえば、承認データを含むデータベースに問い合わせたり、別のサービスに問い合わせたりする場合があります。

Javaプラットフォームには、セキュリティ・プロパティ・ファイル内に構成された1つ以上のASCII (UTF-8)ファイルから承認データを読み込む、デフォルトのPolicy実装が含まれています。これらのポリシー・ファイルには、コードに付与されるアクセス権の厳密なセットが含まれています。具体的には、特定の場所からロードされ、特定のエンティティによって署名され、特定のユーザーとして実行されるコードに付与されるアクセス権の厳密なセットです。各ファイル内のポリシー・エントリは、ドキュメント化された独自の構文に準拠する必要があり、単純なテキスト・エディタまたはグラフィカルなpolicytoolユーティリティを使用して作成できます。

アクセス制御の実施

Java Runtimeは、プログラムの実行時に行われた一連のJava呼出しを追跡します。保護されたリソースへのアクセスが要求された場合、デフォルトでは、要求されたアクセスを許可するかどうかを決定するために呼出しスタック全体が評価されます。

前述したように、リソースはSecurityManagerによって保護されます。Javaプラットフォームおよびアプリケーション内のセキュリティを考慮したコードは、次のようなコードでリソースへのアクセスを保護します。

SecurityManager sm = System.getSecurityManager();
if (sm != null) {
   sm.checkPermission(perm);
}

permは、要求されたアクセスに対応するPermissionオブジェクトです。たとえば、ファイル/tmp/abcを読み取ろうとすると、アクセス権は次のように構成される場合があります。

Permission perm = 
    new java.io.FilePermission("/tmp/abc", "read");

SecurityManagerのデフォルトの実装は、その決定をjava.security.AccessController実装に委譲します。AccessControllerは、呼出しスタックをトラバースして、スタック内の各コード要素を、要求されたアクセス権(たとえば、前述の例ではFilePermission)とともに、インストールされているセキュリティPolicyに渡します。Policyは、管理者によって構成されたアクセス権に基づいて、要求されたアクセスを付与するかどうかを決定します。アクセスが付与されない場合、AccessControllerjava.lang.SecurityException.をスローします。

図4は、アクセス制御の適用を示しています。この特定の例では、最初に2つの要素ClassAおよびClassBが呼出しスタックにあります。ClassAはClassB内のメソッドを呼び出し、メソッドはjava.io.FileInputStream.のインスタンスを作成することによってファイル/tmp/abcにアクセスしようとします。FileInputStreamコンストラクタは、前述したようにFilePermissionpermを作成し、permSecurityManagercheckPermissionメソッドに渡します。この特定の例では、ClassAおよびClassBのアクセス権のみをチェックする必要があります。FileInputStreamSecurityManagerAccessControllerなどのすべてのシステム・コードは、すべてのアクセス権を自動的に受け取るためです。

この例では、ClassAとClassBは異なるコードの特性を持っています(出所および署名者が異なります)。それぞれに異なるアクセス権が付与されている場合があります。要求されたFilePermissionが両方のクラスに付与されていることをPolicyが示した場合にのみ、AccessControllerは要求されたファイルへのアクセスを付与します。

リソースへのアクセスが制御される方法を示す図

図4リソースへのアクセスの制御

9 XML署名

Java XMLデジタル署名APIは、XML署名を生成および検証するための標準のJava APIです。

XML署名は、任意のタイプのデータ(XMLまたはバイナリ)に適用できます(http://www.w3.org/TR/xmldsig-core/を参照)。結果の署名は、XMLで表されます。XML署名は、データを保護するために使用でき、データの整合性、メッセージ認証、および署名者認証を提供します。

APIは、「XML-Signature Syntax and Processing」でのW3C勧告の必須機能または推奨機能をすべてサポートするように設計されています。APIは拡張可能およびプラガブルであり、Java暗号化サービス・プロバイダ・アーキテクチャに基づいてます。

Java XMLデジタル署名APIは、次の6つのパッケージから構成されます。

10 Java API for XML Processing(JAXP)

Java API for XML Processing (JAXP)は、Javaアプリケーションを使用してXMLデータを処理するためのものです。これには、Simple API for XML (SAX)、Document Object Model (DOM)、Streaming API for XML (StAX)の各パーサー、XMLスキーマ検証、およびExtensible Stylesheet Language Transformations (XSLT)のサポートが含まれています。また、JAXPは、XML関連の攻撃からアプリケーションおよびシステムを保護するための安全な処理機能も備えています。『Java API for XML Processing (JAXP)セキュリティ・ガイド』を参照してください。

注意: Java SEのセキュア・コーディング・ガイドラインには、XML関連の攻撃を防御できる追加の推奨事項が含まれています。

11 詳細情報

追加の Java セキュリティ・ドキュメントはオンラインで次の場所にあります。

Java SEセキュリティ

およびJava 2プラットフォーム・セキュリティの詳細、第2版: アーキテクチャ、API設計および実装に関する書籍。

: 歴史的に、新しいタイプのセキュリティ・サービスがJavaプラットフォームに追加されると(最初は拡張機能としての場合もある)、それらを表すために様々な略語が使用されました。これらの略語は引き続きJavaセキュリティ・ドキュメントで使用されているため、それらが何を表しているかをここで説明します。JSSE (Java(tm) Secure Socket Extension)は、セクション7で説明したSSL関連サービスを示しています。JCE (Java(tm) Cryptography Extension)は、暗号化サービス(セクション4)を示しています。JAAS (Java(tm) Authentication and Authorization Service)は、認証およびユーザー・ベースのアクセス制御サービスを示していて、それぞれ、セクション6およびセクション8で説明されています。

付録Aクラスのサマリー

表1は、このドキュメントで説明されているJavaセキュリティ・クラスおよびインタフェースの名前、パッケージ、および使用方法の概要を示しています。

表1主要なJavaセキュリティ・パッケージおよびクラス

パッケージ クラスまたはインタフェース名 使用法
com.sun.security.auth.module JndiLoginModule LDAPまたはNISを使用して、ユーザー名/パスワード認証を実行します
com.sun.security.auth.module KeyStoreLoginModule キーストア・ログインに基づいて認証を実行します
com.sun.security.auth.module Krb5LoginModule Kerberosプロトコルを使用して認証を実行します
java.lang SecurityException セキュリティ違反を示します
java.lang SecurityManager すべてのアクセス制御の決定を仲介します
java.lang System SecurityManagerをインストールします
java.security AccessController アクセス制御の決定を行うために、SecurityManagerのデフォルトの実装によって呼び出されます
java.security DomainLoadStoreParameter ドメイン・キーストア(DKS)のパラメータを保存します
java.security Key 暗号化キーを表します
java.security KeyStore キーおよび信頼できる証明書のリポジトリを表します
java.security MessageDigest メッセージ・ダイジェストを表します
java.security Permission 特定のリソースへのアクセスを表します
java.security PKCS12Attribute PKCS12キーストアの属性をサポートします
java.security Policy セキュリティ・ポリシーをカプセル化します
java.security Provider セキュリティ・サービスの実装をカプセル化します
java.security Security セキュリティ・プロバイダおよびセキュリティ・プロパティを管理します
java.security Signature デジタル署名を作成および検証します
java.security.cert Certificate 公開キー証明書を表します
java.security.cert CertStore 関連性がなく通常は信頼されない証明書のリポジトリを表します
java.security.cert CRL CRLを表します
javax.crypto Cipher 暗号化および復号化を実行します
javax.crypto KeyAgreement キー交換を実行します
javax.net.ssl KeyManager SSL/TLS認証を実行するために使用されるキーを管理します
javax.net.ssl SSLEngine アプリケーションがトランスポート・メカニズムを自由に選択できるように、SSL/TLSパケットを生成および消費します
javax.net.ssl SSLSocket 通常のストリーム・ソケット上でSSL/TLSサポートをカプセル化するネットワーク・ケットを表します
javax.net.ssl TrustManager SSL/TLSインタラクションで信頼できる人に関する決定を行います(たとえば、キーストア内の信頼できる証明書に基づく)
javax.security.auth Subject ユーザーを表します
javax.security.auth.kerberos KerberosPrincipal Kerberosプリンシパルを表します
javax.security.auth.kerberos KerberosTicket Kerberosチケットを表します
javax.security.auth.kerberos KerberosKey Kerberosキーを表します
javax.security.auth.kerberos KerberosTab Kerberosキータブ・ファイルを表します
javax.security.auth.login LoginContext プラガブルな認証をサポートします
javax.security.auth.spi LoginModule 特定の認証メカニズムを実装します
javax.security.sasl Sasl SaslClientおよびSaslServerオブジェクトを作成します
javax.security.sasl SaslClient SASL認証をクライアントとして実行します
javax.security.sasl SaslServer SASL認証をサーバーとして実行します
org.ietf.jgss GSSContext GSS-APIセキュリティ・コンテキストをカプセル化し、コンテキストによって使用可能なセキュリティ・サービスを提供します

付録Bツールのサマリー

表2は、このドキュメントで説明するツールの概要を示しています。

表2 Javaセキュリティ・ツール

ツール 使用法
jar Java Archive (JAR)ファイルを作成します
jarsigner JARファイルの署名および署名の検証を行います
keytool キーストアを作成および管理します
policytool デフォルトのPolicyの実装とともに使用するポリシー・ファイルを作成および編集します

Windows用のJavaプラットフォームに同梱される3つのKerberos関連のツールもあります。同等の機能が、自動的にSolarisおよびLinuxオペレーティング環境の一部になる同じ名前のツールで提供されています。表3は、Kerberosツールの概要を示しています。

表3 Kerberos関連のツール

ツール 使用法
kinit Kerberosチケット認可チケットを取得およびキャッシュします
klist ローカルのKerberos資格キャッシュおよびキー表のエントリを一覧します
ktab ローカルのKerberosキー表に格納された名前およびサービス・キーを管理します

付録C組込みプロバイダ

OracleのJavaプラットフォームの実装には、多数の組込みプロバイダ・パッケージが含まれています。詳細は、「Java(tm)暗号化アーキテクチャOracleプロバイダ・ドキュメント」を参照してください。


Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.