セキュリティ API に関する技術調査 - IPA...15情経第1516号 セキュリティAPI...

121
15 情経第 1516 号 セキュリティ API に関する技術調査 - Part 1 - 概要 アーキテクチャ・機能・暗号技術とアルゴリズム 2004 年 2 月 独立行政法人 情報処理推進機構

Transcript of セキュリティ API に関する技術調査 - IPA...15情経第1516号 セキュリティAPI...

15 情経第 1516 号

セキュリティ APIに関する技術調査

- Part 1 -

概要

アーキテクチャ・機能・暗号技術とアルゴリズム

2004 年 2 月 独立行政法人 情報処理推進機構

登録商標等について

Microsoft、MS、Windows、Windows 2000、Windows NT、Windows ロゴ、Internet Explorer、Outlook、

Visual C++などは、米国Microsoft Corporationの米国およびその他の国における登録商標または商標

である。

Sun Microsystems、Sun ロゴ、Java コーヒーカップロゴ、Solaris、Java、JDK、Solaris などは、米国 Sun

Microsystemsの米国およびその他の国における登録商標または商標である。

その他、本文書に記載されている会社名、商品名、製品名などは、一般に各社の商標または登録商標

または商標である。

本書では、™、©、®などを記載しない。

i

- 目 次 - 1 はじめに.................................................................................................................. 1 2 セキュリティ APIのアーキテクチャ...................................................................... 3 2.1 3層のアーキテクチャモデル............................................................................ 3 2.2 主要なセキュリティ APIのアーキテクチャ.................................................... 6 2.2.1 Microsoft CryptoAPI ................................................................................ 6 2.2.2 Generic Cryptographic Service (GCS) API.............................................. 8 2.2.3 Common Data Security Architecture (CDSA)......................................... 9 2.2.4 Sun Microsystems Java Cryptographic Architecture............................11

3 セキュリティ APIで利用される暗号技術とアルゴリズム ................................... 13 3.1 公開鍵暗号 ..................................................................................................... 13 3.1.1 公開鍵とプライベート鍵 ........................................................................ 13 3.1.2 RSA公開鍵暗号における鍵の構成.......................................................... 13 3.1.3 Diffie-Hellman鍵交換における鍵の構成 ............................................... 14 3.1.4 RSA公開鍵暗号 ...................................................................................... 15 3.1.5 安全性証明付き公開鍵暗号と OAEP...................................................... 15 3.2 鍵交換 ............................................................................................................ 17 3.2.1 公開鍵暗号による鍵交換 ........................................................................ 17 3.2.2 パスワードからの鍵導出 ........................................................................ 19 3.3 共通鍵暗号 ..................................................................................................... 22 3.3.1 ブロック暗号とストリーム暗号.............................................................. 22 3.3.2 ブロック暗号の利用モード..................................................................... 22 3.3.3 パスワードに基づく共通鍵暗号.............................................................. 24 3.3.4 セキュリティ APIで利用される暗号アルゴリズム ................................ 25 3.4 パディングアルゴリズム ............................................................................... 27 3.4.1 ブロック暗号のためのパディングアルゴリズム..................................... 27 3.4.2 公開鍵暗号のためのパディングアルゴリズム ........................................ 28 3.5 一方向性ハッシュ関数 ................................................................................... 30 3.6 デジタル署名 ................................................................................................. 33 3.6.1 RSA署名 ................................................................................................. 33 3.6.2 DSA署名................................................................................................. 35 3.7 メッセージ認証コード(MAC) ................................................................... 36 3.7.1 共通鍵暗号を利用したMAC生成関数(CBC-MAC)........................... 36 3.7.2 一方向性ハッシュ関数を利用したMAC生成関数 ................................. 37 3.7.3 限定的な安全性証明付きMAC生成関数................................................ 39 3.7.4 パスワードに基づくMAC生成関数....................................................... 39 3.7.5 セキュリティ APIで利用されるMACアルゴリズム............................. 40

ii

3.8 セキュア通信 ................................................................................................. 41 3.8.1 SSL 3.0と TLS 1.0 ................................................................................. 41 3.8.2 Transport Layer Security (TLS) 1.1 ...................................................... 51 3.9 PKCS #7......................................................................................................... 53 3.9.1 SignedDataタイプ ................................................................................. 53 3.9.2 EnvelopedDataタイプ ........................................................................... 54 3.9.3 SignedAndEncryptedDataタイプ ......................................................... 55 3.9.4 DigestedDataタイプ .............................................................................. 55 3.9.5 EncryptedDataタイプ ........................................................................... 56

4 セキュリティ APIの主要な機能........................................................................... 57 4.1 公開鍵証明書ハンドリング ............................................................................ 57 4.1.1 CTL(Certificate Trust List)に基づく証明書の検証 ........................... 58 4.1.2 証明書チェインに基づく証明書の検証 ................................................... 60 4.1.3 CRLに基づく証明書の無効化の検証 ...................................................... 60 4.1.4 証明書のストアへの登録/削除 ................................................................ 61 4.1.5 ストア中の証明書の検索 ........................................................................ 62 4.1.6 ストア中の証明書チェインの検索 .......................................................... 63 4.2 セキュア通信 ................................................................................................. 64 4.2.1 抽象レベルのハンドシェイクプロトコル ............................................... 64 4.2.2 抽象レベルのメッセージ保護 ................................................................. 67 4.2.3 SS/TLSハンドシェイクプロトコルの実行 ............................................. 68 4.2.4 SSL/TLSのレコードレイヤプロトコルの実行 ....................................... 69 4.3 鍵交換 ............................................................................................................ 71 4.3.1 公開鍵に基づく鍵交換 ............................................................................ 71 4.4 データの暗号化/復号 ................................................................................... 74 4.4.1 単純な暗号化データの生成..................................................................... 74 4.4.2 単純な暗号化データの復号..................................................................... 77 4.4.3 ストリーム中のデータの暗号化/復号 ..................................................... 78 4.4.4 完備な暗号文オブジェクトの生成 .......................................................... 80 4.4.5 完備な暗号文オブジェクトの復号 .......................................................... 82 4.4.6 PKCS #7 EnvelopedDataの生成 ........................................................... 82 4.4.7 PKCS #7 EnvelopedDataの復号 ........................................................... 84 4.4.8 鍵オブジェクトの生成 ............................................................................ 85 4.4.9 鍵オブジェクトの暗号化 ........................................................................ 87 4.4.10 鍵オブジェクトの復号 .......................................................................... 88 4.5 メッセージダイジェスト(一方向性ハッシュ)............................................ 89 4.5.1 単純なハッシュデータの計算 ................................................................. 89 4.5.2 PKCS #7 DigestedDataの生成 .............................................................. 90

iii

4.5.3 PKCS #7 DigestedDataの検証と復号 ................................................... 91 4.6 デジタル署名 ................................................................................................. 93 4.6.1 単純な署名値の計算 ............................................................................... 93 4.6.2 単純な署名値の検証 ............................................................................... 94 4.6.3 PKCS #7 SignedDataの生成 ................................................................. 95 4.6.4 PKCS #7 SignedDataの検証と復号....................................................... 98 4.7 メッセージ認証コード(MAC) ................................................................. 100 4.7.1 単純なMACの計算.............................................................................. 100 4.8 PKCS #7の複合操作.................................................................................... 101 4.8.1 PKCS #7 SignedAndEnvelopedDataの生成 ....................................... 101 4.8.2 PKCS #7 SignedAndEnvelopedDataの検証と復号............................. 104

5 主要なセキュリティ APIと機能との関係 .......................................................... 106 参考文献 ................................................................................................................. 109 セキュリティ APIに関連する文献 ..................................................................... 109 暗号技術の規格に関する文献 ..............................................................................110 その他の文献 .......................................................................................................112

iv

- 図目次 - 図 2-1 セキュリティ APIの層アーキテクチャ ................................................... 3 図 2-2 Microsoft CryptoAPI のアーキテクチャ(出典:[CryptoAPI])......................... 6 図 2-3 Open Group GCS-APIのアーキテクチャ(出典:[GCS-API]) ............. 8 図 2-4 Open Group CDSAのアーキテクチャ(出典:[CSSM])....................... 9 図 2-5 JCAのアーキテクチャ............................................................................11 図 3-1 RSA鍵交換の例..................................................................................... 18 図 3-2 ブロック暗号の利用モード ................................................................... 24 図 3-3 一方向性ハッシュ関数の繰り返し構造 ................................................. 32 図 3-4 SSLのハンドシェイクプロトコル......................................................... 43 図 3-5 レコードレイヤ ..................................................................................... 51

v

- 表目次 - 表 2-1 CryptoAPIが提供するサービス機能 ........................................................ 7 表 2-2 標準的な CSP ......................................................................................... 7 表 2-3 CSSMのサービス機能........................................................................... 10 表 2-4 J2SEを構成する APIの機能 ................................................................. 12 表 3-1 公開鍵に基づく鍵交換アルゴリズム ..................................................... 19 表 3-2 パスワードからの鍵導出アルゴリズム ................................................. 21 表 3-3ブロック暗号の利用モード .................................................................... 22 表 3-4 PBEアルゴリズム ................................................................................. 25 表 3-5共通鍵暗号アルゴリズム........................................................................ 25 表 3-6 ブロック暗号のためのパディングアルゴリズム ................................... 27 表 3-7 公開鍵暗号のためのパディングアルゴリズム....................................... 29 表 3-8 一方向性ハッシュアルゴリズム ............................................................ 31 表 3-9 デジタル署名アルゴリズム ................................................................... 33 表 3-10 RSA署名のための符号化アルゴリズム ............................................... 34 表 3-11 メッセージ認証コード生成アルゴリズム ............................................ 40 表 3-12 Cipher Suiteに指定されるパラメータ ................................................. 44 表 3-13 Cipher Suiteの意味例 .......................................................................... 45 表 3-14 Diffie-Hellmanの利用モード ................................................................ 48 表 3-15 レコードレイヤで利用される鍵データ ............................................... 49 表 5-1 既存のセキュリティ APIと主要機能の対応........................................ 107

vi

(空白頁)

1

1 はじめに

本パートでは、セキュリティ API について概観する。ここでは、個別の API という観点ではなく、API群を横断する技術や機能という観点から API関数の利用に役立つ情報に焦点を絞って記述し、開発者が実際に APIを利用する局面において有用となる情報を示す。

セキュリティ関連 APIに関しては、情報処理振興事業協会(略称:IPA)の平成

13 年度の調査報告「セキュリティ関連 API に関する調査」(以下、13 年度調査と呼ぶ)において、各種団体が提案するセキュリティ関連 API を、アーキテクチャ/フレームワーク、セキュリティサービス、暗号、認可、バイオ認証に分類した上で、

その概観が解説されている。網羅的な調査によりセキュリティ関連 APIの全体像の俯瞰、個別の APIの特徴を整理したものである。本パートと合わせて参照されたい。

本パートの 2章以降は、以下の構成をとる。 2 章 セキュリティ API のアーキテクチャ

13年度調査においては、MISF、CDSA 1.2、CDSA2.0、JSA、APKI、GSIのセキュリティ APIを「アーキテクチャ/フレームワーク」に分類し、「セキュリティサービスの大枠を取り決める」規格群と位置付けた。これらのアーキテクチャ/フレームワークは、セキュリティ APIの機能を集約的な高次のものから暗号プリミティブなど低次のものへと層別し、効果的に APIを構築していくための概念を示しており、APIを利用するための基本的な情報を与えている。この情報は依然として重要である。。 この章では、セキュリティ APIのアーキテクチャに関して、現状の最新情報に則して 13年度調査の内容を更新するとともに、主要なセキュリティ APIアーキテクチャが共通にベースとしている 3層の階層アーキテクチャを述べる。

3 章 セキュリティ API で利用される暗号技術とアルゴリズム

セキュリティ APIに関して、外部仕様のみではなく、暗号やセキュリティの技術的観点から理解することは、より適切なアプリケーション開発の上で重要である この章では、セキュリティ APIに関し重要と考えられる専門用語と技術内容について、API の利用の上で必要かつ十分な解説を加える。また、セキュリティ APIの標準的な CSP(Cryptographic Service Provider)によってサポートされる具体的な各種アルゴリズムを一覧する。

2

4 章 セキュリティ API の主要な機能

セキュリティ API の機能のうち、証明書ハンドリング、セキュア通信、鍵交換、暗号化/復号、メッセージダイジェスト(一方向性ハッシュ)、デジタル署名、メッ

セージ認証コード、PKCS #7メッセージの復号操作の各項目について示す。 この章では、セキュリティ APIが提供する機能の粒度、および、サポートする暗号アルゴリズムについて述べる。機能の粒度はセキュリティ APIを利用するアプリケーションの機能設計に必須の情報であり、また、暗号アルゴリズムは、アプリケ

ーションの評価のために理解が不可欠な事項である。 5 章 主要なセキュリティ API と機能との対応

既存の主要な APIに関して、4章で見た機能のサポート状況を整理する。開発者がアプリケーション設計を行う際のインデックスとして用いることを狙いとし、個

別のセキュリティ APIについて詳細に触れるものではない。

3

2 セキュリティ APIのアーキテクチャ

2.1 3層のアーキテクチャモデル

すべてのセキュリティ APIは、3層のアーキテクチャ(3-layered architecture)の中で定義される。個別のセキュリティ API によって呼称などに違いがあるものの、階層アーキテクチャの原理的な構成は変わらない。 本パートでは、セキュリティ API共通のアーキテクチャを構成する 3層を、アプリケーション層(Application Layer)、セキュリティサービスマネージャー層(Security Service Manager Layer)、サービスプロバイダー層(Service Provider Layer)と呼ぶこととする(図 2-1)。

アプリケーションA アプリケーションB アプリケーションZ

セキュリティAPI

セキュリティサービスマネージャー

SPI

サービスプロバイダー

A

サービスプロバイダー

B

サービスプロバイダー

Z

api_encrypt()

spi_encrypt()

api_sign()

spi_sign()

セキュリティサービス

マネージャー層

アプリケーション層

サービスプロバイダ層

図 2-1 セキュリティ APIの層アーキテクチャ

各層の基本的な特徴づけを以下に示す。

サービスプロバイダー層 具体的なセキュリティサービスの実装であるサービスプロバイダーによっ

4

て構成される。アプリケーションが要求するセキュリティサービスの実体は、

全て、サービスプロバイダーにより提供される。 セキュリティサービスマネージャー層 上位のアプリケーション層に属するアプリケーションに対して、汎用のセキ

ュリティサービスを共通の API(Application Programming Interface)を介して提供する。 より具体的には、セキュリティサービスマネージャーは下位のサービスプ

ロバイダーを管理しており、上位のアプリケーションからの要求を下位の適

切なサービスプロバイダーに引き渡し、サービスプロバイダーが提供するサ

ービスをアプリケーションに供給するメッセンジャーの役割を果たす。 アプリケーション層 セキュリティサービスマネージャー層が提供するセキュリティサービスを

利用して個別の目的を実現する多様なアプリケーションからなる。 本節では、アプリケーション層とセキュリティサービスマネージャー層との間の

界面を、セキュリティAPIとし、セキュリティAPIが提供する主要な機能を整理する。 一方、セキュリティサービスマネージャー層とサービスプロバイダー層との界面

は、SPI(Service Provider Interface)と呼ばれることが多い。セキュリティ APIに定義される関数とSPIに定義される関数との間には概して一対一の対応が存在するが、これは、アプリケーションがセキュリティ APIの関数を介してサービスプロバイダーが提供する関数を利用するという基本構造を反映した結果である。 上記の 3層アーキテクチャにおいては、セキュリティサービスマネージャー層が中心的な役割を果たす。セキュリティサービスマネージャー層は、下位のサービス

プロバイダーが提供するサービスを、共通のインターフェイスであるセキュリティ

API を介してアプリケーションに提供する。言い換えるならば、3 層アーキテクチャの意義は、アプリケーションからサービスプロバイダーの実装を隠蔽する役割を

果たすセキュリティサービスマネージャー層にある。 サービスプロバイダーの実装を隠蔽することの利点を以下に示す。

アプリケーションの開発に当たって、個別のサービスプロバイダーが提供するサービスの詳細を関知する必要がない。

サービスプロバイダーをモジュール化することが可能となり、拡張性や柔軟性が高まる。特に、暗号やセキュリティの分野では技術革新が急速であるの

で、具体的なセキュリティサービスを提供するサービスプロバイダーを追加

することで、アプリケーションへの影響を最小限に止めつつ最新の技術を利

用できることの利点は重要である。

5

サービスプロバイダーの開発環境が開放されるので、異なるベンダーが同じ機能を有するサービスプロバイダーを提供することが可能である。これによ

り、競争原理が働き、アプリケーションの開発に当って、よりコストパフォ

ーマンスに優れたサービスプロバイダーの実装を選択することができる。 輸出規制の制限を受けない開発が可能となる。暗号技術は輸出規制の対象であるが、具体的に制限の対象となるのはサービスプロバイダーが提供するセ

キュリティサービスである。一方、アプリケーションは共通のセキュリティ

API を介してサービスプロバイダーを利用するので、アプリケーションのみを輸出し、輸出先でサービスプロバイダーを調達することで、アプリケーシ

ョンの輸出に規制を受けなくてすむ。 次節では、主要なセキュリティ APIのアーキテクチャを概観する。

6

2.2 主要なセキュリティ APIのアーキテクチャ

CryptoAPI(Microsoft), GCS-API(Open Group), CDSA(Open Group)、JCA(Sun Microsystems)などの主要なセキュリティ APIのアーキテクチャは、いずれも、2.1 で述べた 3層アーキテクチャに従っている。以下では、上の4つの主要セキュリティ APIに関して、それらのアーキテクチャを概説する。

2.2.1 Microsoft CryptoAPI

図 2-2 に Microsoft 社が提供する CryptoAPI([CryptoAPI])のアーキテクチャを示す。

Application

CryptoAPI

セキュリティサービス

マネージャー層

アプリケーション層

サービス

プロバイダ層

Cryptographic Function

StrongCP

EnhancedCP

AESCP

DSSCP

DSS&

D-HCP

DSS&

D-H/Schannel

CP

RSA/Schannel

CP

BaseCP

Certificate StoreFunction

Certificate Encode/Decode Function

Simple MessageFunction

Low Level MessageFunction

Certificate & Certificate Store Functions

Message Functions

図 2-2 Microsoft CryptoAPI のアーキテクチャ(出典:[CryptoAPI])

7

CryptoAPIにおいては、セキュリティサービスマネージャー層が提供する機能は、Cryptographic Function、Certificate Encode/Decode Function、Certificate Store Function、Low Level Message Function、及び、Simplified Message Functionの 5つであると定義される(表 2-1)。

表 2-1 CryptoAPIが提供するサービス機能

サービス機能 内容

Cryptographic Functions 暗号化/復号、メッセージダイジェスト、デジタル署名、MACなどプリミティブな暗号機能

Certificate Encode/Decode FunctionsCertificate Store Functions

公開鍵証明書の生成、検証、蓄積、検索な

どに関する機能 Low Level Message Functions Simplified Message Functions

暗号化メッセージの交換形式である PKCS #7メッセージの操作。

CryptoAPI では、サービスプロバイダーを Cryptographic Service

Provider(CSP)と呼んでいる。CSPとしては、表 2-2で示すプリミティブな暗号機能を有する CSPをMicrosoft社が提供しているほか、スマートカードによるサービスを提供する CSPなど、外部ベンダーが提供する CSPが想定される。

表 2-2 標準的な CSP

CSP サービス内容

Base Cryptographic Provider 輸出可能な暗号機能を提供。 Strong CP Windows 2000 以降の OS への適用を可能とする

Base Cryptographic Providerへの拡張。 Enhanced CP より長い鍵と強力なアルゴリズムをサポート。 AES CP AES共通鍵暗号をサポート DSS CP SHA 一方向性ハッシュ関数と DSS デジタル署名

をサポート。 DSS and D-H CP DSS Cryptographic Providerが提供する機能に加

えて、Diffie-Hellman鍵交換をサポート。 DSS and D-H/Schannel CP DSS and Diffie-Hellman CPが提供する機能に加

えて、SSL 3.0及び TLS 1.0のための鍵導出アルゴリズムをサポート。

RSA/Schannel CP SSL 2.0, PCT 1.0, SSL 3.0及び TLS 1.0のための鍵導出アルゴリズムをサポート。

8

2.2.2 Generic Cryptographic Service (GCS) API

Open Groupが推進する GCS-API([GCS-API])も、3層アーキテクチャによって、個別の暗号アルゴリズムや実装からの独立を実現している(図 2-3)。

Application 1

GCS-API Algorithm Indipendent Interface

セキュリティサービス

マネージャー層

アプリケーション層

サービス

プロバイダ層

Cryptographic SupportFacility(CSF)

Application 2 Application 3

Template CC andPopulated CC

Database

Algorithm Specific Interface

DES RSA SHA-1 … Algorithm-nCryptographic Algorithms

図 2-3 Open Group GCS-APIのアーキテクチャ(出典:[GCS-API])

GCS-API におけるセキュリティサービスマネージャー層の実体は、

CSF(Cryptographic Support Facility)と呼ばれる。GCS-APIでは、個別の暗号アルゴリズムや実装は CC(Cryptographic Context)と呼ばれるオブジェクトに対応付けられ、CSFは CCのデータベースを管理する。

CSFの基本的な役割はアプリケーションとCCの間をとりもつメッセンジャーであり、アプリケーションの要求に応えて実装が与えられている暗号アルゴリズムを

特定し、アプリケーションが発行する暗号操作を引き渡す。CSFの典型的な利用手順を以下に示す。

1. アプリケーションは、暗号アルゴリズムを特定する識別名(例えば、

RSA_SIGN_SHA-1)をキーとして、必要な機能をもつ CCを CSFに問い合

9

わせる。 2. CSFは、実装と対応付けられている CCをデータベースから検索し、そのハンドルをアプリケーションに返す。

3. アプリケーションは、得られた CCのハンドルを引数にして、CCに依存しない共通の API関数(例えば、gcs_generate_checkvalue())を呼び出す。

4. CSF は、CC のハンドルから暗号アルゴリズムの実装を特定し、アプリケーションが要求した暗号機能の実行を要求する。

2.2.3 Common Data Security Architecture (CDSA)

同 CDSA([CSSM])は、アプリケーション層とセキュリティサービスマネージャー層との間に Layered Security Service Layerを設けているが(図 2-4)、実質的には 2.1 で述べた 3層アーキテクチャと等価である。

Application in C and C++

CSSM APIセキュリティサービス

マネージャー層

アプリケーション層

サービス

プロバイダ層

Integrity Services

CSP+CtxManager

Layered Services MiddlewareTools Language Interface Adapter

Module Management

TP ModuleManager

AC ModuleManager

CL ModuleManager

DL ModuleManager

ElectiveModule

Manager

SPI TPI ACI CLI DLI EMI

Cryptographic

Service

Provider

Trust Module

Library

Authorization

Com

putationLibrary

CertificateLibrary

Data S

torageLibrary

New

Category

Of S

ervice

図 2-4 Open Group CDSAのアーキテクチャ(出典:[CSSM])

CDSAでは、セキュリティサービスマネージャー層を Common Security Service

Manager Layer(CSSM)と呼び、そのアプリケーションへの界面を CSSM-APIと

10

名付けている。 機能の概念モデルとしては、CSSMは Cryptographic Service Manager、Trust

Policy Service Manager、Certificate Service Manager、Data Store Service Manager、Authorization Computation Service Managerから構成されるものとしている。それぞれのコンポーネントが提供するサービスの定義を表 2-3に整理する。

表 2-3 CSSMのサービス機能

Service Manager コンポーネントから受けるサービス機能

Cryptographic SM 暗号化/復号、メッセージダイジェスト、デジタル署名、MACなどのプリミティブな暗号機能のための APIの提供を行う。

Trust Policy SM ドメイン固有のトラストポリシーに従って、公開

鍵証明書チェインの取得・検証、CRL の検証、証明書の無効化などのための APIを提供する。

Certificate Service Manager 公開鍵証明書と RCLの基本的な操作を行うライブラリへの API の提供を行う。公開鍵証明書の生成、署名、検証、検索、フィールド値の取得な

どの機能を含む。 Data Store SM 公開鍵証明書や CRLなどを格納するためのセキ

ュアなストレージへの API を提供する。アプリケーションによるデータオブジェクトの検索の

機能を含む。 Authorization Computation SM ACL(Access Control List)の機能をもつライブ

ラリへの API を提供する。具体的には、要求されたデータオブジェクトへの操作に関して、操作

の権利を検証するための鍵をアプリケーション

に供給する。権限委譲(delegation)や属性証明書もサポートする。

11

2.2.4 Sun Microsystems Java Cryptographic Architecture

Java Cryptographic Architecture([JCA])においても、3層のアーキテクチャにより、暗号サービスの具体的な実装とアプリケーションの独立を実現している(図 2-5)。

JCAは、具体的な暗号アルゴリズムの実装を提供する実体を CSP(Cryptographic Service Provider)と定義し、CSPの実装を管理するための Providerクラスとシステムに登録される Provider クラスの管理(検索、追加、削除)のための Securityクラスを提供することで、3 層アーキテクチャの基本機能を実現する。また、従来は JSA(Java Security Architecture)の一部であったメッセージダイジェストとデジタル署名の機能、鍵生成の機能と Keyクラスなど、暗号に関わる基本的な部分を取り込んでいる。

Application 1

APIセキュリティサービス

マネージャー層

アプリケーション層

サービス

プロバイダ層

JCA

JCE

JAASCert Path API

SPI

CSP 1 CSP nCSP 2

Application 2 Application n

・・・CSP 3

図 2-5 JCAのアーキテクチャ

Java 2 Platform, Standard Edition, v 1.4(J2SE])では、JCAのフレームワークに基づいて拡張が行われ、Java Cryptography Extension([JCE])、Java Security

12

Socket Extension([JSSE]) 、 Java Authentication and Authorization Service([JAAS])、及び、Java Certification Path API([JPATH])が含まれている(表 2-4)。JCE、JSSE、JAAS、及び、Java Certification Path API は、拡張されたAPIと標準的な実装を提供する。

表 2-4 J2SEを構成する APIの機能

API 機能

Java Cryptographic Architecture (JCA)

CSPに関わるフレームワーク機能(実装の管理、システムへの登録・削除・検索など)に加えて、メッセージダイジェス

トとデジタル署名の暗号の基礎機能を提供する。 Java Cryptographic Extension (JCE)

暗号化/復号、鍵交換、メッセージ認証コードなどの暗号の基礎機能を拡張する。

Java Authentication and Authorization Service (JAAS)

ユーザの認証(Authentication)と認可(Authorization)の機能を提供し、ユーザベース、グループベース、ロールベ

ースのアクセス制御を実現する。 Java Secure Socket Extension

SSL 3.0([SSL3.0])と TLS 1.0([TLS1.0])のセキュア通信の機能を実現する高次の APIで提供する。

Java Certification Path API

公開鍵証明書チェインを操作するための機能を提供する。

13

3 セキュリティ APIで利用される暗号技術とアルゴリズム

この章では、情報セキュリティ技術の専門家向けではない開発者に向け、セキュ

リティ APIの機能についての知識の整理を行う。 文献調査を基に、重要な専門用語と技術内容に関して、セキュリティ APIの利用という観点において必要十分なレベルの解説を行う。また、セキュリティ APIの標準的な CSPの実装がサポートする、具体的な各種アルゴリズムを一覧する。

3.1 公開鍵暗号

3.1.1 公開鍵とプライベート鍵

公開鍵暗号は、[DH]でその存在が予言され、[RSA]によって初めて発見された。公開鍵暗号は、次の 2つの性質を満たす暗号として特徴付けられる。

1. 暗号化に用いる鍵と復号に用いる鍵が異なる。 2. 暗号化に用いる鍵から復号に用いる鍵を計算することは困難である。 公開鍵暗号は、暗号化の鍵を公開しても復号の鍵は秘匿されるという特質を活用

して、積極的に暗号化鍵を公開することで、従来の暗号利用のメソドロジーを変革

し、暗号利用の全く新しいメリットを提供することとなった([DH])。特に、インターネットなど公衆のネットワーク上で不特定多数のユーザ間で秘匿通信を行うア

プリケーションでは、必須のキー技術となっている。 公開鍵暗号における暗号化鍵を公開鍵(public key)、対応する復号のための鍵をプライベート鍵(private key)とよぶ。プライベート鍵は個人鍵、秘密鍵、私用鍵、私有鍵などと呼ばれることも多いが、本報告書ではプライベート鍵という呼称を一貫

して用いる。また、互いに対応する公開鍵とプライベート鍵とのペアを公開鍵ペア

と呼ぶ。 [DH]以降、公開鍵とプライベート鍵の具体的な構成法に関して多くの提案がなされたが、現時点で安全と認められ実用に供されているものは、RSA公開鍵暗号における構成法と、Diffie-Hellman鍵交換における構成法の 2つである。

3.1.2 RSA 公開鍵暗号における鍵の構成

RSA公開鍵暗号、RSA鍵交換、RSA署名などの暗号スキームは、以下に示す公開鍵ペアの構成法を共有する。

14

n = pq nは公開の合成数、p,qはそれぞれ秘密の素数

ed = 1 mod (p – 1)(q – 1 ) eは公開鍵、dはプライベート鍵

p, qが分かっている時には、Euclid互除法により公開鍵 eからプライベート鍵 dを効率的に計算することができる。一方、p, qが与えられていない時には、公開鍵 eからプライベート鍵 dを計算することと、nを素因数分解して p, qを求めることとは、実は同じであることが知られている。下記の囲み記事は、公開鍵 eの値が小さい場合に、プライベート鍵 dの計算と nの素因数分解とが同値であることの証明である1。

公開法数 n と公開鍵 e からプライベート鍵 dを求めることが出来たと仮定すると、以下のように n

を素因数分解することができる。

ed = 1 mod (p – 1)(q – 1 )より、ed – 1は(p – 1)(q – 1 )で割り切れる。

一方、0 < d < (p – 1)(q – 1 ) とすると、0 < ed – 1 < e(p – 1)(q – 1 )が成り立つので、ai = (ed – 1)/i (i = 1, …, e – 1)のいずれかは、ai = (p – 1)(q – 1 )を満たす。

ai – n – 1 = – (p + q) より、p,qは二次方程式 x2 + (ai – n – 1)x + n = 0 の 2根となる。

「n が十分大きい時には n の素因数分解は計算量的に不可能である」ことが数学の長い歴史によって証言されていることから、公開鍵からプライベート鍵を計算す

ることは現実的には不可能であると考えられている。 公開鍵暗号を構成する上では、公開鍵からプライベート鍵が計算できないことが

最も重要な要件であるが、RSA公開鍵暗号の鍵の構成では、法数 nの素因数分解を秘密にしておける限り、プライベート鍵の安全は保証される。これが、「RSA 公開鍵暗号は素因数分解の困難性に安全性の根拠を置いている」とされる所以の一端で

ある2。

3.1.3 Diffie-Hellman 鍵交換における鍵の構成

特定の有限群では、群に含まれる要素の数が十分に大きくなると、その群の上で

1公開鍵 eの値が大きい時には、p,qを見つけ出す確率的アルゴリズムが存在する。 2ここで述べたように、プライベート鍵を導出する、所謂、total breakに対する RSA公開鍵暗号の安全性は、法数 nの素因数分解の困難性に帰着される。一方、RSA公開鍵暗号が「プライベート鍵を用いずに復号できる暗号文は確率的に無視しえるほど少ない」ことを求める安全性を満足しているかについては、それ自体が RSA予想と呼ばれる仮説である。RSA予想は、素因数分解の困難性に帰着されることが予想されているものの、証明は見つかっていない。

15

の離散対数問題(Discrete Logarithm Problem, DLP)の解決が計算量的に不可能になると考えられている。

素数 pを法とした離散対数問題

与えられた y と gから、y = gx mod p を満足する xを求めよ。

Diffie-Hellman鍵交換([DH])では、特定の群の上では離散対数問題が困難であるという性質を利用して、群の要素を公開鍵としその離散対数をプライベート鍵と

して公開鍵ペアを定義する。

法数pの場合では、y = gx mod pを満足する x, yに対して、yを公開鍵、xをプライベート鍵とする。

Diffie-Hellman 鍵交換と同じ鍵の構成法を取るアルゴリズムとしては、DSA(Digital Signature Algorithm, [DSS])などがある。 また、離散対数問題が困難であるとされる有限群としては、素数 pを法とし乗算を演算とする群(素体の乗法群)と楕円曲線とが知られており、実用上も公開鍵暗

号のベースとして利用されている。

3.1.4 RSA 公開鍵暗号

広義には、公開鍵暗号は後述する鍵交換やデジタル署名を含み、多くのアルゴリ

ズムが実用に供されている。一方、メッセージを公開鍵で暗号化しプライベート鍵

で復号するという狭義の意味で考えるならば、RSA公開鍵暗号([RSA])が公開鍵暗号の実質的な標準である。

RSA公開鍵暗号のアルゴリズムは[PKCS1]に定義が与えられている。

3.1.5 安全性証明付き公開鍵暗号と OAEP

[BLE]により、選択暗号文攻撃(Chosen Ciphertext Attack)の脅威が俄かに現実味を帯びてきた。[BLE]は、PKCS #1 v1.5([PKCS1v1.5])のパディングアルゴリズムの「欠陥」を利用することで、選択暗号文攻撃による RSA 公開鍵暗号のプライベート鍵の探索が可能であることを示している。SSLサーバーなどに勝手に生成した暗号文を送ると、サーバーは復号した結果が PKCS #1 v1.5のパディングに従っていない場合にエラーを返す。攻撃者は、暗号文を適切に選択してサーバーに

送ってエラーの発生を観察することで、プライベート鍵の存在範囲を狭めていくこ

とが可能であるというのが[BLE]の報告内容である。 [BLE]が発端となって、選択暗号文攻撃に対する安全性が証明できる暗号方式の

16

研究が進展した。特に、OAEP(Optimal Asymmetric Encryption Padding)は、パディングのフォーマットを工夫することで、RSA 公開鍵暗号が Plain Text Awarenessと呼ばれる安全性のクライテリアを満足することを示した3。OAEPは、インターネット上のセキュアなクレジットカード決済のためのプロトコルである

SET(Secure Electronic Transactions, [SET])にも採用されている。 OAEPは、他の多くの安全性証明可能暗号方式と同じく、ランダムオラクルモデ

ルに基づいている。即ち、安全な一方向性を有する擬似乱数関数 g(x)と h(x)の存在を仮定して、以下のように定義される。実際には、g(x)と h(x)は、SHA-1 のような一方向性ハッシュ関数を用いて構成される。

OAEP(m) = s | t mはゼロパディングされたメッセージ

s = m XOR g(r) rはメッセージごとに都度生成される乱数

t = r XOR h(s)

復号の際には m のパディングが再現されていること(復号されたメッセージの最後に指定された

長さのビット 0が続くこと)を検証する

3 [BLE]では、OAEPにより、任意の落し戸付一方向性関数が証明可能な安全性をもつ暗号関数として利用できるとしたが、[SH]によりその証明に誤りがあることが指摘され、反例が示された。しかし、[FOPS]により、RSA関数の場合は OAEPが有効であることが示されている。

17

3.2 鍵交換

鍵交換は、通信の当事者相互で秘密裏に鍵を交換するための機能であり、仮に通

信経路が安全でないとしても(通信が盗聴されていても)、第三者には交換された鍵

が漏洩しないことを要求する。 鍵交換は認証及びセキュア通信においてキーとなる機能である。認証においては

正しく鍵を共有できた事実を確認することで相手を正しい通信相手を認識する。ま

た、セキュア通信では、メッセージは共通鍵暗号(0)で暗号化されたり、また、メッセージ認証コード(0)が添付されて交換されるので、通信の当事者相互で同一の秘密鍵を使用しなければならない。 セキュリティ APIで利用される鍵交換アルゴリズムには、大きく、公開鍵暗号に

よる鍵交換とパスワードからの鍵導出(password-based key derivation)のふたつの手法がある。

3.2.1 公開鍵暗号による鍵交換

公開鍵暗号ベースの鍵交換の原理的アルゴリズムとしては、公開鍵の構成法の分

類に対応して、RSA鍵交換と Diffie-Hellman鍵交換[DH]とが利用される。

(1) RSA 鍵交換

RSA公開鍵暗号を用いた鍵交換は、Needham-Schroeder認証と呼ばれる鍵交換アルゴリズムに基づいており、[SSL3.0]、[TLS1.0]、及び、[TLS1.1]においてもサポートされている。

Needham-Schroeder認証では、Aliceと Bobの双方で共有するべき秘密情報をランダムに生成し、相手の公開鍵で暗号化して送付する。オリジナルの

Needham-Schroeder 認証では、復号した秘密情報を再度相手の公開鍵で暗号化して送付することで認証を実現していたが、この方法には正当なユーザを復号オラク

ルとして濫用する攻撃法があることが発見されている。そのため、SSL などでは、秘密情報を再送付するのではなく、秘密情報に対する一方向性ハッシュ値を送付す

ることで秘密情報を知り得たことを証明する方法をとる。 図 3-1では、秘密情報の共有の確認手段として一方向性ハッシュ関数を用いる原

理的な例を示す。

18

Alice

乱数rAを生成Bobの公開鍵で

rAを暗号化 =EB(rA )

rBを復号k = rA | rBを共有

ハッシュ関数h()からh(k | “Alice”)を計算

受信したハッシュを検証

Bob

rAを復号乱数rBを生成

Aliceの公開鍵でrBを暗号化 =EA(rB )

rA | rBを共有

ハッシュ関数h()からh(k | “Bob”)を計算

受信したハッシュを検証

EB(rA )

EA(rB )

h(k | “Alice”)h(k | “Bob”)

図 3-1 RSA鍵交換の例

(2) Diffie-Hellman 鍵交換

離散対数問題の困難性に基づいて定義される公開鍵ペアによる鍵交換である。 Alice と Bob が鍵交換をする場合を考える。Alice と Bob とは、それぞれ、下式を満たす公開鍵ペア(yA, xA)と(yB, xB)を保持する。ただし、yAと yBは公開鍵であり、

xAと xBはプライベート鍵であるとする。

yA = gxA mod p

yB = gxB mod p

Aliceと Bobは、公開鍵 yAと yBとを交換し、下式に従って鍵 kを共有する。

k = yB xA mod p = yA xB mod p

実際に、Diffie-Hellman鍵交換アルゴリズムに従って鍵交換を行う際には、Aliceと Bobが都度使い捨ての公開鍵ペアを生成する方法(ephemeral key)と、固定の公開鍵ペアを使用する方法の 2つがある。 認証目的で鍵交換を行う場合には、前者では Aliceと Bobは使い捨ての公開鍵を

19

生成し、使い捨ての公開鍵に署名して検証用の公開鍵証明書とともに相手に送付す

る。後者では、公開鍵証明書を交換し、証明書に記載される公開鍵を使用して共有

鍵を計算する。SSL 3.0([SSL3.0)では、Diffie-Hellman鍵交換に用いる公開鍵として、使い捨てと固定の両方をサポートしている。

Diffie-Hellmanによる二者間の鍵交換を敷衍して、3名以上のユーザ間での鍵交換を実現することができる。JCEでは、n者間での鍵交換をサポートしている。

KEA(Key Exchange Algorithm, [FOR])は、FORTEZZAで規定されている鍵交換アルゴリズムであるが、Diffie-Hellman鍵交換アルゴリズムをベースとしている。

表 3-1 公開鍵に基づく鍵交換アルゴリズム

アルゴリズム名 説明

RSA-KX [SSL3.0]などにより規定。 Diffie-Hellman-KX 素体の乗法群、または、楕円曲線の上で定義される

Diffie-Hellman鍵交換。[PKCS3]により規定。 KEA NIST により規定された([FOR])。Diffie-Hellman 鍵交

換アルゴリズムをベースとする。当初アルゴリズム仕様

が公開されなかったが、現在は仕様が公開されている

([SJKEA])。

3.2.2 パスワードからの鍵導出

共通鍵暗号でメッセージを暗号化するセキュアな通信では、通信者相互で、メッ

セージを暗号化し復号するための鍵を共有しなければならない。公開鍵暗号による

鍵交換とハイブリッド暗号(電子封書)を利用すれば、郵便・電話・メールなどプ

ロトコル外の手段で鍵を交換する手続きをユーザに要求することなく、通信プロト

コルの機能の一部として鍵交換を実行することができる。しかしながら、公開鍵証

明書を事前に取得するなどのセッティングが必要であることもまた事実であるため、

簡便に利用できるパスワードによる鍵交換は今なおその有用性を失わない。 また、公開鍵暗号を利用する場合であっても、ローカルなレポジトリに格納され

るプライベート鍵へのアクセスは、最終的にはユーザのパスワードによる認証に基

づくことになるのが通常である。 このような事情から、パスワードから共通鍵暗号(0)やメッセージ認証コード(0)の鍵を導出するアルゴリズムは、実用上、広い適用範囲をもつ。 パスワードからの鍵導出には、パスワード空間の狭さに起因する課題が存在する。

[PKCS5]では、この課題に対抗するために saltと iteration countとによる対策を講じている。

事前計算攻撃に対抗する salt

20

パスワードの空間は狭いことから、固定した平文に対する暗号文のテーブル

を事前計算し、通信の傍受内容からパスワードを逆引きする攻撃を実用的な

コストで実行することが可能である。即ち、攻撃者は、交換されることが期

待される平文を複数のパスワードで暗号化して、暗号文をエントリーとして

もつテーブルを事前計算する。攻撃者は、入手した暗号文とテーブル中のエ

ントリーを比較し、両者が一致した場合パスワードを逆引きする。 この攻撃に対抗するために、鍵を導出する際に、一定以上の長さをもつ乱数

saltをパスワードと共に入力とする。例えば、パスワードと saltとを連接したバイト列に対して一方向性ハッシュ関数を施し、その結果を鍵とする。パ

スワードの空間は狭くとも、salt の効果により導出される鍵の空間は十分に広くなるので、事前計算攻撃のメリットは無効化もしくは減殺される。 salt は暗号化されず平文で交換されるので、受信者はパスワードだけを知っていれば、鍵を導出することができる。

鍵全探索攻撃に対抗する iteration count salt により事前計算による効率的な攻撃を防止するが、salt 自身は平文で交換されるため、通信傍受後に鍵を全探索する攻撃は依然として有効である。

例えば、傍受の結果得られた saltと解析用の「辞書」に登録されたパスワードとから鍵を導出し、傍受した暗号文から意味のある平文が復号されるまで、

パスワードを取り替えて復号を繰り返す。 この攻撃に対抗するために、鍵導出に用いる一方向性ハッシュ関数や擬似乱

数関数の適用回数(iteration count)を多くすることで鍵導出のコストを大きくし、結果として、全探索攻撃のコストを耐えがたいものとする方法をと

ることができる。[PKCS5]では、適切な iteration countとして 1000以上を推奨している。

PKCS #5 v2.0([PKCS5])では、PBKDF1と PBKDF2の 2つの鍵導出アルゴリズムを規定している(表 3-2)。

(1) PBKDF1

PBKDF1は PKCS #5 v1.5との互換性のために規定されているもので、新規に開発されるアプリケーションでは PBKDF2 を利用することが推奨されている。使用される一方向性関数は、MD2([MD2])、MD5([MD5])、SHA-1([SHA1])のいずれかであり、導出される鍵の長さが 16バイト以下(MD2或いはMD5の場合)或いは 20バイト(SHA-1の場合)以下に制約される。

21

(2) PBKDF2

PBKDF2では、導出される鍵の長さに関して、実用的な意味では、制限を設けない。従って、十分に長い鍵を導出して、そこから任意個数の鍵を分割・生成し、

イベント毎に鍵を変えたり(例、read_key と write_key)、時間経過に伴って鍵を変えるなどの処理を可能とすることができる。

表 3-2 パスワードからの鍵導出アルゴリズム

アルゴリズム名 説明

PBKDF1 鍵導出のための一方向性ハッシュ関数として、MD2([MD2])、MD5([MD5])、及び、SHA-1([SHA1])を指定。導出される鍵は 16バイト以下(MD2及びMD5の場合)、或いは、20バイト以下(SHA-1の場合)に制限される。

PBKDF2 PBKDF1 との差は、一方向性ハッシュ関数の代わりにより安全性の高い擬似乱数関数を用いている点、導出される鍵の

長さに実質的な制限がない点の二点である。利用する擬似乱

数関数に制限はないが、[PKCS5]では擬似乱数関数としてHMAC-SHA-1を例として規定している。HMAC-SHA-1のケースでは、出力は(232 – 1)×20バイトを上限として任意に指定可能である。

22

3.3 共通鍵暗号

共通鍵暗号は、暗号化と復号に共通の鍵を用いる暗号方式である。共通鍵暗号と

対照をなす公開鍵暗号が、暗号化と復号に異なる鍵を用いることから、この名称で

呼ばれる。公開鍵暗号に比べ、古くから利用されていることから、慣用暗号という

呼称も広く用いられている。

3.3.1 ブロック暗号とストリーム暗号

ブロック暗号とストリーム暗号の区別は実用的なもので、理論的には明確な区別

はない。ストリーム暗号は計算機による処理に適したデータサイズ(ビット、バイト、

ワード等)を単位として変換(暗号化及び復号)を実行する暗号方式であり、ブロ

ック暗号は、入力データをブロックと呼ばれる比較的大きなサイズ(64、128、256バイトなど)の塊に分解し、ブロックを単位として変換を実行する暗号方式である。

3.3.2 ブロック暗号の利用モード

ブロック暗号の利用モードは、当初、NISTにより DES([DES])の利用モードとして制定されたが(FIPS PUB 81 [DES Mode])、現在では任意のブロック暗号に適用される。 セキュリティ APIの標準的な実装では、[DES Mode]に規定される4方式に加え、以下の 5方式が利用される(表 2-1、表 3-3)。

表 3-3ブロック暗号の利用モード

利用モード 説明

ECB Electronic CodeBook。[DES Mode]により規定。 CBC Cipher Block Chaining。[DES Mode]により規定。 CFB Cipher FeedBack。[DES Mode]により規定。 OFB Output FeedBack。[DES Mode]により規定。 PCBC error-Propagating Cipher Block Chaining。Kerveros 4により規定。

(1) ECB

最も基本的な利用モードである。 暗号化においては、パディング(3.4.1)によりブロック長の整数倍に整えられた平文データをブロックに分解し、各平文ブロックに暗号化関数を施す。更に、得ら

れた暗号文ブロックを平文ブロックと同じ順に再構成して、暗号文データを得る。 同じ平文ブロックは同じ暗号文ブロックに変換されることから、攻撃者は、暗号

文を比較して、もととなる平文の一致・不一致の情報を得ることができる。

23

(2) CBC

各平文ブロックと直前の暗号文ブロック(平文ブロックが最初である場合にはイ

ニシャルベクタ)とのビット毎排他的論理和(XOR, Exclusive OR)を計算し、その結果に暗号化関数を施して暗号文ブロックとする。

CBCモードの本来の狙いは、平文データ中に等しい平文ブロックが複数現れる場合であっても、生成される暗号文ブロックを異なるようにすることにあり、暗号文

を観察する攻撃者が等しい平文ブロックを同定できないようにする点にある。 CBCモードは以下の性質をもつ。

1. ひとつの暗号ブロックが正しく受け取られない場合、その暗号ブロックに対応する平文ブロックと、その直後の平文ブロックの 2 つのブロックだけが正しく復号されない。

2. 暗号処理中に異なる平文ブロックが入力されると、以降の平文ブロックが全て同一であっても、問題の平文ブロック以降、出力される暗号文ブロッ

クは異なる。 1の性質は、通信中のエラー混入に対して耐性があると評価することもできるが

(エラーが発生したブロックの2ブロック後からは回復する)、他の部分に影響を及

ぼさずに暗号文の一部差し替えが可能であるとネガティブに考えることもできる。

PCBCはこの点を改善したものである。 2の性質は、CBCモードのブロック暗号を利用してメッセージ認証コードの生成関数を構成する際の根拠となる(3.7.1)。

(3) CFB と OFB

ともにブロック暗号をストリーム暗号として用いるためのモードである。 CFB と OFB の違いは、暗号化関数の入力レジスタへのフィードバック(r ビット)として、直前の暗号文を用いるか、直前の暗号化関数の出力を用いるかの違い

である。

(4) PCBC

CBCモードにおいて、直前の暗号文ブロックに加え、直前の平文ブロックともビット毎排他的論理和をとってから暗号化関数に入力する。 直前の平文ブロックを暗号化関数の入力に加えることにより、ある暗号文ブロッ

クが通信経路上で差し替えられた場合、受信者は以降の暗号文ブロックを正しく復

号することはできなくなる。これが、error-Propagating と呼ばれる所以であり、PCBCは CBCが持つ弱点を補強することが目的である。

24

暗号文ストリーム

平文ストリーム

暗号文

平文

暗号文

平文

Ekey

m1

c1

E

c2

E

ck

IV

m2 mk

Ekey

m1

c1

E

c2

E

ck

IV

m2 mk

IV ‥

Ekey

mk ck

IV

(a) CBCモード (b) CFBモード

(d) PCBCモード

暗号文ストリーム

平文ストリーム

Ekey

mk ck

IV

(c) OFBモード

図 3-2 ブロック暗号の利用モード

3.3.3 パスワードに基づく共通鍵暗号

PBE(Password-Based Encryption)は、PBKDF1や PBKDF2によりパスワードから導出された鍵を用いる共通鍵暗号である。

[PKCS5]には、PBES1と PBES2の 2つの方式が規定されている。

(1) PBES1

PBKDF1により導出される鍵を、CBCモードの RC2或いは DESに適用する方式の規定である。PBKDF1 では、16 バイト長の鍵をパスワードから導出することができるので、その先頭 8バイトを暗号化鍵(復号鍵)に、続く 8バイトをイニシャルベクタに利用する。

(2) PBES2

PBKDF2により導出される鍵を、任意の共通鍵暗号アルゴリズムに適用するためのフレームワークを定めたものであり、共通鍵暗号アルゴリズムの指定や、暗号化

25

鍵やイニシャルベクタの計算方法については何も規定していない。 [PKCS5]では、例として、DES-CBC、DESEDE2-CBC、RC2-CBC、RC5-CBC

への適用を規定している。

表 3-4 PBEアルゴリズム

アルゴリズム名 説明 PBES1 PBKDF1 により導出する鍵による共通鍵暗号。RC2-CBC

と DES-CBCへの適用が[PKCS5]により規定されている。PBES2 PBKDF2により導出する鍵を任意の共通鍵暗号アルゴリズ

ムに適用するフレームワーク。[PKCS5]では、DES-CBC、DESEDE2-CBC、RC2-CBC、RC5-CBCへの適用を規定している。

3.3.4 セキュリティ API で利用される暗号アルゴリズム

表 3-5は、セキュリティ APIの標準的な CSPでサポートされる主要なブロック暗号及びストリーム暗号をまとめたものである。

表 3-5共通鍵暗号アルゴリズム

アルゴリズム

名 ブロック長 (ビット)

鍵長 (ビット)

説明

AES 128 128, 192, 256,

DES の後継として Rijndeal アルゴリズムに基づいて開発されたものであ

り、[AES]により米国で標準化されている。

BLOWFISH 64 32~488 CAST 可変 可変 段数も可変。64 ビットブロック、128

ビット鍵、16 段処理を行う CAST-128が一般的に使用される。

CDMF 64 40 DES 56 ビット鍵中にパリティビットを埋め込むことで、輸出可能な 40ビット鍵に縮小する。

DES 64 56 [DES]により米国で標準化されている。

26

アルゴリズム

名 ブロック長 (ビット)

鍵長 (ビット)

説明

DES-EDE 64 112 168

DESによる暗号化/復号を3回繰り返すため、Triple-DES とも呼ばれる。金融機関で使われてきた他、米国において

は、寿命を迎えた DESと AESとの間隙を埋めるために米国において標準化

された経緯がある([X9.52])。 112 ビットの鍵を用いる DES-EDE2と 、 168 ビ ッ ト の 鍵 を 用 い る

DES-EDE3の 2つが利用される。 112 ビットの鍵を用いる方式は[DES EDE]によって標準化されている。

IDEA 64 128 PGPで採用されている。 PBE

- - パスワードから導出した鍵を用いる暗

号方式。[PKCS5]に規定されている以外にも以下が利用される。 PBEWithMD5AndCast: 一方向性ハッシュ関数に MD5、共通鍵暗号に CASTを指定 PBEWithSHA1AndCast: 一方向性ハッシュ関数に SHA1、共通鍵暗号に DESを指定

RC2 64 1~1024 RCシリーズは RSA DSI社が開発した共通鍵暗号。

RC4 - 1~2048 ストリーム暗号に分類される。 RC5 16, 32, 64 1~256 ブロック長(w ビット)、鍵長(b バイ

ト)、段数( r 段)のすべてが可変([RC5])。RC5-w/r/bと指定されるが、RC5-32/12/16の仕様が推奨されている。

SKIPJACK 64 80 NISTにより規定された([Skipjack])。当初アルゴリズム仕様が公開されなか

ったため議論を呼んだが、現在は仕様

が公開されている([SJKEA])。

27

3.4 パディングアルゴリズム

3.4.1 ブロック暗号のためのパディングアルゴリズム

ブロック暗号による暗号化では、入力となる平文メッセージに適当な長さのパデ

ィングストリング(Padding String)を接合して、入力のバイト長をブロック長のバイト長の整数倍に整えた後、暗号化を行う。逆に、暗号文を復号する場合には、

復号して得られた最後の平文ブロックからパディングストリングを取り除き、オリ

ジナルの平文メッセージを復元する。 パディングアルゴリズムは、復号時にパディングストリングを一意に特定できる

ようなパディングストリングの生成方法を定める。表 3-6では、セキュリティ APIで利用されるブロック暗号のためのアルゴリズムを示す。

表 3-6 ブロック暗号のためのパディングアルゴリズム

アルゴリズム名 説明

PKCS #5-Padding [PEM]及び[PKCS3]で規定されたパディングアルゴリズム。ブロック長は 8バイトに固定。

SSL-Padding [SSL3.0]及び[TLS1.0]で規定されるパディングアルゴリズム。ブロック長は 256バイトまでの可変長である。

PKCS #5-Padding、SSL-Paddingのいずれも以下の特徴を有する。

ブロックを bバイト、メッセージを mバイトとする時、パディングの結果得られるバイト列の長さ lは以下のように計算される。

l = ([m /b] + 1) ×b

但し、[m /b]は m /bの整数部(m /bを超えない最小の整数)とする。

特に、mが bで割り切れる時には、l = m + b となり、パディングだけのブロックが追加されることに

注意。

また、PKCS #5-Paddingでは b = 8に固定されるが、SSL-Paddingでは b は 256

以下の任意の値を取ることが許される。 b = 8 の時でも、PKCS #5-Padding と SSL-Padding とは一致しない。PKCS

#5-Padding では l – m を値に持つバイトによりパディングされるのに対し、SSL-Paddingでは l – m – 1を値に持つバイトによりパディングされるからである。

28

3.4.2 公開鍵暗号のためのパディングアルゴリズム

共通鍵暗号におけるパディングの主要な目的が、平文メッセージを暗号に適した

長さに調整する点にあったのに対し、公開鍵暗号におけるパディングの目的は以下

の 2点にある。

暗号文に乱数性を持たせる 暗号化処理が正しく行われたことを確認する手段を設ける

第 1の目的は、暗号化処理の実行者に制限がないという公開鍵暗号の特質に起因する。プライベート鍵を持たない攻撃者が暗号文そのものを解読することは困難で

あるとしても、平文の候補が絞られているようなケースでは、候補となる平文を暗

号化して暗号文と比較することで平文を特定することは可能である。暗号化に必要

な公開鍵へのアクセスに制限を仮定しないからである。このような攻撃を避けるた

めに、同じ平文を暗号化する場合でも、暗号文が処理の都度ランダムに変化する機

能をパディングによって与える。 第 2の目的は、不正に作成された暗号文を排除する点にある。 例えば、RSA署名ではメッセージのハッシュ値を署名鍵で暗号化することで署名値を生成するので、攻撃者がメッセージのハッシュ値を暗号化メッセージに見せか

けて送付して相手に復号させることにより、復号の実行者の関知の埒外で RSA 署名を生成させることができてしまう。 具体的には、暗号化の前にパディングによって平文メッセージに特定の「マーク」

をつけることを義務づけ、復号処理に際して「マーク」が復元されなかった場合に

は、不正な暗号文として復号結果を破棄する方法で実現される。これにより、復号

の実行者は正規の暗号文とハッシュ値とを区別することができるので、暗号文に見

せかけてハッシュ値を送付する攻撃を回避することが可能となる。 [PKCS1v1.5]では、上記の目的に適合し、RSA公開鍵暗号に適用可能なパディン

グアルゴリズムを規定している。[PKCS1v1.5]によるパディングアルゴリズムは、3バイトの固定バイト(マーク)と 8バイト以上の乱数バイトを平文メッセージに追加するという単純なものである。

一方、[PKCS1v1.5]のような単純なパディングアルゴリズムでは、選択暗号文攻撃を許す危険性があることが指摘され([BLE])、パディングアルゴリズムに選択暗号文攻撃に対する耐性が求められるようになった。[PKCS1]で規定されているOAEP(0)は、暗号文の乱数性と暗号文の検査の機能を与えた上で、[PKCS1v1.5]で規定されていたパディングアルゴリズムの脆弱性を修正し、選択暗号文攻撃に対

29

して証明可能な安全性を提供する。

表 3-7 公開鍵暗号のためのパディングアルゴリズム

アルゴリズム名 説明

EME-PKCS-v1_5 3 バイトの固定値と 8 バイト以上の乱数とからなるバイト列をメッセージに接合する単純なパディング方式。

[PKCS1v1.5]で RSA公開鍵暗号への適用として規定。 OAEP Optimal Asymmetric Encryption Padding。擬似乱数関数

を使って、メッセージをマスクするパディング方式。

[PKCS1]で RSA公開鍵暗号への適用として規定。

30

3.5 一方向性ハッシュ関数

ハッシュ関数とは、任意長のバイト列を入力として受け取り、固定長のバイト列

を出力する関数と定義される。更に、ハッシュ関数 H(x)が一方向性を有するとは、ハッシュ関数の出力の衝突を見つけることが困難であることと定義される。

H(a) = H(b) を満足する互いに異なる入力の組 (a, b)を見つけ出すことは計算量的に困難であ

る。出力が同じになる入力の組を衝突と呼ぶ。

ハッシュ関数が一方向性を有していれば、以下の性質も満足する4。

与えられた hに対して、H(a) = h を満足する入力 aを見つけ出すことは計算量的に困難である。

一方向性ハッシュ関数の最も重要な適用は、デジタル署名とメッセージ認証コー

ドであるが、一方向性はこれらの適用における安全上の要となる。 例えば、RSA署名では、メッセージに一方向性ハッシュ関数を施してハッシュ値を計算し、得られたハッシュ値を署名鍵で暗号化することで署名値を生成する。一

方向性ハッシュ関数が満足する上記の 2つの性質により、次のような偽造行為が防止される。

同じハッシュ値をもつふたつのメッセージを作成し、第一のメッセージに署名させ、その署名値を第二のメッセージの署名に転用する。

既存の署名付きメッセージを入手して、オリジナルのメッセージと同じハッシュ値をもつメッセージを見つけ出し、オリジナルの署名値を第二のメッセ

ージの署名に転用する。 また、[MD5 MAC]のようなメッセージ認証コードアルゴリズムでは、メッセージに鍵を埋め込んでハッシュ値を計算し、その値をメッセージ認証コードとして利

用する。ハッシュ関数が一方向性を有していないとすると、短いメッセージに対す

るメッセージ認証コードから鍵が逆算される。 現時点で利用されている一方向性ハッシュアルゴリズムとしては、RSA DSI社が開発したMDシリーズ(MD2、MD4、MD5)と、MD4のデザインをベースに NIST

4 正確には、ハッシュ関数の一方向性は、衝突(collision)と preimageの計算困難性として段階的に定義される。collisionと preimageは、実用の一方向性ハッシュ関数(または圧縮関数)はニシャルベクターを入力としてとることから、イニシャルベクタ(IV)の一致・不一致もパラメータにいれて更に細かく定義される([HandBook, Note 9.95])。具体的には、発見のための計算が難しい順に、preimage, 2nd-preimage, collision-fixed-IV、collision-random-IV, pseudo-collisionが定義される。本稿では、collision-fixed-IVが計算不可能であることを一方向性の定義とし、一方向性が満足された時には preimageが計算不可能であることを性質として述べている。

31

(National Institute of Standards and Technology)が開発した SHA及び SHA-1がある。

表 3-8 一方向性ハッシュアルゴリズム

アルゴリズム名 説明 MD2 16 バイトのハッシュ値を出力。[MD2]により規定。有効な

衝突が発見されているため、ほとんど利用されない。 MD4 16 バイトのハッシュ値を出力。[MD4]により規定。以降の

一方向性ハッシュ関数の基本構造を提示した点で歴史的意

味があるが、有効な衝突が発見されているため5、ほとんど

利用されない。 MD5 16 バイトのハッシュ値を出力。[MD5]により規定。圧縮関

数に弱い衝突6が発見されているが、現在でも広く利用され

ている。 SHA 20 バイトのハッシュ値を出力。[SHA]により規定。SHA-1

の前のバージョンであり、SHA-1 以前に開発されたシステムとの互換性のためにサポートされる。

SHA-1 20 バイトのハッシュ値を出力。[SHA1]により規定。SHAに技術的改良を加えたもので、現在では SHA に代わってSHA-1が利用される。SHAの表記で SHA-1を指すケースもあり、注意が必要。

SSL3-SHAMD5 [SSL3.0]及び[TLS1.0]で利用される一方向性ハッシュアルゴリズム。MD5によるハッシュ値(16バイト長)と SHA-1によるハッシュ値(20バイト長)とを接合してハッシュ値とすることで、一方のアルゴリズムへの依存性を弱めてい

る。

MD4 以降の一方向性ハッシュ関数は、圧縮関数と呼ばれるプリミティブな関数を多段に繰り返してハッシュ値を計算する繰り返し構造(iterated construction)を取っている。圧縮関数は、固定長のイニシャルベクタ(MD5では 128ビット、SHA-1 5 MD4 では圧縮関数に入力されるメッセージブロックは 128ビットなので、衝突の計算に必要な試行回数の理論的加減は、Birthday Attackによる 264である。しかし、実際には、220回の計算で衝突を発見する方法が知

られている。 6 MD5の圧縮関数に対して、イニシャルベクタを取り替えてもよいという条件のもとでの衝突であるcollision-random-IVが発見されている。MD5では、固定のイニシャルベクタを用いるので、collision-fixed-IVより弱い collision-random-IVの発見が、直ちにMD5の安全性を脅かすものではない。

32

では 160 ビット)と固定長のメッセージブロック(MD4 と SHA-1 では 512 ビット)を入力としてとり、イニシャルベクタと同じ長さの値を出力する(MD5 では128ビット、SHA-1では 160ビット)。圧縮関数の出力はイニシャルベクタとして次段の圧縮関数に入力される(図 3-3)。

平文

圧縮関数

圧縮関数

圧縮関数

IV ‥

m1 m2 mk

Hash Value

図 3-3 一方向性ハッシュ関数の繰り返し構造

33

3.6 デジタル署名

デジタル署名はメッセージへの署名者の認証と否認拒否の 2つの機能を提供する。否認拒否とはメッセージの署名者が署名の事実を後で否認することができないこと

を意味する。 デジタル署名に関しては多くのアルゴリズムが提案されているが、現在は、RSA(Rivest-Shamir-Addleman)署名と DSA(Digital Signature Algorithm)署名が主流である。RSA署名は RSA公開鍵暗号における鍵の構成法に基づいており、DSA署名は Diffie-Hellman鍵交換における鍵の構成法に基礎を置いている。

3.6.1 RSA 署名

RSA 署名は、メッセージに対する一方向性ハッシュ値を、RSA 公開鍵暗号のプライベート鍵(署名鍵)で暗号化したデータを署名データとするもので、MD2、MD5、SHA、SHA-1 などの多様な一方向性ハッシュアルゴリズムと組み合わせて利用される。 検証は、署名データを公開鍵(検証鍵)で復号した結果と、署名対象のメッセー

ジの一方向性ハッシュ値との一致を検査することで実行される。

表 3-9 デジタル署名アルゴリズム

アルゴリズム名 説明 RSA-MD2 MD2によるハッシュ値を RSA署名鍵で暗号化 RSA-MD5 MD5によるハッシュ値を RSA署名鍵で暗号化 RSA-SHA SHAによるハッシュ値を RSA署名鍵で暗号化 RSA-SHA1 SHA-1によるハッシュ値を RSA署名鍵で暗号化 SSL3-DS SSL3-SHAMD5によるハッシュ値を RSA署名鍵で暗号化 実際には、署名鍵で暗号化する前に、ハッシュ値は所定の方法で符号化される。 現在、広く利用されている符号化方式としては、PKCS #1 v1.5([PKCS1v1.5])

が規定する EMSA-PKCS1-v1_5と、PKCS #1([PKCS1])が規定する EMSA-PSSがある。

(1) EMSA-PKCS1-v1_5

メッセージのハッシュ値と利用したハッシュアルゴリズムの識別子とを、DERにより符号化したデータ(DigestInfo)の先頭に、11バイト以上の固定バイトを付加する。

34

DigestInfo ::= SEQUENCE {

digestAlgorithm AlgorithmIdentifier,

digest OCTET STRING}

ハッシュアルゴリズムの識別子を署名計算への入力に含める理由は、ハッシュア

ルゴリズムのすり替えによる署名の転用を防ぐ点にある。 仮に、署名者が注意深く安全なハッシュアルゴリズムを用いてデジタル署名を生

成しても、弱いハッシュアルゴリズムが存在すると、攻撃者は弱いハッシュアルゴ

リズムで署名に用いられたハッシュ値と同じ値をもつメッセージを探索することで、

デジタル署名を転用することができる。 ESMA-PKCS1-v1_5では、ハッシュアルゴリズムの識別子を署名計算への入力に含めることで、デジタル署名を復号した時に署名生成に使用したハッシュアルゴリ

ズムの指定も復元されるので、上記の転用による攻撃は不可能となる。

(2) EMSA-PSS

デジタル署名に対する最も強い攻撃は選択メッセージ攻撃(Chosen Message Attack)である。選択メッセージ攻撃では、攻撃者はメッセージを任意に選択して署名させ、集めた署名を材料としてデジタル署名を偽造する。

EMSA-PSS は、選択メッセージ攻撃に対して証明可能な安全性を実現するための符号化方式である。PSSは Pseudo-random Signature Schemeの頭文字であることからも分かるとおり、EMSA-PSS は符号化の過程で乱数効果を加える。即ち、同じメッセージを符号化しても、符号化の値は都度変化し、従って、デジ

タル署名の値も変化する。 EMSA-PSSは[PKCS1]などで規定されているが、EMSA-PKCS-v1_5と異なり、ハッシュアルゴリズムの識別子は符号化に含まれない。先に述べた弱いハッシュ

アルゴリズムを利用した転用攻撃を防ぐためには、メッセージ中に適切な形でハ

ッシュアルゴリズムを特定する情報を埋め込まなければならない。

表 3-10 RSA署名のための符号化アルゴリズム

アルゴリズム名 説明 EMSA-PKCS1-v1_5 メッセージのハッシュ値とハッシュアルゴリズムの識別子

の DERによる符号化の先頭に、11バイト以上の固定バイトを連接する。

EMSA-PSS 乱数をハッシュ値への入力に含めることにより、同じメッ

セージであっても都度異なる署名値が得られる。選択メッ

セージ攻撃に対して、証明可能な安全性を提供する。

35

3.6.2 DSA 署名

離散対数問題系の公開鍵ペアを用いて生成されるデジタル署名であり、選択メッ

セージ攻撃に対して証明可能な安全性を有していることが知られている。 ベースのアルゴリズムは ElGamal署名[ElGamal]であるが、署名長を短縮するために、Schnorr署名におけるテクニックと独自のテクニックを導入している。NISTによって、FIPS PUB 186([DSS])として標準化されている。 使用する一方向性ハッシュアルゴリズムとして SHA-1 のみを許す点、ベースとなる群を素体の乗法群と楕円曲線とから選択できる点、複数のユーザでベースとな

る群を共有できる点で、RSA署名と相違する。特に、ハッシュアルゴリズムが固定されていることから、例えば、PKCS #7データ中では、アルゴリズムの指定方法が異なることに注意しなければならない。即ち、RSA 署名では、RSA 署名の識別子とは別にハッシュアルゴリズムの識別子を指定しなければならないが、DSA署名では DSA署名であることを指定するだけでアルゴリズムが一意に決定される。 一般に、RSA 署名は検証処理が速く、DSS 署名は署名生成処理が速いとされている。

36

3.7 メッセージ認証コード(MAC)

メッセージ認証コードは、メッセージの改ざん検知(message integrity)を目的として、メッセージに添付される固定長のデータである。

MAC の生成及び検証には秘密鍵が必要であり、秘密鍵を共有している通信者同士で、メッセージの改ざん検知を実行することができる。デジタル署名と異なり、

署名作成者の認証と否認拒否の機能は提供しない。

3.7.1 共通鍵暗号を利用した MAC生成関数(CBC-MAC)

CBC-MAC とは、CBC モードでのブロック暗号による最後の暗号文ブロックをMACの生成に使用する方法の総称である。 ブロック暗号を CBC モードで動かした時、平文の一部が改ざんされると以降の暗号文ブロックに連鎖的に影響が及び、特に、最後の暗号文ブロックの値が変化す

る。この性質を利用して、メッセージを CBC モードで暗号化し、最後の暗号文ブロックからMACを計算するのが CBC-MACと呼ばれる手法である。 但し、最後の暗号文ブロックをそのまま MAC として用いると、鍵の全探索攻撃による危険があるほか、特定の条件のもとでMACの偽造の可能が指摘されている。

CBC-MACの偽造

鍵 kによるブロック暗号関数を enck(x)とあらわす。

メッセージ xのブロックへの分解を x = x1 | x2 | … | xm、xmへのパディングを p、イニシャルベクタをIV として、CBCモードでの暗号化を以下のように表す。

e1 = enck(IV XOR x1) e2 = enck(e1 XOR x2) … em-1 = enck(em-2 XOR xm-1)

em = enck(em-1 XOR (xm | p))

メッセージ xへの鍵 kによるMACを、mack(IV, x) = em により定義する。

更に、メッセージ yの最初のブロックを y1、y = y1 | ytailとし、そのMAC mack(iv, y)が与えられているとすると、mack(iv, y)はメッセージ z = x | p | (IV XOR mack(IV, x) XOR y1) | ytailの鍵 kによるMACと一致する。これは、MAC計算における最初の暗号文ブロックが、zと yの場合で一致するからである。

enck(em XOR (IV XOR mack(IV, x) XOR y1)) = enck(IV XOR y1)

37

このような攻撃を排除するため、最後の暗号文ブロックを同じ鍵で再度暗号化す

る、最後の暗号ブロックの一部を MAC として利用するなどの方法が推奨されている。 ブロック暗号アルゴリズムとして DESを用いる方法は、DES-MACとして[DES

MAC1]及び[DES MAC2]に規定されている。

3.7.2 一方向性ハッシュ関数を利用した MAC生成関数

一方向性ハッシュ関数から鍵付一方向性ハッシュ関数を構成し、MAC 生成関数とする手法が知られている。一方向性ハッシュ関数から鍵付一方向性ハッシュ関数

鍵を構成する方法に関しては、以下の 3つが一般的である。 1. Secret prefix方式 入力メッセージの先頭に鍵データを接合し、得られたバイト列に対してハッ

シュ関数を施した結果をMACとする。

pfx-h(key, msg) = h( key | msg)

2. Secret suffix方式 入力メッセージの最後尾に鍵データを接合し、得られたバイト列に対してハ

ッシュ関数を施した結果をMACとする。

sfx-h(key, msg) = h(msg | key)

3. Envelope方式 入力メッセージの前後を 2 つの鍵データで挟み、得られたバイト列に対してハッシュ関数を施した結果をMACとする。

env-h(key1, key2, msg) = h(key1 | msg | key2)

MD5や SHA-1など普及している一方向性ハッシュ関数は、圧縮関数の多段繰り返しによって構成される(0)。このような構造をもつハッシュ関数に対する、Secret prefix法と Secret suffix法の適用はでは偽造の危険が指摘されているため、これらの方法はあまり利用されない([BCK])。

38

Secret prefix法への攻撃

メッセージ y のハッシュ値を pfx-h(key, x)をイニシャルベクタとして計算すると、 h [IV = pfx-h(key, x)] (y) = pfx-h(key, x | y)

が成立し、MACの転用が可能となる。

Secret suffix法への攻撃

ハッシュ関数の衝突、即ち、h (x) = h(y)を発見できると、 sfx-h(key, x) = sfx-h(key, y)

により、MACの転用が可能となる。ハッシュ関数の衝突の計算は、秘密鍵 keyにアクセスすることなく実行可能であり、また、並列に実行できることから、MACそのものへの攻撃よりはるかに容易

であるとされる。

MD5 を一方向ハッシュ関数として用いる Envelope 法による MAC 生成関数は、

[MD5 MAC]に規定されている。 但し、Envelope 法では 2 つの鍵を使用するが、鍵の全探索攻撃に対する鍵空間

の広さは鍵一つ分しかないことに注意して、鍵の長さを決定しなければならない

([BCK])。

Envelope法の鍵全探索に対する鍵空間の広さ

ふたつのメッセージ x と y に対して MAC の衝突が発見された場合、鍵 key1と鍵 key1の探索を、

独立に 2 段階で実行することができる。従って、鍵の長さを l ビットとすると、探索しなければ鍵の個数は最大で 2×2l= 2l+1であり、key1と key1とを併せて長さ 2lビットの鍵を用いているにも関わらず、鍵空間の広さは 22lとはならない。以下にその理由を示す。

h(key1 | x | key2) = h(key1 | y | key2)が成立したとすると、

h(key1 | x | key2) = h [IV = h(key1 | x)] (key2) h(key1 | y | key2) = h [IV = h(key1 | y)] (key2)

より、h(key1 | x) = h(key1 | y)が成り立つので、鍵 key1の全探索を鍵 key2とは独立に実行することが

できる。鍵 key1が見つかれば、次いで、h [IV = h(key1 | x)] (key2)が与えられたMAC と一致するよ

うに、鍵 key2の全探索を行えばよい。

39

3.7.3 限定的な安全性証明付き MAC生成関数

一方向性圧縮関数を多段に組み合わせて一方向性ハッシュ関数を構成する、いわ

ゆる、多段繰り返し構造(iterated structure)をもつ一方向性ハッシュ関数を利用して、限定的ながら、安全性の証明がついた MAC 生成関数を構成する方法が知られている。HMAC(Hash-based MAC)である。

より正確には、HMACでは、MAC生成関数としての安全性を圧縮関数の安全性に帰着できることが証明される。圧縮関数の安全性の検証は、一方向性ハッシュ関

数のそれに比べて著しく容易であると考えられているため、HMACは有効であると考えられている。

また、現在主流である一方向性ハッシュ関数(MD5, SHA-1)は、いずれも、アッシュ関数の多段繰り返しにより構成されるので、HMACの適用範囲は広い。このため、HMACは広く利用されており、[HMAC]及び[HMAC SHA1]としてアルゴリズムが標準化されているほか、TLS1.1([TLS1.1])においても採用されている。

一方向性ハッシュ関数 h(x)に対して、HMACによるMAC生成関数は以下のよう

に定義される。

HMAC-h(key, msg) = h(key XOR opad | h((key XOR ipad) | msg))

但し、keyはMAC生成鍵、msgは入力メッセージ、ipad及び opadは公開のパディング定数

3.7.4 パスワードに基づく MAC生成関数

MAC生成のための鍵をパスワードから生成するMAC生成関数であり、PKCS #2 v.2.0[PKCS5]に規定されている。

[PKCS5]では、鍵導出アルゴリズムとしては PBKDF2 を指定しているが、ベー

スとなる MAC 生成アルゴリズムとしては任意のものを指定できるとしている。但し、SHA-1をベースとした HMACが例として与えられている。

40

3.7.5 セキュリティ API で利用される MAC アルゴリズム

表 3-11は、セキュリティ APIの主要な CSPでサポートされる、メッセージ認証コードの生成アルゴリズムである。

表 3-11 メッセージ認証コード生成アルゴリズム

アルゴリズム名 説明 HMAC-MD5 一方向性ハッシュ関数として MD5を使用する HMACであ

り、[HMAC]により規定。 HMAC-SHA-1 一方向性ハッシュ関数として SHA-1 を使用する HMAC で

あり、[HMAC]及び[HMAC SHA1]により規定。 PBMAC パスワードから導出される鍵を用いた HMAC-SHA1 であ

り、[PKCS5]に規定がある。 CBC-MAC 共通鍵によるブロック暗号を CBCモードで動作させ、最後

の暗号文ブロックからMACを生成。 ブロック暗号として DES を用いる規格は、[DES MAC1]及び[DES MAC2]により規定。

MD5-MAC 一方向性ハッシュ関数として MD5を使用する Envelope法によるMACであり、[MD5 MAC]により規定。

41

3.8 セキュア通信

3.8.1 SSL 3.0 と TLS 1.0

暗号通信プロトコルとしては、SSL(Secure Socket Layer)3.0と TLS(Transport Layer Security)1.0が、最も広く使用されている標準である。 従って、セキュリティ APIとしてはその上でこれらの暗号通信プロトコルを実装できることが重要な要件となるとともに、JSSEのように SSLを直接取り扱うための関数を提供するセキュリティ APIも存在する。SSLはセキュリティ APIの主要なアプリケーションであるという認識から、この節では少しく詳細に SSL 3.0(TLS 1.0)を解説する。

(1) 利用状況

SSLは、二者間の汎用の認証プロトコルであり、もともとは、Web通信における認証とプライバシーの問題を解決することを目的に、米国 Netscape Communication Corporationによって開発されたものである。

SSLは Netscape2.0からウェブブラウザに標準実装されるとともに、仕様を公開しフリーライセンスとしたため、広く普及することになった。そのため、

多くのブラウザ、サーバーソフトウェアに実装された。現在では、金融機関、eコマースサイトなど個人の秘密情報をやり取りするようなサイトでは、米国に

限らず、日本国内でもほぼ全面的に SSLが採用されている。 SSL1.0は仕様が策定されたが実装されることはなく、1995年 4月に仕様が公開された SSL2.0から、Netscape Navigator 1.0/2.0に実装が行われた。しかしながら、SSL2.0 では乱数発生に実装上のバグが判明したため、これを改良した SSL3.0([SSL3.0])が 1996年 11月に仕様が公開された。

SSL3.0 以降の仕様策定と普及の主体は IETF(Internet Engineering Task Force)に移り、1999年 1月に TLS1.0([TLS1.0])として標準化された。

(2) 仕様

SSLは、二者間の汎用的な認証プロトコルであり、以下の機能を提供する。 1. 公開鍵証明書に基づいてエンティティ間認証を行う。 2. エンティティ間の通信を改ざん、盗聴、成りすましから保護する。 技術的な観点からの、プロトコルのおおよその流れは次のようになる。

42

1. 通信の当事者(クライアントとサーバー)が、それぞれ、公開鍵証明書に基づいて公開鍵暗号の計算を実行することで、秘密の乱数

(master_secret)を共有する。公開鍵暗号と暗号学的一方向性ハッシュ関数の安全性を仮定すると、当事者間に攻撃者が割り込む MITM(Man-In-The-Middle)攻撃に対しても、当事者以外がこの秘密を知りえることはない。

2. クライアントとサーバーは、共有の秘密である master_secret から、これ以後交換されるメッセージを暗号化するための鍵とメッセージ認証コ

ード(MAC, Message Authentication Codes)を生成するための鍵を生成する。これらの鍵は、クライアントとサーバーに共通のアルゴリズム

で生成されるので、両者の間で共有される。暗号鍵は通信の秘匿の目的

に、MAC鍵は改ざん検知の目的のために使用される。 SSLの特徴として以下を挙げることができる。

トランスポートプロトコル独立 SSL のメッセージを運搬するトランスポートのプロトコルを選ばない。SSLは、TCP/IPのようなトランスポート層のプロトコル上であっても、http、ftpのようなアプリケーション層のプロトコル上であっても、同様に機能を提供

することが可能であり、下位のプロトコルを完全に隠蔽する。 複数の暗号アルゴリズムのサポート 公開鍵暗号、共通鍵暗号、暗号利用モード、一方向性ハッシュ関数それぞれ

に関して、複数のアルゴリズムをサポートしている。それに付随して、当事

者間で、どのアルゴリズムを使用するか決定するネゴシエーションの仕組み

を備えている。特に、輸出規制の対象となる製品に組み込んだ場合でも、相

互運用性を保証している。 一方向認証のサポート 当事者間の認証として、相互的に認証する双方向認証( bilateral authentication)に加えて、クライアントによるサーバーの認証のみをサポートする一方向認証(unilateral authentication)をサポートしている。一方向認証をサポートすることにより、一般ユーザへの公開鍵証明証の配布が進

んでいない現状のインターネット上においても、機能を提供することが可能

となり、SSLの普及の一因となっている。 この節では、SSLの認証機能の中核部分であるハンドシェイクプロトコル

(Handshake Protocol)を中心に解説し[SSL3.0, 5.6]、最後にレコードレイヤ(Record Layer)におけるメッセージの秘匿と改ざん防止について簡単に

43

触れることとする[SSL3.0, 5.2]。 Change Cipher Spec Protocol [SSL3.0, 5.3]、及び、Alert Protocol [SSL3.0,

5.4]に関しては、この章では取り上げない。

(a) ハンドシェイクプロトコルの概要

図 3-4は、SSLのハンドシェイクプロトコルで、クライアントとサーバーとの間で交換されるメッセージの種類と交換順序を表したものである。

クライアント ClientHello サーバ

ServerHello

Certificate

ServerKeyExchange

Certificate

ClientKeyExchange

CertificateVerify

Finished

省略可能なメッセージ

ServerKeyExchange

CertificateRequest

ServerHelloDone

Finished

図 3-4 SSLのハンドシェイクプロトコル

ハンドシェイクプロトコルの目的は、次の 2つである。 1. クライアントとサーバーの間で共通に用いられる暗号パラメータ(Cipher Suite)の合意

2. メッセージの秘匿と改ざん検知のための鍵のもととなる秘密master_secretの合意

Cipher Suiteの合意に関しては、まずクライアントがサポート可能なパラメータの一覧を ClientHelloメッセージにいれてサーバーに送付し、サー

バーはその中から一つを選択して ServerHelloメッセージにいれて返送す

るという方法をとる。 SSL 3.0でサポートされている Cipher Suiteを表 3-12に示す。

44

表 3-12 Cipher Suiteに指定されるパラメータ

パラメータ 符号化

SSL_NULL_WITH_NULL_NULL { 0x00,0x00 }

SSL_RSA_WITH_NULL_MD5 { 0x00,0x01 }

SSL_RSA_WITH_NULL_SHA { 0x00,0x02 }

SSL_RSA_EXPORT_WITH_RC4_40_MD5 { 0x00,0x03 }

SSL_RSA_WITH_RC4_128_MD5 { 0x00,0x04 }

SSL_RSA_WITH_RC4_128_SHA { 0x00,0x05 }

SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 { 0x00,0x06 }

SSL_RSA_WITH_IDEA_CBC_SHA { 0x00,0x07 }

SSL_RSA_EXPORT_WITH_DES40_CBC_SHA { 0x00,0x08 }

SSL_RSA_WITH_DES_CBC_SHA { 0x00,0x09 }

SSL_RSA_WITH_3DES_EDE_CBC_SHA { 0x00,0x0A }

SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA { 0x00,0x0B }

SSL_DH_DSS_WITH_DES_CBC_SHA { 0x00,0x0C }

SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA { 0x00,0x0D }

SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA { 0x00,0x0E }

SSL_DH_RSA_WITH_DES_CBC_SHA { 0x00,0x0F }

SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA { 0x00,0x10 }

SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA { 0x00,0x11 }

SSL_DHE_DSS_WITH_DES_CBC_SHA { 0x00,0x12 }

SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA { 0x00,0x13 }

SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA { 0x00,0x14 }

SSL_DHE_RSA_WITH_DES_CBC_SHA { 0x00,0x15 }

SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA { 0x00,0x16 }

SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 { 0x00,0x17 }

SSL_DH_anon_WITH_RC4_128_MD5 { 0x00,0x18 }

SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA { 0x00,0x19 }

SSL_DH_anon_WITH_DES_CBC_SHA { 0x00,0x1A }

SSL_DH_anon_WITH_3DES_EDE_CBC_SHA { 0x00,0x1B }

SSL_FORTEZZA_KEA_WITH_NULL_SHA { 0X00,0X1C }

45

パラメータ 符号化

SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA { 0x00,0x1D }

SSL_FORTEZZA_KEA_WITH_RC4_128_SHA { 0x00,0x1E }

表 3-12 の一覧におけるパラメータの意味について、いくつかの例を表

3-13に示す。

表 3-13 Cipher Suiteの意味例

パラメータ 鍵交換 アルゴリズム

共通鍵 アルゴリズ

ハッシュ関数 アルゴリズム

SSL_RSA_WITH_RC4_128_MD5 RSA RC4(128) MD5 SSL_RSA_EXPORT_WITH_RC4_40_MD5

RSA (512以下)

RC4(40) MD5

SSL_DH_DSS_WITH_DES_CBC_SHA

Diffie-Hellman DES(64) SHA-1

SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA

KEA Skipjack SHA-1

表 3-12 中の符号化欄は、ClientHello 及び ServerHello の中で指定

する時の各パラメータの参照番号を定めるものである。 SSL では、鍵交換のアルゴリズムとして、大きく RSA 公開鍵暗号、

Diffie-Hellman鍵交換、そして、FORTEZZA-KEAをサポートしている。 ハンドシェイクプロトコルでは、鍵交換のための公開鍵暗号アルゴリズム

に従って、まず、pre_master_secretと呼ばれる秘密情報を共有し、次いで、それぞれが pre_master_secretからmaster_secretを計算する。

master_secret は 、 pre_master_secret と 、 ClientHellow 及 び

ServerHello によってクライアントとサーバーが相手に送付する乱数

(ClientHellow.random 及び ServerHello.random)とに依存するよ

うに生成される7。 ハンドシェイクプロトコルの最後に交換される Finished メッセージは、

master_secret を鍵として計算された MAC を指定する。サーバー及びクライアントは、受け取った MACを自分が保有する master_secretで検証することで、master_secretを共有していることを確認し、相手の認証を行う。

FORTEZZA-KEAは、米国政府内では広く使われているが、外部では利用頻度も低く、また、TLS 1.1でもサポートされないので、この章では取り上

7 master_secretの生成アルゴリズムは、SSL 3.0と TLS 1.1で異なる。SSL 3.0ではMD5と SHA-1を組み合わせた計算式でmaster_secretを算出するが、TLS 1.1では擬似乱数関数(Pseudo Random Function)による。

46

げない8。以下では、RSA のケースと DH のケースそれぞれについて、

ClientHello 以下のメッセージの意味と、master_secret の共有方法について説明していく。

(i) RSAで鍵交換を行う場合のハンドシェイクプロトコル

まず、鍵交換のアルゴリズムとして RSA 公開鍵暗号が指定された場合について、クライアントとサーバーが交換するメッセージの意味を説明する。

1. ClientHello: クライアントが生成する 28 バイトの乱数

(ClientHello.random)を指定する。 2. ServerHello: サ ー バ ー が 生 成 す る 28 バ イ ト の 乱 数

(ServerHello.random)を指定する。 ClientHello.random と

ServerHello.random と は 、 後 に 、 pre_master_secret か らmaster_secretを生成する際に使用される他、以下のハンドシェイクプロトコルにおいて再生攻撃を防止する役割を果たす。

3. (Server)Certificate: 原則として、鍵交換に用いる RSA公開鍵を指定する公開鍵証明書を指定する。クライアントは、この RSA公開鍵で pre_master_secret を暗号化して、サーバーに送付する(ClientKeyExchange)。 証明書中の公開鍵を鍵交換に使わない場合については、

ServerKeyExchangeを参照せよ。 4. ServerKeyExchange: RSAで鍵交換を行う場合には、原則的には、このメッセージは省略される。このメッセージが送られる場合には、

サーバーが一時的に生成した RSA 公開鍵(公開法数と公開指数のペア)と、その RSA公開鍵に対するデジタル署名とが指定される。このメッセージに指定される RSA 公開鍵はクライアントが

pre_master_secret を暗号化する際に利用し、デジタル署名は直前のCertificateで指定された公開鍵証明書によって検証される9。

5. ServerHelloDone: サーバーからの送信の終了を示す空のメッセージ。ServerKeyExchangeが省略可能であることから、クライアント

に明示的に送信の終了を知らせる必要がある。 6. CertificateRequest: このメッセージが送付されるのは、サーバーがクライアント認証を要求する場合に限る。

7. (Client)Certificate: CertificateRequestへの返信として、ク 8 必要であれば[SSL3.0, 5.6.7.2]を参照されたい。 9 SSL 3.0では、RSAを鍵交換に利用するケースで、どのような場合に ServerKeyExchangeが送られるかを明記していない。一方、TLS 1.1では、RSA-EXPORTが Cipher Suiteに指定されていて、Certificate中の RSA公開鍵の法数長が 512ビットを超える場合に限ると規定されている。

47

ライアントの公開鍵証明書を送付する。このメッセージに指定される

証明書は署名検証用の公開鍵に対するものでなければならず、後述の

CertificateVerify に指定される署名値はこの公開鍵証明書によ

って検証される。 8. ClientKeyExchange: クライアントは 46 バイトの乱数である

pre_master_secretを生成し、サーバーの公開鍵で暗号化して送付する。暗号化に用いられる公開鍵は、原則として、(Server)Certificateに指定される公開鍵証明書の公開鍵であるが、ServerKeyExchange

が送付されている場合には同メッセージ中に指定されている RSA 公開鍵を使用する。

9. CertificateVerify: クライアント認証が要求されている場合にのみ送付されるメッセージ。ClientHello からこのメッセージの直前

のメッセージまでを連接したデータに対するデジタル署名が指定され

る。サーバーは、このデジタル署名をクライアントの公開鍵証明書(ク

ライアントが送付する Certificate に指定されている公開鍵証明

書)を用いて検証することで、クライアントの認証を行う10。 10. Finished: クライアント、サーバーどちらが送付する場合でも、

master_secretを鍵として生成されたMACが指定される。具体的には、ClientHellowから直前のメッセージまでを連接したデータに、更に、

“client finished”或いは“server finished”という文字列を連接したデータに対するMACである11。

(ii) Diffie-Hellmanで鍵交換を行う場合のハンドシェイクプロトコル

このケースでは、Diffie-Hellman鍵交換アルゴリズムによって交換される鍵が、pre_master_secretとして使用される。RSAを鍵交換アルゴリズムを利用するケースでは、クライアントが pre_master_secretを生成し、それを秘密裏にサーバーに送付するという方法をとったが、Diffie-Hellmanの場合では、クライアントとサーバーは交換したデータを利用して、相互に

pre_master_secretを計算する。 SSL 3.0では、Diffie-Hellman鍵交換アルゴリズムの利用モードとして、表 3-14の 5つを規定している。

10 SSL 3.0と TLS 1.1では、CertificateVerifyに指定されるデジタル署名の生成に用いるハッシュ関数のアルゴリズムが異なる。SSL 3.0ではmaster_secretを鍵としたHMACに似たアルゴリズム(パディングと鍵の論理和をとる代わりに、パディングを鍵に連接する)でハッシュ値を計算するが、TLS 1.1はMD5或いは/及びSHA-1による(RSA署名ではMD5と SHA‐1によるハッシュ値を連接する)。 11 Finishedに指定されるMACの生成アルゴリズムは、SSL 3.0と TLS 1.1で異なる。TLS 1.1では擬似乱数関数(Pseudo Random Function)を用いるのに対し、SSL 3.0ではHMACに似たアルゴリズムを使用する(パディングと鍵の論理和をとる代わりに、パディングを鍵に連接する)。

48

表 3-14 Diffie-Hellmanの利用モード

利用モード 定義 DH_DSS サーバー(クライアント)の公開鍵証明書に指定された

Diffie-Hellman 公開鍵を使用して pre_master_secretを生成する。公開鍵証明書への署名は DSS(Digital Signature Standard [DSS])による。

DH_RSA サーバー(クライアント)の公開鍵証明書に指定された

Diffie-Hellman の公開鍵を使用して pre_master を生成する。公開鍵証明書への署名は RSA署名による。

DHE_DSS サーバー(クライアント)は、使い捨ての Diffie-Hellman公開鍵を生成して、生成した公開鍵に基づいて

pre_master_secretを生成する。 ServerKeyExchange(CertificateVerify)メッセージ中で、Diffie-Hellman 公開鍵への署名が指定されるが、その際の署名アルゴリズムは DSAである。DHEはDiffie-Hellman-Ephemeralによる。

DHE_RSA サーバー(クライアント)は、使い捨ての Diffie-Hellman公開鍵を生成して、生成した公開鍵に基づいて

pre_master_secretを生成する。 ServerKeyExchange(CertificateVerify)メッセージ中で、Diffie-Hellman 公開鍵への署名が指定されるが、その際の署名アルゴリズムは RSA 署名である。DHEは Diffie-Hellman-Ephemeralによる。

DH_anon サーバー(クライアント)は、使い捨ての Diffie-Hellman公開鍵を生成して、生成した公開鍵に基づいて

pre_master_secret を生成する。Diffie-Hellman 公開鍵への署名は交換されず、サーバー及びクライアントの

認証は行われない。サーバーとクライアントとが互いに匿

名でチャネルを開くときに使うモードである。_anon はanonymousによる。

DH_DSS 及び DH_RSA の利用モードでは、ServerKeyExchange,

ClientKeyExchange及び CertificateVerifyのメッセージは交換され

ない。Certificateに指定された公開鍵証明書中の Diffie_Hellman公開鍵が pre_master_secretの計算に使用されるからである。 一 方 、 DHE_DSS 及 び DHE_RSA の 利 用 モ ー ド で は 、

ServerKeyExchange並びに ClientKeyExchangeのメッセージは必須で

ある。これらのメッセージに指定される、サーバー及びクライアントの使い

捨てのDiffie-Hellman公開鍵がpre_master_secretの計算に使用されるからである。CertificateVerifyはクライアント認証が要求された場合にのみ

49

送付される。 DH_anonは、匿名モードのハンドシェイクであるので、サーバー、クライ

アントのいずれも、Certificate メッセージを送付しない。逆に、

ServerKeyExchange並びに ClientKeyExchangeのメッセージは必須と

なる。

(b) レコードレイヤプロトコルの概要

SSL 3.0のレコードレイヤは、アプリケーションデータに対して、暗号化による秘匿と MAC による改ざん検知の機能を与えるメッセージラッパーを規定する。 即ち、アプリケーションデータは MAC が添付され、暗号化された後、ペ

イロードとしてレコードレイヤのメッセージにより運搬される。 SSLのハンドシェイクプロトコルのメッセージも、レコードレイヤを介して交換される。 これまでに見たように、ハンドシェイクプロトコルを実行することで、サ

ーバーとクライアントとが共通の秘密情報 master_secret を共有する。master_secret は、48 バイトのデータで、鍵交換で共有されたやはり 48 バイトの秘密の共有情報 pre_master_secret と、 ClientHellow 及び

ServerHello で交換される各々28 バイトの乱数 ClientHello.random

及び ServerHello.randomに依存して生成される、乱数性の高いデータで

ある。 レコードレイヤでは、master_secretから、表 2-12で示す 6つの鍵データを生成して、アプリケーションデータの秘匿と改ざん防止のために使用する。

表 3-15 レコードレイヤで利用される鍵データ

鍵データ 用途 client_write_MAC_secret クライアントがアプリケーションデータに対す

るMACを生成する際に使用する鍵。 server_write_MAC_secret サーバーがアプリケーションデータに対する

MACを生成する際に使用する鍵。 client_write_key クライアントがアプリケーションデータを暗号

化する際に使用する鍵。 server_write_key サーバーがアプリケーションデータを暗号化

する際に使用する鍵。 client_write_IV Cipher Suite において CBC (Cipher Block

Chaining [CipherMode])モードの使用が指定されている時に、クライアントが暗号化で使用

するイニシャルベクタ。

50

鍵データ 用途 server_write_IV Cipher Suite において CBC (Cipher Block

Chaining [CipherMode])モードの使用が指定されている時に、サーバーが暗号化で使用

するイニシャルベクタ。 輸出可能なアルゴリズムが指定されている場合、即ち、_EXPORTが Cipher

Suite に指定されている場合には、下記のように、それ以外の場合とは異なる方法で、 client_write_key、 server_write_key、 client_write_IV 及び

server_write_IVを計算する。 1. 通常の方法で client_write_key と server_write_key を計算した後、

client_write_key と server_write_key そ れ ぞ れ に 対 し て

ClientHello.random と ServerHello.random を接合し、更に、

ハッシュ(MD5)を計算して、_EXPORT における client_write_keyと server_write_keyとする。

2. ClientHellow.random と ServerHello.random を接合した値に

対して、それぞれ、ハッシュ値をとり、 client_write_IV と

server_write_IV とを計算する。_EXPORT 以外のケースでは、

client_write_IVと server_write_IVはmaster_secretから生成される。即ち、client_write_IVと server_write_IVは当事者間の秘密であるので、実質的な鍵の一部となり、輸出規制における鍵長の制限に抵触し

て し ま う 。 そ こ で 、 _EXPORT で は 、 平 文 で 交 換 さ れ る

ClientHellow.random と ServerHello.random か ら

client_write_IVと server_write_IVとを計算することで、この問題を回避しているのである。

さて、SSL のレコードレイヤでは、アプリケーションデータを、(適当に分割・圧縮した後に)Cipher Suiteに指定されるパラメータに従って、MACを添付し、暗号化を施して、送信する。受信側は、復号の後に、MAC を検証し、伸長したデータを再構成してアプリケーションデータを復元する。

51

サーバ公開鍵証明書

CA

クライアン

SSLHandshake

Protocol

SSLRecordLayer

client_write_MAC_secret

MAC

アプリケーションデータ

MAC

暗号化 復号MAC生成

MAC検証

公開鍵証明書

CA

アプリケーションデータ

client_write_key

client_write_MAC_secret

client_write_key

master_secretmaster_secret 鍵交換

図 3-5 レコードレイヤ

3.8.2 Transport Layer Security (TLS) 1.1

(1) 利用状況

TLS 1.1の前のバージョンである TLS 1.0は、現在多くのブラウザ、サーバーソフトウェアで実装されているが、多くの場合 TLSでの認証を試みて失敗すると SSL3.0に切り替えてセッションを継続するような仕組みになっている。

TLS 1.0は 1999年 1月に RFC 2246([TLS1.0])として標準化されている。

2002 年 10 月にはプロトコルの拡張が行われた TLS 1.1 が

INTERNET-DRAFT([TLS1.1])として提案され、審議中である。

(2) 仕様

この節では、SSL 3.0から TLS 1.1への主要な変更点のみを述べる。この変更点だけ読み替えれば、前節の SSL 3.0の解説はそのまま TLS 1.1に適用される。

(a) 擬似乱数生成関数の強化

TLS 1.1では、SSL 3.0と同様に、公開鍵暗号に基づく鍵交換アルゴリズムを用いて交換した秘密情報 pre_master_secretからmaster_secretと呼ば

52

れる鍵の種となる秘密データを生成し、更に、master_secret から以下の 4種類の鍵を生成する。

client_write_MAC_secret server_write_MAC_secret (final_)client_write_key (final_)server_write_key これらmaster_secret及び鍵の生成には、擬似乱数関数(Pseudo Random

Function)が用いられるが、TLS 1.1では乱数特性がより強化された擬似乱数関数を用いている。

SSL 3.0では、MD5及び SHAの 2つの一方向性ハッシュ関数を組み合わせて擬似乱数生成関数を定義していたが、TLS 1.1ではその乱数特性が圧縮関数の特性に帰着される HMAC([BCK]、[HMAC SHA1])をベースとして、より理論的に擬似乱数生成関数を構成している。 レコードレイヤにおいてアプリケーションデータの暗号化及びメッセージ

認証コードの生成に用いられるこれらの鍵の安全性(乱数性)は、プロトコ

ルの安全性に直接的に影響を及ぼすことから、この修正により TLS 1.1の安全性は相当程度向上したものと考えられる。

(b) イニシャルベクタの乱数化

SSL 3.0では、ブロック暗号を CBCモードで利用することを許している。その際使用されるイニシャルベクタは、セッション毎に固定的に生成される

規定となっており、この性質を利用した攻撃方法が発見されている。 この弊害を取り除くため、TLS 1.1では、自由な値をイニシャルベクタとして使用することを許し、特に、安全な擬似乱数生成アルゴリズムによりイ

ニシャルベクタを生成して使用することを推奨している。

(c) FORTEZZA KEAのサポートの取止め

SSL 3.0 では、鍵交換アルゴリズムとして、RSA 公開鍵暗号及び

Diffie-Hellman鍵交換に加えて、FORTEZZA KEA [FOR]をサポートしている。しかしながら、FORTEZZA は予定されていた利用者である米国連邦政府内においてさえ、ほとんど利用されていないことから、TLS 1.1 では FORTEZZAのサポートを取止めている。

53

3.9 PKCS #7

PKCS #7は、RSA Laboratoryが開発した暗号メッセージの交換形式を定める規格であり、世界標準の位置づけにある。

PKCS #7メッセージには、暗号化されたメッセージやメッセージに対する署名値に加えて、復号や署名検証に必要なアルゴリズムや公開鍵証明書などの情報が全て

同梱されるので、PKCS #7に従ってメッセージを符号化することで、事前の取り決めや付加的な通信を行うことなく、暗号処理が施されたメッセージの交換が可能と

なる。 PKCS #7 は、SignedData、EnvelopedData、SignedAndEncryptedData、

DigestedData、EncryptedData の 5 タイプのコンテンツタイプを定義している。これらのコンテンツタイプは、ASN.1によって、構文と符号化規則が定義される。

3.9.1 SignedData タイプ

SignedData タイプは、本体のコンテンツデータ、コンテンツデータに対する署名データ、署名データの検証に関連する証明書(証明者の公開鍵証明書と証明

書チェイン)を同梱するメッセージのタイプである。 同一のコンテンツデータに対して、複数の署名鍵による複数の署名データを指

定することが許される。署名データは、SignerInfoタイプに属する要素中に指定される。SignerInfoタイプは、署名データに加えて、ハッシュアルゴリズムと署名アルゴリズムの指定と署名者の属性データを指定する。

SignedData ::= SEQUENCE {

version Version,

digestAlgorithms DigestAlgorithmIdentifiers,

contentInfo ContentInfo,

certificates

[0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,

crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,

signerInfos SignerInfos }

DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier

ContentInfo ::= SEQUENCE {

contentType ContentType,

content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }

ContentType ::= OBJECT IDENTIFIER

54

SignerInfos ::= SET OF SignerInfo

SignerInfo ::= SEQUENCE {

version Version,

issuerAndSerialNumber IssuerAndSerialNumber,

digestAlgorithm DigestAlgorithmIdentifier,

authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,

digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,

encryptedDigest EncryptedDigest,

unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL }

EncryptedDigest ::= OCTET STRING

3.9.2 EnvelopedData タイプ

EnvelopedDataタイプは、共通鍵(コンテンツ鍵)で暗号化されたコンテンツデータ、コンテンツの暗号化アルゴリズムの識別子、及び、メッセージの受信者

の公開鍵によるコンテンツ鍵の暗号化データを同梱するメッセージのタイプであ

る。 一つのコンテンツデータは一つのコンテンツ鍵で暗号化されるが、コンテンツ

鍵を複数の受信者の公開鍵で暗号化してメッセージ中に指定することが許される。

これにより、同一の EnvelopedData メッセージを複数の受信者で共有することが可能となる。 また、コンテンツデータとして任意のタイプを許すので、例えば、SignedDataメッセージを EnvelopedData メッセージに埋め込むことで、機密性とメッセージ認証の機能の両立を実現することができる。

EnvelopedData ::= SEQUENCE {

version Version,

recipientInfos RecipientInfos,

encryptedContentInfo EncryptedContentInfo }

RecipientInfos ::= SET OF RecipientInfo

RecipientInfo ::= SEQUENCE {

version Version,

issuerAndSerialNumber IssuerAndSerialNumber,

keyEncryptionAlgorithm

KeyEncryptionAlgorithmIdentifier,

encryptedKey EncryptedKey }

55

EncryptedKey ::= OCTET STRING

EncryptedContentInfo ::= SEQUENCE {

contentType ContentType,

contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,

encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }

EncryptedContent ::= OCTET STRING

3.9.3 SignedAndEncryptedData タイプ

SignedAndEncryptedDataタイプは、PEM(Privacy Enhanced Mail、[PEM])との互換性のために導入されたタイプであり、EnvelopedData メッセージにSignedDataメッセージを埋め込むことで等価な機能を実現することができる。

SignedAndEncryptedDataタイプは、Envelopedメッセージに SignerInfo要素を添付したものとして定義される。但し、SignerInfo要素中に指定される署名データは、署名者の署名鍵によるデータをコンテンツ鍵で暗号化したデータであ

る。

SignedAndEnvelopedData ::= SEQUENCE {

version Version,

recipientInfos RecipientInfos,

digestAlgorithms DigestAlgorithmIdentifiers,

encryptedContentInfo EncryptedContentInfo,

certificates

[0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,

crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,

signerInfos SignerInfos }

3.9.4 DigestedData タイプ

コンテンツデータ、ハッシュアルゴリズムの識別子、及び、コンテンツデータ

のハッシュ値を同梱するメッセージである。

DigestedData ::= SEQUENCE {

version Version,

digestAlgorithm DigestAlgorithmIdentifier,

contentInfo ContentInfo,

digest Digest }

56

Digest ::= OCTET STRING

3.9.5 EncryptedData タイプ

暗号化したコンテンツデータから構成されるメッセージタイプである。 コンテンツデータを復号するための鍵は、PKCS #7の規定の外側で共有されることを前提とする。

EncryptedData ::= SEQUENCE {

version Version,

encryptedContentInfo EncryptedContentInfo }

57

4 セキュリティ APIの主要な機能

この章では、セキュリティ関連 APIがサポートする機能について概観する。 ここでは、セキュリティ APIを利用する開発者に対して、APIがサポートする標準的な機能とそれらの利用方法に関し情報を提供することを意図している。本章に

おける記述は以下の方針に従っている。 1. API 関数単位の解説ではなく、機能単位の解説を示す。よって、暗号技術の観点から見た時の機能が解説の単位となるので、必ずしも機能と API関数とが一対一に対応しない。 ひとつの機能が複数の API関数により実現されることはごく普通であるので、本章の解説中の「入力」と「出力」は API関数の「入力」と「出力」に必ずしも対応しないことに注意されたい。

2. 本章の解説は網羅的ではない。個々のセキュリティ APIが実現する機能については、これを網羅せず、重要な機能にフォーカスして解説を行う。 各セキュリティ APIに関する詳細な知識やサポートする詳細な機能についてはそれぞれのドキュメントを参照されたい。

3. 各機能に関しては、努めて、サンプルコードを載せることとした。 これらのサンプルコードは、あくまで機能の実現方法に対する理解を高め

ることを目的とするものであり、煩瑣な詳細は捨象している。プログラムと

しては完全ではない点に留意されたい。

4.1 公開鍵証明書ハンドリング

[X.509]などで定義される公開鍵証明書は、認証の基盤となる重要なデータであるため、一部のセキュリティ APIでは公開鍵証明書を直接取り扱うための機能を提供している。 公開鍵証明書そのものの取り扱いにおいて最も基本的な機能は、証明書データの

検証と CRL(Certificate Revocation List)データに基づく証明書データの無効化である。 加えて、公開鍵証明書は特定のエンティティの信用を保証するデータであり、ま

た、その正当性はルート証明書から証明書のチェインをたどって検証されることか

ら、ひとつのエンティティが保有する公開鍵証明書の数は夥しいものとなる傾向が

ある。このため、多数の公開鍵証明書を効率よく取り扱うための手段が共通に求め

られている。一部のセキュリティ APIでは、証明書を格納する証明書ストアの機能を提供している。 以下では、公開鍵証明書(チェイン)の検証、公開鍵証明書の無効化、証明書ス

トアの機能について整理する。

58

4.1.1 CTL(Certificate Trust List)に基づく証明書の検証

(1) 入力

CTL CTLの署名検証のための証明書 検証対象の証明書

(2) 出力

検証の成否

(3) 説明

指定された CTLを基に、検証対象の証明書の検証を実行する。CTLを直接指定する代わりに、CTLを格納するストアを指定するケースもある。

CTLに基づく証明書の検証は以下の手順で実行される。 1. CTLの署名を検証する。検証鍵は、この機能の実行者が信頼するサブジェクトのものでなければならない。そのため、署名検証のための証明書

を入力として指定される。実際には、証明書を格納するストアが指定さ

れ、ストア中から証明書を検索する機能も一部として提供されることが

ある。 2. CTL毎に定められた方法により、検証対象の証明書を検証する。例えば、

CTLに証明書のハッシュ値が記載されている場合には、検証対象の証明書のハッシュ値を計算して、一致するエントリーが存在することを検証

する。

(4) 例

//Example based on CryptoAPI

DWORD encodeType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;

//証明書の構文・符号化規則として X.509 と PKCS #7を指定

DWORD flag = CERT_VERIFY_INHIBIT_CTL_UPDATE_FLAG |

CERT_VERIFY_TRUSTED_SIGNER_FLAG;

//有効期限切れの CTLの更新は実行しないようにフラグを設定

//CTL_VERIFY_USAGE_PARA (params)中の rghSignerStoreで指定されたストア中の

59

//証明書のみを CTLの検証に用いる

//パラメータの設定の開始

CTL_USAGE usage;

usage.cUsageIdentifier = 0;

CTL_VERIFY_USAGE_PARA params;

params.cbSize = sizeof(CTL_VERIFY_USAGE_PARA);

params.ListIdentifier.cbData = 0;

//公開鍵証明書の検証に利用する CTLのストアを指定

params.cCtrlStore = 1;

params.rghCtlStore = &defaultCtlStore;

//CTLの署名検証のための公開鍵証明書のストアを指定

params.cSignerStore = 1;

params.rghSignerStore = &baseStore;

CTL_VERIFY_USAGE_STATUS status;

//statusを初期化

status.cbSize = sizeof(CTL_VERIFY_USAGE_STATUS);

status.dwError = 0;

status.dwFlags = 0;

status.ppCtl = NULL;

status.dwCtlEntryIndex = 0;

status.ppSigner = NULL;

status.dwSignerIndex = 0;

//パラメータの設定の終了

Bool rslt;

rslt = CertVerifyCTLUsage(encodeType, CTL_CERT_SUBJECT_TYPE,

60

&targetCertificate, usage, flag, params, status);

//rsltに検証結果を格納

4.1.2 証明書チェインに基づく証明書の検証

(1) 入力

証明書チェイン

(2) 出力

検証の成否

(3) 説明

証明書チェインの検証では、以下の二項目を検証する。

証明書チェインを構成する最初の要素が、ルート証明書、自己署名(self-signed)証明書などの信頼できる証明書である。

チェイン、2 番目以降の証明書の署名が直前の証明書の検証鍵で検証できる。

(4) 例

//Example based on CryptoAPI

Bool Rslt;

CERT_CHAN_POLICY_STATUS status;

rslt = CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_BASE,

&certChain, NULL, &status);

//rsltに検証結果を格納

4.1.3 CRL に基づく証明書の無効化の検証

(1) 入力

CRL 検証対象の証明書

61

(2) 出力

検証の成否

(3) 説明

指定された CRL中に検証対象の証明書が含まれているかを検査する。

(4) 例

//Example based on CryptoAPI

PCRL_ENTRY *hit = NULL;

if (CertIsValidCRLForCertificate(&targetCertificate, &crl, 0, NULL))

//crlが targetCertificateの無効化検査の目的に適切であるかを検査

// CertIsValidCRLForCertificate()ではcrl中のエントリの検索は行わない

(

CertFindCertificationInCRL(&targetCertificate, &crl,

0, 0, hit);

//crl中に targetCertificateに相当するエントリが存在するときには

//hitにエントリへのポインタをセットする

}

4.1.4 証明書のストアへの登録/削除

(1) 入力

登録する証明書 証明書ストア

(2) 出力

検証の成否

(3) 説明

一つのサイトにおいて複数の証明書が扱われることが通常であることから、

62

一部の APIは、複数の証明書を取り扱うための手段として、証明書ストアの機能をサポートする。 証明書ストアには、証明書が格納される他、CRLや CTLも格納される。 証明書ストアでは、証明書は符号化された状態ではなく、検索時などに属性

にアクセスしやすいように、オブジェクトか構造体に変換されて格納されるこ

とが普通である。

(4) 例

//Example based on CryptoAPI

DWORD encodeType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;

CertAddEncodedCertificateToStore(store, encodeType, encodedCert,

encodedCertSize, CERT_STORE_ADD_REPLACE_EXISTING, NULL);

//encodedCertは符号化された公開鍵証明書のバイト列へのポインタ

//encodedCertSizeは符号化証明書の長さを与える DWORD

//encodedCertが指す符号化証明書を復号し、CERT_CONTEXT として storeに格納

//store中に既に対応する証明書が存在するときには置き換える

4.1.5 ストア中の証明書の検索

(1) 入力

証明書ストア 検索条件

(2) 出力

検索の成否 検索された証明書

(3) 説明

証明書ストア中から検索条件に適合する証明書を検索する。

63

(4) 例

//Example based on CryptoAPI

DWORD encodeType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;

CERT_CONTEXT *foundCertificatep;

foundCertificatep = CertFindCertificateInStore(store, encodeType, 0,

CERT_FIND_SUBJECT_STR, subjectName, &foundCertificate);

//subjectNameで指定されるサブジェクト名をもつ証明書を検索

//条件に合う証明書が見つかれば見つかった証明書へのポインタ、

//見つからなければ NULLを返す

4.1.6 ストア中の証明書チェインの検索

(1) 入力

証明書ストア 検索条件

(2) 出力

検索の成否 検索された証明書チェイン

(3) 説明

証明書ストア中から検索条件に適合する証明書チェインを検索する。

64

4.2 セキュア通信

セキュア通信は、通信者間での通信を保護することを目的とした通信プロトコル

を指す。 セキュア通信プロトコルは、通信者間で認証と鍵交換を行うことでセッションを

確立するハンドシェイクプロトコルと、交換された鍵に基づきセッション中で保護

されたメッセージを交換するプロトコル(SSL/TLSではレコードレイヤプロトコルと呼ばれる)とから構成される。 メッセージの保護とは以下の機能の組み合わせを意味する。

暗号化によるメッセージ秘匿(confidentiality) MACによる改ざん防止(message integrity) デジタル署名によるメッセージ認証(originator authentication)

セキュリティ API は、具体的なプロトコルを抽象した汎用的なレベルでの APIを提供するカテゴリと、具体的なプロトコル(SSL/TLS, Kerberos, SPKM)に従ってセキュア通信の機能を提供するカテゴリとに分類される。

4.2.1 抽象レベルのハンドシェイクプロトコル

(1) 入力

通信相手の識別子

(2) 出力

保護された通信セッション

(3) 説明

抽象レベルの APIでは、上位のアプリケーションに対しては具体的なプロトコルを隠蔽し、下位のプロトコルメカニズムの実装者に対しては共通のフレー

ムワークを提供する。 セキュア通信のためのプロトコルには、一方向(unilateral)認証と双方向(bilateral)の認証の選択、メッセージ秘匿性(confidentiality)の有無の選択を許すものがあるので、高次の APIでもアプリケーションがこれらの選択ができるように機能を提供する。

65

(4) 例

抽象レベルのセキュア通信のための機能を提供する API として、GSS-APIがある。以下では、GSS-APIを例にとって、セキュア通信のためのハンドシェイクプロトコルの実行手続きを見る。

GSS-API では、公開鍵証明書などのユーザの認証情報は credentials というオブジェクトに抽象される。具体的なプロトコルによって認証情報

は異なるので、credentials は完全に非透過(opaque)であるとともに、複数のプロトコルに対応する複数の認証情報を含むことが許される。

通信者同士で交換されるメッセージは、token というオブジェクトで抽象される。実際に交換されるメッセージの内容もフォーマットもプロト

コル依存であるので、tokenは完全に非透過である。 セッションの確立のためのラウンド数(メッセージ往復の回数)はプロトコルの種別に依存するため、GSS-APIでも任意数の tokenを交換できるようになっている。具体的には、GSSContextクラスのオブジェクト

に対して isEstablished メソッドを投げ、返り値が false である間

は token の交換を継続することで、ベースとなるプロトコルが必要とするラウンド数を実行できるようにしている。

まず、能動的にセッションの開始を意図するユーザ(オリジネータ)のプロ

グラム例を示す。

//Example based on GSS-API

GSSManeager manager = GSSManager.getInstance()

GSSContext context = manager.createContext(targetName, protocolOid,

myCredential, lifetime);

//targetName:通信相手の識別名(GSSName)

//protocolOid:具体的なプロトコルを指定する OID(Oid)

//myCredential:オリジネータの認証情報(GSSCredential)

//lifetime:セッションの寿命(int)

context.requestConf(true); //メッセージ秘匿性の要求

context.requestMutualAuth(true); //双方向認証の要求

66

byte[] iToken = new byte[0];

byte[] oToken = new byte[0];

do{

oToken = context.initSecContext(iToken, 0, iToken.length);

//oToken: アクセプタに送付するべきメッセージの出力

//iToken: アクセプタから送付されたメッセージの入力

if (oToken != null) send(oToken); //メッセージの送信

if (context.isEstablished()) break; //セッションの確立を検査

iToken = receive(); //通信相手からのメッセージの受信

}while(true); //セッションが確立するまでメッセージの交換を継続

次に、通信相手からの要求を受け、セッションを受け入れるユーザ(アクセ

プタ)のプログラム例を示す。

//Example based on GSS-API

GSSManager manager = GSSManager.getInstance()

GSSContext context = manager.createContext(myCredential);

//myCredentials:アクセプタの認証情報(GSSCredential)

byte[] oToken = new byte[0];

byte[] iToken = new byte[0];

do {

iToken = receive();

//オリジネータからのメッセージを受信

oToken = context.acceptSecContext(iToken, 0, iToken.length);

//oToken:オリジネータに送付するメッセージの出力

//iToken:オリジネータから送付されたメッセージの入力

if (oToken != null) send(oToken); //メッセージを送信

67

if (context.isEstablished()) break; //セッションの確立を検査

}while{true} //セッションが確立するまでメッセージの交換を継続

4.2.2 抽象レベルのメッセージ保護

(1) 入力

保護された通信セッション 平文の送信メッセージ 保護された受信メッセージ

(2) 出力

保護された送信メッセージ 平文の受信メッセージ

(3) 説明

前述のシェイクハンドプロトコルによって確立されたセキュアなセッション

上で、保護されたメッセージを交換する。

(4) 例

前節の例でのハンドシェイクプロトコルに引き続いて、セッションのオリジ

ネータがメッセージを送信するプログラム例を示す。 送信するメッセージの生成には、wrapメソッドを用いる。wrapメソッドで

は、ハンドシェイクプロトコルで交換した鍵に基づいて、暗号化や MAC 添付などの処理を施された結果が tokenとして出力される。どのような暗号処理を施すかは、ハンドシェイクプロトコルにおいて合意され、その内容は context

オブジェクトに隠蔽される。

//Example based on GSS-API

oToken = context.wrap(message, 0, message.length, 0);

//contextオブジェクトはハンドシェイクプロトコルにおいて設定

//平文のコンテンツ message(byte[])から保護メッセージ oTokenを生成

send(oToken); //メッセージを送信

68

tokenの受信側では、unwrapメソッドを用いる。

//Example based on GSS-API

byte[] massage = new byte[0];

iToken = read(); //保護メッセージを受信

message = context.unwrap(iToken, 0, iToken.length, 0);

//contextオブジェクトはハンドシェイクプロトコルにおいて設定

//受信した保護メッセージ iTokenから平文メッセージを復元

4.2.3 SS/TLS ハンドシェイクプロトコルの実行

(1) 入力

通信相手の識別子(IPアドレス、ホスト名) 通信相手のポート番号

(2) 出力

SSL/TLSセッション

(3) 説明

JSSE で は 、 個 別 の メ ッ セ ー ジ (ClientHello, ServerHello, ServiceKeyExchange, Certificate, CertificateRequest, ServerHelloDone, ClientKeyExchange, CertificateVerify, Finished)と秘密情報master_secretを隠蔽しつつ、SSL或いは TLSのセキュア通信の機能を提供する。 この機能により、アプリケーションの開発者は、SSL 或いは TLS の仕様の詳細を関知することなく、SSL 或いは TLS により保護されるセッションを利用することが可能となる。

(4) 例

SSL(TLS)では、クライアントが ClientHelloメッセージをサーバーに送

付することで、セッションを開始する。即ち、セッションのオリジネータは常

にクライアントである。 以下では、クライアント側での SSL(TLS)ハンドシェイクプロトコルの実行

69

の例を、JSSEに従って示す。JSSEでは、SocketクラスのサブクラスとしてSSLSocketクラスを用意する。SSLSocketクラスは Socketクラスのメソッ

ドをすべて継承しており、また、アルゴリズムなどの暗号処理に関わる設定は

は SSL(TLS)の枠内で合意されるので、アプリケーションは暗号処理を意識することなく、Socket と同じインターフェイスでセッションを確立することが

できる。

//Example based on JSSE

SSLSocketFactory factory =

(SSLSocketFactory)SSLSocketFactory.getDefault();

SSLSocket secureSocket = (SSLSocket)factory.createSocket(host, port);

//ホスト名とポート番号を指定して SSLSocketを生成

secureSocket.setEnableSesstionCreation(TRUE);

//生成した SSLSocketの上で新しいセッションを張ることを許可

String[] enabledCS = secureSocket.getEnabledCipherSuites();

//利用可能な CipherSuiteを事前に確認

BOOLEAN clientAuthNecessary = secureSocket.getNeedClientAuth();

//クライアント認証の必要の有無を事前に確認

secureSocket.startHandshake();

//ハンドシェイクプロトコルを実行

String[] supportedCS = secureSocket.getSupportedCipherSuite();

//サーバーとの間で実際に合意された CipherSuiteを取得

4.2.4 SSL/TLS のレコードレイヤプロトコルの実行

(1) 入力

SSL/TLSセッション 平文の送信メッセージ 保護された受信メッセージ

70

(2) 出力

保護された送信メッセージ 平文の受信メッセージ

(3) 説明

SSL(TLS)は、ハンドシェイクプロトコルによるセッションの確立後、レコードレイヤプロトコルにおいてサーバーとクライアントとの間で保護された

メッセージを交換する。

(4) 例

JSSE の SSLSocket オブジェクトは、Socket クラスのメソッドを全て継

承しているので、通常の Socketオブジェクトと同じインターフェイスで SSLセッションを介して保護されたメッセージの交換が可能である。

//Example based on JSSE

OutputStream os = secureSocket.getOutputStream();

//暗号化はアプリケーションから隠蔽され、送信メッセージは osを介して送られる

InputStream is = secureSocket.getInputStream();

//復号はアプリケーションから隠蔽され、受信メッセージは isを介して取得される

71

4.3 鍵交換

セキュリティ API がセキュア通信におけるハンドシェイクプロトコルの実行機能を提供している場合、鍵交換は暗黙的に実行される。 一方、より低次元の機能を提供しているセキュリティ APIでは、明示的に鍵交換を実行する機能を提供する。

4.3.1 公開鍵に基づく鍵交換

(1) 入力

鍵交換アルゴリズム オーナーの私有鍵、或いは、公開鍵ペア 通信相手の公開鍵、或いは、公開鍵証明書 アルゴリズムパラメータ

(2) 出力

交換された鍵

(3) 説明

公開鍵による鍵共有は、SSL や TLS のハンドシェイクプロトコルにおいても利用されており、非常に重要な暗号機能である。 鍵交換の API関数では、鍵交換のアルゴリズムの識別子を関数呼び出しの際の入力引数に指定する設計をとることが通常である。個別のアルゴリズムごと

に API関数を定義するのではなく、アルゴリズムを入力引数に指定する設計により、API関数の定義は共通のまま、複数のアルゴリズムなどをサポートすることが可能となり、個別のプロバイダによる実装の差異を隠蔽したり、将来の

拡張や輸出規制にも柔軟に対応することが可能となる。例えば、暗号アルゴリ

ズムを追加する際には、入力引数の許容値に新たなアルゴリズム識別子を追加

すれだけでよく、API関数の定義そのものを変更する必要はない。

(4) 例

JCEでは、鍵交換のために KeyAgreementクラスを用意しており、二者間

及び n者間の Diffie-Hellman鍵交換をサポートしている。 以下は二者間の鍵交換の例である。

72

//Example based on JCE

KeyAgreement ownerKeyAgree = KeyAgreement.getInstance(“DH”);

//Diffie-Hellman鍵交換を実行するための KeyAgreementオブジェクトを生成

ownerKeyAgree.init(ownerPrivateKey);

//KeyAgreementオブジェクトにオーナの私有鍵を設定

ownerKeyAgree.doPhase(opponentPublicKey, TRUE);

//通信相手の公開鍵を設定

byte[] sharedSecret = ownerKeyAgree.generateSecret();

//交換した共有鍵(バイト列)の取り出し

次に n者間の Diffie-Hellman鍵交換の例を示す。 各ユーザ(i = 1, …, n)は、各々、KeyAgreementオブジェクトを生成して、各自の私有鍵を設定する。

KeyAgreemant keyAgree_i = KeyAgreement.getInstance(“DH”);

keyAgree_i.init(privateKey_i);

ユーザ 1は、以下のように、tmpKey_2を生成してユーザ2に送る。

Key tmpKey_2 = keyAgree_1.doPhase(publicKey_2, FALSE);

ユーザ2は、tmpKey_3 を生成してユーザ 3 に送り、以下、tmpKey_i をユ

ーザ間で順にリレーし、ユーザ nが tmpKey_nを受け取る。

Key tmpKey_3 = keyAgree_2.doPhase(tmpKey_2, FALSE);

… Key tmpKey_ n = keyAgree_ n-1.doPhase(tmpKey_ n-1, FALSE);

73

最終的に、ユーザ nは以下により他のユーザと秘密を共有する。

keyAgree_ n.doPhase(tmpKey_ n, TRUE);

byte[] sharedSecret = keyAgree_ n.generateSecret();

74

4.4 データの暗号化/復号

データの暗号化と復号とは、暗号処理の最も基本的な機能であり、メッセージ秘

匿(Confidentiality)を提供する。 この節では、セキュリティ APIが提供する、低次から高次にわたる暗号化及び復号の機能を整理する。 最も低次の暗号化機能は、暗号化されたデータをそのままバイト列として出力す

るものである。このレベルの暗号化機能は、セキュリティ APIによってサポートされていないメッセージフォーマットやプロトコルを実装する場合に有用であるが、

アルゴリズムやアルゴリズムパラメータなど暗号化データ以外に意識的に取り扱わ

なければならない付随情報が多く、プログラミングは煩瑣になる。 次いで高次の暗号化機能では、構造体またはクラスに暗号化データと付随情報と

を一括して指定して、同じセキュリティ APIの実装を用いるプログラム間では暗号化メッセージの交換に際してこれらの付随情報を隠蔽する。この節では、既存の構

造体(クラス)であるストリームをラッピングすることによる機能の実現と、新た

にクラスを定義することによる実現との 2つを解説する。 さて、構造体やクラスの活用により、プログラミングの複雑さは大幅に軽減され

るが、同一のセキュリティ APIに基づかない限りプログラム間での暗号化データの交換はできない。プラットフォームやローカルな実装に依存せず、異種システム間

での完結した交換を実現するために、構造と符号化規則を明確に定義したメッセー

ジ中に暗号化データを埋め込む方法が取られる。相互交換性を実現する暗号化メッ

セージの規定としては、PKCS #7が実質的な標準の位置を占めている。この節では、最も高次の暗号化機能として、PKCS #7 EnvelopedDataメッセージの生成と復号の機能を述べる。 また、暗号化/復号に用いられる鍵を、単なるバイト列ではなく、アルゴリズム

やアルゴリズムパラメータと関連付けられたオブジェクトとして扱う機能も、広く

セキュリティ APIに採用されている。この節では、鍵オブジェクトとその暗号化及び復号についても、解説を行う。

4.4.1 単純な暗号化データの生成

(1) 入力

暗号アルゴリズムの識別子 ブロック暗号アルゴリズムにおける利用モード パディングアルゴリズムの識別子

75

アルゴリズムパラメータ 暗号化に用いる鍵 平文のバイト列

(2) 出力

暗号文のバイト列

(3) 説明

最も原始的な暗号化関数では、出力となる暗号文に特定の形式(フォーマッ

ト)を想定せず、平文のバイト列を入力として受け取り、暗号文のバイト列を

出力する。 暗号化のための API関数は、暗号アルゴリズム、共通鍵によるブロック暗号の場合の利用モード、及び、パディングアルゴリズムの指定を入力として受け

取る。個別のアルゴリズムごとに API関数を定義するのではなく、アルゴリズムを入力引数に指定する設計により、API関数の定義は共通のまま、複数の暗号アルゴリズムなどをサポートすることが可能となり、個別のプロバイダによ

る実装の差異を隠蔽するなど、将来の拡張や輸出規制にも柔軟に対応すること

が可能となる。例えば、暗号アルゴリズムを追加する際には、入力引数の許容

値に新たな値を追加すればよく、API関数の定義そのものを変更する必要はない。 鍵は、鍵データ(鍵オブジェクト)を入力引数に指定する他、公開鍵を暗号

化に用いる際には証明書を指定できるケースもある。 暗号化の方式によっては、データの暗号化には、暗号アルゴリズム、利用モ

ード、パディングアルゴリズム、暗号化鍵に加えて、アルゴリズムパラメータ

が必要となる場合がある。次の 2つは、代表的なアルゴリズムパラメータの例である。

CBC、CFB、OFBモードにおけるイニシャルベクタ(IV) PBEにおける saltと iteration count

暗号化関数の実行に当たっては、当然、アルゴリズムパラメータを入力引数

に明示的に指定することができるが、省略を許す実装も多い。アルゴリズムパ

ラメータが省略された場合は、システムが自動的にアルゴリズムパラメータを

生成する。 一方、復号時には、暗号化に用いたと同じアルゴリズムパラメータが必要に

なる。そのため、原始的な暗号化関数を用いた場合には、暗号化メッセージの

送信者はアルゴリズムパラメータを明示的に受信者に送付しなければならない。

76

システムが自動的にアルゴリズムパラメータを生成する場合には、送信者はシ

ステムに問い合わせてアルゴリズムパラメータを取り出し、得られたアルゴリ

ズムパラメータを受信者に送付する手順をとることとなる。この点で、暗号文

のバイト列を直接扱う暗号化機能はプリミティブであるが故に融通がきく反面、

プログラミングは煩瑣になる。

(4) 例

JCEでは、Cipherクラスにより、暗号化/復号の機能が提供される。 以下は共通鍵暗号アルゴリズムによる暗号化手順の例である。

//Example based on JCE

Cipher e = Cipher.getInstance(“DES/CBC/SSL3Padding”);

/*SSL にしたがってパディングした平文に対して、DES の CBC モードで暗号化/復号を実行する

Cipherオブジェクトを生成*/

e.init(ENCRYPT_MODE, myKey);

/*生成した Cipherオブジェクトを暗号化の目的で使用、鍵として myKeyを指定*/

e.doFinal(clearText, offset, length, cipherText);

/*平文のバイト列 clearTextを指定された方式で暗号化し、バイト列 cipherTextに出力*/

上記の例では、Cipher オブジェクトが暗黙的にイニシャルベクタを生成し

ている。送信者は、以下の手順でイニシャルベクタを取得し、直列化した後、

暗号文と共に受信者に渡す。

//Example based on JCE

AlgorithmParameters iv = e.getParameters();

/*イニシャルベクタを AlgorithmParametersオブジェクトとして取得する*/

byte[] encodedIV = iv.getEncoded();

/*受信者に送信するためにイニシャルベクタを直列化する*/

公開鍵暗号に基づく暗号化も、共通鍵暗号の場合と同様の手順で実行される。

77

次の例は OAEPと RSAによる暗号化手順である。

//Example based on JCE

Cipher c = Cipher.getInstance(“RSA/NONE/OAEPwithMD5AndMGF1Padding”)

//OAEPwithMD5AndMGF1Paddingにしたがってパディングした平文に対して、

//RSAにより暗号化/復号を実行する Cipherオブジェクトを生成

c.init(ENCRYPT_MODE, certificate)

//生成したオブジェクトを暗号化の目的で使用、

//暗号化のための公開鍵は証明書オブジェクト certificateにより指定

c.doFinal(clearText, offset, length, cipherText)

//平文のバイト列 clearTextを指定された方式で暗号化しバイト列 cipherTextに出力

4.4.2 単純な暗号化データの復号

(1) 入力

暗号アルゴリズムの識別子 ブロック暗号における利用モード パディングアルゴリズムの識別子 アルゴリズムパラメータ 復号に用いる鍵 暗号文のバイト列

(2) 出力

平文のバイト列

(3) 説明

入力となる暗号文に特定の形式(フォーマット)を想定せず、暗号文のバイ

ト列を入力として受け取り、平文のバイト列を出力する。

(4) 例

前節の例において、DESで暗号化した cipherTextを復号する例を示す。

78

暗号化は CBC モードで行われているので、受信者は、直列化されたイニシャルベクタ encodedIVを送信者から受け取る必要がある。

//Example based on JCE

AlgorithmParameters iv;

iv = AlgorithmParameters.getInstance(“DES/CBC/SSL3Padding);

iv.init(encotedIV);

//直列化されたイニシャルベクタをオブジェクトに変換

Cipher d = Cipher.getInstance(“DES/CBC/SSL3Padding”);

d.init(DECRYPT_MODE, myKey, iv)

//Cipherオブジェクトを復号目的で使用、復号のための鍵とイニシャルベクタを設定

d.doFinal(cipherText, offset, length, clearText);

//暗号文のバイト列 cipherTextを指定された方式で復号し、バイト列 clearTextに出力

4.4.3 ストリーム中のデータの暗号化/復号

(1) 入力

暗号アルゴリズム ブロック暗号における利用モード パディングアルゴリズム 暗号化(復号)のための鍵 アルゴリズムパラメータ ストリームのハンドル

(2) 出力

暗号化した(復号した)データのストリームへの書き込み 暗号化した(復号した)データのストリームからの読み出し

(3) 説明

ストリーム中のデータに対する暗号化(復号)の処理を隠蔽し、ストリーム

の読み書きと同じインターフェイスで、暗号化データを扱える機能を提供する。 具体的には、以下のような操作が可能となる。

暗号化データを格納するストリームに対して、通常のインターフェイスでデータの読み出しを実行することで、復号された平文のデータを得る。

暗号化データを格納するストリームに対して、通常のインターフェイス

79

でデータの書き出しを実行することで、平文データを暗号化した結果を

ストリームに書き出す。 平文データを格納するストリームに対して、通常のインターフェイスでデータの読み出しを実行することで、暗号化されたデータを得る。

平文データを格納するストリームに対して、通常のインターフェイスでデータの書き出しを実行することで、暗号化データを復号した結果をス

トリームに書き出す。

(4) 例

JCEでは、CipherInputStreamクラスと CipherOutputStreamクラス

を用意して、ストリーム上での暗号化データの操作を提供している。

CipherInputStream オブジェクトに対しては、FileInputStream オブ

ジェクトと Cipher オブジェクトとを関連付けることができる。

CipherInputStreamオブジェクトに readメソッドを投げると、関連付けら

れた FileInputStream オブジェクトから読み出されたデータに対して、

Cipher オブジェクトによる処理を施した結果が読み出される。逆に、

CipherOutputStream オブジェクトに write メソッドを投げると、データ

に対して Cipherオブジェクトによる処理を施した結果を、関連付けられてい

る FileOutputStreamオブジェクトに書き出す。

以下の例は、DESで暗号化されたデータを格納するストリームからデータを読み出し、データを復号した後 AESで最暗号化して別のストリームに書き出すプログラムである。

//Example based on JCE

FileInputStream input;

FileOutputStream output;

CipherInputStream decryptedInput;

CipherOutputStream encryptedOutput;

Cipher d = Cipher.getInstance(DES/NONE/NoPadding);

d.init(DECRYPT_MODE, desKey);

//Cipherオブジェクト dを DESによる復号用に設定

Cipher e = Cipher.getInstance(AES/NONE/NoPadding);

e.init(ENCRYPT_MODE, aesKey);

80

//Cipherオブジェクト eを AESによる暗号化用に設定

input = new FileInputStream(“desEncrypted.txt”);

output = new FileOutputStream(“aesEncrypted.txt”);

decryptedInput = new CipherInputStream(input, d);

//decryptedに readを投げると、inputから読み出した暗号文のバイト列を

//DESで復号した結果が読み出されるように設定

encryptedOutput = new CipherOutputStream(output, e);

//encryptedに writeを投げると、平文のバイト列を

//AESで暗号化した結果を outputに書き出すように設定

byte[] buffer = new byte[16];

//AESは 128ビット長のブロックを処理するので、128ビットずつ読み出す

int len = decryptedInput.read(buffer);

/*inputからデータを読み出し、DESで復号した後、bufferに格納する*/

while (len != -1) {

encryptedOutput.write(buffer, 0, len);

/*bufferの内容を AESで暗号化した後、outputに書き出す*/

len = decryptedInput.read(buffer);

}

4.4.4 完備な暗号文オブジェクトの生成

(1) 入力

暗号アルゴリズム ブロック暗号における利用モード パディングアルゴリズム 暗号化のための鍵 平文データ

81

アルゴリズムパラメータ

(2) 出力

完備な暗号文オブジェクト

(3) 説明

先述したように、単純なバイト列として暗号化データを出力する原始的な暗

号化関数では、暗号化データに加えて、暗号アルゴリズムやイニシャルベクタ

などのアルゴリズムパラメータを受信者に対して明示的に送信する手間が必要

であった。これに対し、一部のセキュリティ APIでは、復号に必要な情報を予め暗号文に添付し、完備な暗号文オブジェクトを生成する手段を提供する。 これにより、受信者が同じセキュリティ APIを用いている限り、暗号文オブジェクトを引き渡すだけで復号を実行することが可能となる。

(4) 例

JCEでは、完備な暗号文オブジェクトとして SealedObjectクラスを用意

している。 暗号文の送信者は、以下の手順で SealedObject オブジェクトを生成し、

受信者に送付する。復号のために必要な情報は SealedObject オブジェクト

に添付されるので、特に、送信者がイニシャルベクタを別途受信者に送付する

必要はない。

//Example based on JCE

Cipher e = Cipher.getinstance(“DES/CBC/NoPadding”);

c.init(ENCRYPT_MODE, key);

SealedObject cipherObj = new SealedObject(document, e)

//バイト列 document を Cipher オブジェクトで暗号化した結果から cipherObj を生成

//Cipherオブジェクトが生成したイニシャルベクタは cipherObjに添付

82

4.4.5 完備な暗号文オブジェクトの復号

(1) 入力

復号のための鍵 完備な暗号文オブジェクト

(2) 出力

平文データ

(3) 説明

暗号化オブジェクト中には、アルゴリズムやイニシャルベクタなどのアルゴ

リズムパラメータが同梱されているため、オブジェクトの受信者は、復号のた

めの鍵にさえアクセスできれば、付随的な通信なしで平文データの復号が可能

となる。

(4) 例

暗号文の受信者は、復号のための鍵を共有するだけで、暗号文を復号するこ

とができる。下記の例では、Cipher オブジェクトもシステムによって自動的

に生成される。

//Example based on JCE

String plainText = (String)cipherObj.getObject(key);

//getObject メソッドは復号に必要な Cipherオブジェクトを自動的に生成

4.4.6 PKCS #7 EnvelopedData の生成

(1) 入力

データの暗号化アルゴリズムの識別子 データ鍵の暗号化アルゴリズムの識別子 受信者の公開鍵証明書(複数可) 暗号化の対象となるデータ(バイト列)

83

(2) 出力

PKCS #7 EnvelopedDataタイプのメッセージ

(3) 説明

PKCS #7 EnvelopedDataの生成では、データを共通鍵暗号アルゴリズムで暗号化した後、暗号化に用いた共通鍵(データ鍵)を受信者の公開鍵で暗号化

する。暗号化されたデータ、暗号化されたデータ鍵、及び、データ鍵の暗号化

に用いた公開鍵の証明書は ASN.1に従って符号化され、EnvelopedDataデータ中に格納される。 メッセージの受信者を複数設定することが許されるので、データ鍵は複数の

公開鍵で暗号化され、対応する証明書も複数指定することができる。

(4) 例

CryptoAPI では、バイト列で与えられるデータから、EnvelopedData タイプのメッセージを生成する関数を用意している。

//Example based on CryptoAPI

BYTE *content = (BYTE *)”This is a sample text to be enveloped.”;

DWORD contentSize = strlen((char *) content)+1;

DWORD envelopedMessageSize;

//パラメータの設定を開始

CRYPT_ENCRYPT_MESSAGE_PARA prams;

params.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);

params.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;

//PKCS #7 と X.509の符号化ルールをサポート

params.hCryptProv = defaultCSP;

params.ContentEncryptionAlgorithm.pszObjId = szOID_RSA_RC4;

//コンテンツを RC4で暗号化、RC4鍵を RSAで暗号化

//パラメータの設定を終了

84

CryptEncryptMessage(&params, 1, &recipientCert, content, contentSize,

NULL, &envelopedMessageSize);

//EnvelopedData メッセージのバイト数を取得

BYTE *envelpedMessage = (BYTE *)malloc(envelpedMessageSize);

//EnvelopedData メッセージのための領域を確保

CryptEncryptMessage(&params, 1, &recipientCertPtr, content,

contentSize, envelopedMessage, &envelopedMessageSize);

//EnvelopedData メッセージを envelopedMessageが指す領域に格納

//3番目の引数には受信者の公開鍵証明書の配列を指定するが、この例では 1通のみ

4.4.7 PKCS #7 EnvelopedData の復号

(1) 入力

PKCS #7 EnvelopedDataタイプのメッセージ

(2) 出力

復号されたデータ(バイト列)

(3) 説明

PKCS #7 EnvelopedDataタイプのメッセージには、復号に必要な情報がすべて同梱されているので、メッセージのみを入力として、オリジナルのデータ

を復号することが可能である。

(4) 例

先の例で生成した EnvelopedData データである envelopedMessage を復

号し、平文データを領域 decodedMessageに格納するプログラムを示す。

//Example based on CryptoAPI

//パラメータの設定を開始

CRYPT_DECRYPT_MESSAGE_PARA params;

85

params.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA);

params.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;

//PKCS #7 と X.509の構文・符号化規則をサポート

params.cCertStore = 1;

params.rghCertStore = &defaultCertStore;

//復号のための私有鍵が格納されている CertStoreを指定

//パラメータの設定を終了

CryptDecryptMessage(&params,envelopedMessage,envelopedMessageSize,

NULL, &decodedMessageSize, NULL);

//復号されたデータのバイト数を取得

BYTE *decodedMessage = (BYTE *)malloc(decodedMessageSize);

//EnvelopedData メッセージのための領域を確保

CryptDecryptMessage(&params,envelopedMessage,envelopedMessageSize,

decodedMessage, &decodedMessageSize, NULL);

//復号されたメッセージを decodedMessageが指す領域に格納

4.4.8 鍵オブジェクトの生成

(1) 入力

暗号アルゴリズムの識別子 アルゴリズムパラメータ 鍵長

(2) 出力

鍵データと設定情報を含む鍵オブジェクト

(3) 説明

暗号アルゴリズムや鍵交換アルゴリズム等で用いられる鍵は、データ型として

86

はバイト列であるが、実際には、必ずアルゴリズムやパラメータなどの情報と組

み合わせて利用される。 したがって、鍵データと、その他、鍵利用に際して必須の情報とをひとつのオ

ブジェクトにまとめることで、プログラミングの効率化とプログラムの構造化に

役立つ。

(4) 例

CryptoAPI では、HCRYPTKEY クラスを用意し、そのオブジェクトに鍵に関する必要な情報すべてをバインドできるようにしている。このため、例えばデ

ータの暗号化に際して引数に鍵オブジェクトを指定するだけで、暗号化に必要

な設定情報(暗号アルゴリズム、共通鍵によるブロック暗号の利用モード、パ

ディングアルゴリズム、および、アルゴリズムパラメータ)を指定することが

できるようになり、各種設定情報を追跡する手間を省くことができる。

//Example based on CryptoAPI

HCRYPTKEY keyObj;

//鍵オブジェクトを生成

#define KEYLENGTH 0x0038000

CryptGenKey(hProv, CALG_DES, KEYLENGTH, &keyObj);

//DESの 56ビット鍵をランダムに生成、鍵オブジェクトに設定

Byte mode = CRYPT_MODE_CBC;

CryptSetKeyParam(hProv, keyObj, KP_MODE, &mode, 0)

//鍵オブジェクトを CBCモードに設定

//実際にはデフォルトで CBCモードに設定されるためこのコードは不要

Byte iv[8];

CryptGenRandom(hProv, 8, iv);

//イニシャルベクタのための乱数を生成

CryptSetKeyParam(keyObj, KP_IV, iv, 0);

//鍵オブジェクトにイニシャルベクタを設定

87

4.4.9 鍵オブジェクトの暗号化

(1) 入力

暗号アルゴリズムの識別子 ブロック暗号における利用モード パディングアルゴリズムの識別子 アルゴリズムパラメータ 暗号化に用いる鍵 平文の鍵オブジェクト

(2) 出力

暗号化された鍵データのバイト列

(3) 説明

ハイブリッド暗号方式やエンベロープ方式と呼ばれる手法では、バルクデー

タを暗号化する際に用いた共通鍵を公開鍵で暗号化することで、共通鍵暗号に

よる高い処理効率と公開鍵暗号による鍵配送の利点とを両立させる。このよう

な鍵の暗号化は、暗号通信や鍵管理において重要な手法であり、PKCS #7([PKCS7])の EnvelopedDataデータでも利用されている。 一方、セキュリティ APIでは、鍵は、単なるバイト列ではなく、オブジェクトとして扱われることが普通であるので、鍵オブジェクトを直接暗号化する関

数は有用であり、一部の APIでは鍵オブジェクトを暗号化する関数を提供している。

(4) 例

JCEでは、wrap 関数により、鍵オブジェクトの暗号化が実行される。鍵オブジェクトから鍵データが取り出され、暗号化された後、バイト列に格納され

る。鍵が帰属するアルゴリズムなどの情報は暗号化されない。

//Example based on CryptoAPI

Cipher e = Cipher.getInstance(“RSA/NONE/NoPadding”);

e.init(WRAP_MODE, certificate);

88

byte[] wrappedKey = e.wrap(keyObject);

4.4.10 鍵オブジェクトの復号

(1) 入力

暗号アルゴリズムの識別子 ブロック暗号における利用モード パディングアルゴリズムの識別子 アルゴリズムパラメータ 復号に用いる鍵 暗号化された鍵データのバイト列

(2) 出力

平文の鍵オブジェクト

(3) 説明

暗号化された鍵のバイト列を復号し、鍵オブジェクトを再構成する機能である。

(4) 例

JCEでは、unwrap関数により、鍵オブジェクトの復号が実行される。

//Example based on CryptoAPI

Cipher d = Cipher.getInstance(“RSA/NONE/NoPadding”);

d.init(UNWRAP_MODE, myPrivateKey);

Key unwrappedKey = d.unwrap(wrappedKey, “DES”, SECRET_KEY);

89

4.5 メッセージダイジェスト(一方向性ハッシュ)

メッセージダイジェストは、メッセージデータに一方向性ハッシュ関数を施して

得られる固定長のデータであり、デジタル署名によるメッセージ認証や、改ざん検

知などの機能の実現に利用される。 この節では、一方向性ハッシュ関数の出力をそのままバイト列として出力する低

次の機能と、ダイジェスト付きメッセージの交換形式をサポートする高次の機能と

を解説する。ダイジェスト付きメッセージの交換形式の規定としては、PKCS #7 DigestedDataが標準であることから、PKCS #7に限定して解説する。 メッセージ認証コードに利用される、HMAC などの鍵付一方向性ハッシュ関数

(keyed hash function)に関しては、次節で述べる。

4.5.1 単純なハッシュデータの計算

(1) 入力

ハッシュアルゴリズムの識別子 ハッシュをとるバイト列

(2) 出力

ハッシュ値であるバイト列

(3) 説明

メッセージに対するハッシュ値を計算し、そのままバイト列として出力する。

(4) 例

CryptoAPIでは HCRYPTHASHクラスが用意される。HCRYPTHASHクラスの

オブジェクトは、ハッシュアルゴリズムと関連付けて生成され、

CryptHashData関数により計算されたハッシュ値を保持する。ハッシュ値の

取出しには、CryptGetHashParam関数を用いる。

//Example based on JCE

HCRYPTHASH hashObj;

//ハッシュオブジェクトを生成

90

BYTE hashValue[20];

DWORD hashValueLen = 20;

CryptCreateHash(csp, CALG_SHA, 0, 0, &hashObj);

//ハッシュ関数アルゴリズム SHAをハッシュオブジェクトに設定

//cspは CSPの特定のハンドルであるが、この例では意味はない

CryptHashData(hashObj, content, contentLen, 0);

//content[]に指定されたバイト列のハッシュ値を計算

CryptGetHashParam(hashObj, HP_HASHVAL, hashValue, &hashValueLen, 0);

//ハッシュ値を hashValue[20]にバイト列として取り出す

4.5.2 PKCS #7 DigestedData の生成

(1) 入力

ハッシュアルゴリズムの識別子 ハッシュ対象のバイト列

(2) 出力

PKCS #7 DigestedData型のメッセージ

(3) 説明

入力のバイト列に対してハッシュ値を計算し、オリジナルのデータと計算し

たハッシュ値とを併せて ASN.1 に従って符号化し、PKCS #7 DigestedDataタイプのメッセージを生成する。

(4) 例

//Example based on CryptoAPI

BYTE *content = (BYTE *)”This is a sample text to be hashed.”;

DWORD contentSize = strlen((char *) content)+1;

DWORD digestedMessageSize;

91

//パラメータの設定を開始

CRYPT_HASH_MESAGE_PARA params;

params.cbSize = sizeof(CRYPT_HASH_MESSAGE_PARA);

params.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;

//PKCS #7 と X.509の符号化ルールをサポート

params.hCryptProv = NULL;

params.HashAlgorithm.pszObjId = szOID_RSA_MD5;

//ハッシュアルゴリズムとして MD5を指定

params.pvHashAuxInfo = NULL;

//パラメータの設定を終了

CryptHashMessage(&params, FALSE, 1, &content, &contentSize, NULL,

&digestedMessageSize, NULL, NULL);

//DigestedData メッセージのための領域を確保

BYTE *digestedMessage = (BYTE *)malloc(digestedMessageSize);

//DigestedData メッセージのための領域を確保

CryptHashMessage(&params, FALSE, 1, &content, &contentSize,

digestedMessage, &digestedMessageSize, NULL, NULL);

//DigestedData メッセージを digestMessageが指す領域に格納

4.5.3 PKCS #7 DigestedData の検証と復号

(1) 入力

PKCS #7 DigestedData型のメッセージ

(2) 出力

ハッシュ値の検証の成否 復号されたデータ(バイト列)

92

(3) 説明

PKCS #7 DigestedDataデータ内のメッセージは ASN.1で符号化されているので、まずメッセージを復号し、ハッシュ値を計算する。計算したハッシュ

値を、同メッセージ内に添付されているハッシュ値と比較し、一致すれば検証

成功を返す。

(4) 例

//Example based on CryptoAPI

BOOLEAN rslt;

rslt = CryptVerifyMessageHash(&params, digestedMessage,

digestedMessageSize, NULL, &decodedMessageSize, NULL, NULL))

//ハッシュ値の検査の結果を rsltに格納

if (rslt) {

BYTE *decodedMessage = (BYTE *)malloc(decodedMessageSize);

//復号データのための領域を確保

CryptVerifyMessageHash(&params,DigestedMessage,digestedMessageSize,

decodedMessage, &decodedMessageSize, NULL, NULL);

//復号データを decodeMessageが指す領域に格納

}

93

4.6 デジタル署名

メッセージデータに対するデジタル署名も、バイト列としての署名値そのものを

出力する低次の機能と、メッセージにデジタル署名が添付された交換形式のメッセ

ージを出力する高次の機能とが提供される。デジタル署名付きメッセージの交換形

式の標準は、PKCS #7 SignedDataであるので、この節では SignedDataに限定して説明を行う。

4.6.1 単純な署名値の計算

(1) 入力

一方向性ハッシュアルゴリズムの識別子 署名アルゴリズムの識別子 署名鍵 署名対象のバイト列

(2) 出力

署名値を与えるバイト列

(3) 説明

メッセージの署名値を計算し、そのままバイト列として出力する。 DSSが署名アルゴリズムとして指定された場合には、一方向性ハッシュアル

ゴリズムは SHA-1が用いられる。

(4) 例

CryptoAPIでは、HCRYPTHASHオブジェクトを介して、バイト列として署名値を生成する関数が用意されている。署名鍵は、署名鍵と関連付けられた CSPのハンドルを HCRYPTHASHオブジェクトの生成時に指定することで、特定され

る。

//Example based on CryptoAPI

HCRYPTPROV csp;

HCRYPTHASH hashObj;

94

CryptAcquireContext(&csp, NULL, NULL, PROV_RSA_FULL, 0);

//デフォルトの鍵コンテナーと関連付けられたデフォルトの CSPのハンドルを cspに設定

//PROV_RSA_FULLにより署名アルゴリズムとして RSA-MD5をサポート

CryptCreateHash(csp, CALG_MD5, 0, 0, &hashObj);

//cspはユーザの RSA署名鍵と関連付けられた CSPのハンドル

CryptHashData(hashObj, content, contentLen, 0);

//計算されたハッシュ値は hashObjに保持

DWORD sgntrLen;

CryptSignHash(hashObj, AT_SIGNATURE, NULL, 0, NULL, &sgntrLen);

BYTE *signature = (BYTE *)malloc(sgntrLen);

//署名を格納する領域を確保

CryptSignHash(hashObj, AT_SIGNATURE, NULL, 0, signature, &sgntrLen);

//hashObjは cspを特定、cspはユーザの RSA署名鍵を特定

//hashObjが保持するハッシュ値に対して、cspに関連付けられた RSA署名鍵で署名を生成

//署名値はバイト列として signatureに格納

4.6.2 単純な署名値の検証

(1) 入力

ハッシュアルゴリズムの識別子 署名アルゴリズムの識別子 署名検証鍵 署名対象のバイト列 署名値を与えるバイト列

(2) 出力

検証の成否

95

(3) 説明

バイト列で与えられた署名値を直接検証する機能である。

(4) 例

前節の例で生成された signatureを検証する CryptoAPIの関数を示す。

//Example based on CryptoAPI

BOOLEAN r;

r = CryptVerifySignature(hashObj,signature,sgntrLen,pubKey,NULL,0);

//pubKeyは検証鍵を指定

4.6.3 PKCS #7 SignedData の生成

(1) 入力

ハッシュアルゴリズムの識別子 署名アルゴリズムの識別子 署名鍵及び対応する公開鍵証明書 公開鍵証明書の列 署名対象のバイト列

(2) 出力

PKCS #7 SignedData型メッセージ

(3) 説明

メッセージデータに対してデジタル署名を計算し、オリジナルのメッセージ

データと署名値とを併せて符号化し、SignedDataメッセージを生成する。 SignedData メッセージ中には、メッセージデータと署名値だけではなく、一方向性ハッシュ及び署名のアルゴリズムと公開鍵(証明書)など署名の検証

に必要な情報とが同梱される。

96

(4) 例

以下は CryptoAPIによる例である。

//Example based on CryptoAPI

BYTE *content = (BYTE *)”This is a sample text to be signed.”;

DWORD contentSize = strlen((char *) content)+1;

DWORD signedMessageSize;

//パラメータの設定開始

CRYPT_SIGN_MESSAGE_PARA params;

params.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);

params.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;

//PKCS #7 と X.509の符号化ルールをサポート

params.pSigningCert = signerCertPtr;

//署名鍵と関連付けられた CERT_CONTEXTへのポインタ

params.HashAlgorithm.pszObjID = szOID_RSA_MD5;

//MD5をハッシュアルゴリズムとして使用

params.HashAlgorithm.Parameter.cbData = NULL;

params.cMsgCert = 1;

params.rgpMsgCert = &signerCertPtr;

//メッセージに同梱する証明書は署名者の一通のみ

params.cAuthAttr = 0;

params.dwInnerContentType = 0;

params.cMsgCrl = 0;

params.cUnauthAttr = 0;

params.dwFlags = 0;

params.pvHashAuxInfo = NULL;

97

params.rgAuthAttr = NULL;

//パラメータの設定終わり

CryptSignMessage(&params, FALSE, 1, &content, &contentSize,

NULL, &signedMessageSize);

//SignedData メッセージのバイト数を取得

BYTE *signedMessage = (BYTE *)malloc(signedMessageSize);

//SignedData メッセージのための領域を確保

CryptSignMessage(&params, FALSE, 1, &content, &contentSize,

signedMessage, &signedMessageSize);

//SignedData メッセージを生成

98

4.6.4 PKCS #7 SignedData の検証と復号

(1) 入力

PKCS #7 SignedData型メッセージ

(2) 出力

署名検証の成否 復号されたデータ(バイト列)

(3) 説明

PKCS #7 SignedDataデータ中のメッセージは ASN.1で符号化されているので、まずメッセージを復号し、次いで署名値を検証する。

(4) 例

前節の例で生成した signedMessageの検証を行う例を示す。 //Example based on CryptoAPI

BOOLEAN rslt;

//パラメータの設定を開始

CRYPT_VERIFY_MESSAGE_PARA params;

params.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);

params.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;

//PKCS #7 と X.509の符号化ルールをサポート

params.hCryptProv = 0;

params.pfnGetSignerCertificate = NULL;

params.pvGetArg = NULL;

//パラメータの設定を終了

rslt = CryptVerifyMessageSignature(&params, 0, signedMessage,

signedMessageSize, NULL, &decodedMessageSize, NULL);

99

//デジタル署名の検査の結果を rsltに格納

if (rslt) {

BYTE *decodedMessage = (BYTE *)malloc(decodedMessageSize);

//復号データのための領域を確保

CryptVerifyMessageSignature(&params, 0, signedMessage,

signedMessageSize, decodedMessage, &decodedMessageSize, NULL);

//復号データを decodeMessageが指す領域に格納

}

100

4.7 メッセージ認証コード(MAC)

4.7.1 単純なMACの計算

(1) 入力

MAC生成アルゴリズム MAC計算のための鍵 認証対象のバイト列

(2) 出力

MACを与えるバイト列

(3) 説明

メッセージからメッセージ認証コードを計算し、そのままバイト列として出

力する。

(4) 例

JCEでは、原始的なMAC生成のために、Macクラスが用意されている。

//Example based on JCE

Mac mac = Mac.getInstance(“HmacSHA1”);

mac.init(macKey);

byte[] macString = mac.doFinal(document);

101

4.8 PKCS #7の複合操作

4.8.1 PKCS #7 SignedAndEnvelopedData の生成

(1) 入力

ハッシュアルゴリズムの識別子 署名アルゴリズムの識別子 署名鍵及び対応する公開鍵証明書 受信者の公開鍵証明書 署名及び暗号化の対象となるデータ(バイト列)

(2) 出力

PKCS #7 SignedAndEnvelopedData型メッセージ

(3) 説明

PKCS #7 SignedAndEnvelpedDataは、PEM([PEM])との互換性のために導入されたデータ型である。 メッセージには署名が施され、共に、共通鍵(データ鍵)を用いて暗号化さ

れる。

(4) 例

以下は CryptoAPIによる例である。

//Example based on CryptoAPI

BYTE *content = (BYTE *)”This is a sample text to be signed and

enveloped.”;

DWORD contentSize = strlen((char *) content)+1;

DWORD signedAndEnvelopedMessageSize;

//パラメータの設定開始

CRYPT_SIGN_MESSAGE_PARA sparams;

102

sparams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);

sparams.pSigningCert = signerCertPtr;

//署名鍵と対応付けられた CERT_CONTEXTのポインタを指定

sparams.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;

//PKCS #7 と X.509の符号化ルールをサポート

sparams.HashAlgorithm.pszObjID = szOID_RSA_MD5;

//MD5をハッシュアルゴリズムとして使用

sparams.HashAlgorithm.Parameter.cbData = NULL;

sparams.cMsgCert = 1;

sparams.rgpMsgCert = &signerCert;

//署名に関連する証明書は署名者の一通のみを同梱

sparams.cAuthAttr = 0;

sparams.dwInnerContentType = 0;

sparams.cMsgCrl = 0;

sparams.cUnauthAttr = 0;

sparams.dwFlags = 0;

sparams.pvHashAuxInfo = NULL;

sparams.rgAuthAttr = NULL;

CRYPR_ENCRYPT_MESSAGE_PARA eparams;

eparams.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);

eparams. dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;

eparams.hCryptProv = 0;

eparams.ContentEncryptionAlgorithm.pszObjId = szOID_RSA_RC4;

//メッセージを RC4で暗号化し、RC4の鍵(共通鍵)を RSAで暗号化

eparams.ContentEncryptionAlgorithm.Parameter.cbData = 0;

103

eparams.dwFlags = 0;

eparams.dwInnerContentType = 0;

//パラメータの設定終わり

CryptSignAndEncryptMessage(&sparams, &eparams, 1, &recipientCert,

content, contentSize, NULL, &signedAndEnvelopedMessageSize);

//SignedAndEnvelopedData メッセージのバイト数を取得

BYTE *signedAndEnvelopedMessage =

(BYTE *)malloc(signedAndEnvelopedMessageSize);

//SignedAndEnvelopedData メッセージのための領域を確保

CryptSignAndEncryptMessage(&sparams, &eparams, 1, &recipientCertPtr,

content, contentSize, signedAndEvelopedMessage,

&signedAndEnvelopedMessageSize);

//SignedAndEnvelopedData メッセージを signedAndEnvelopedMessageに格納

//3番目の引数には受信者の公開鍵証明書の配列を指定するが、この例では 1通のみ

104

4.8.2 PKCS #7 SignedAndEnvelopedData の検証と復号

(1) 入力

復号のための私有鍵 PKCS #7 SignedAndEnvelopedData型メッセージ

(2) 出力

署名検証の成否 復号されたデータ(バイト列)

(3) 説明

格納されている暗号化メッセージとデジタル署名を復号し、署名を検証する。

検証の成否と復号されたメッセージとを返す。

(4) 例

前節の例で生成した signedMessageの検証を行う例を示す。

//Example based on CryptoAPI

BOOLEAN rslt;

//パラメータの設定開始

CRYPT_DECRYPT_MESSAGE_PARA dparam;

dparams.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA);

dparams.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING |

X509_ASN_ENCODING;

//PKCS #7 と X.509の符号化ルールをサポート

dparams.cCertStore = 1;

dparams.rghCertStore = &myCertStore;

//復号のための私有鍵を格納する証明書ストアを指定

105

CRYPR_VERIFY_MESSAGE_PARA vparams;

vparams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);

vparams. dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING |

X509_ASN_ENCODING;

vparams.hCryptProv = 0;

vparams.pfnGetSignerCertificate = NULL;

vparams.pvGetAlg = NULL;

//パラメータの設定終わり

rslt = CryptDeryptAndVerifyMessageSignature(&dparams, &vparams, 0,

signedAndEnvelopedMessage, signedAndEnvelopedMessageSize,

NULL, &decodedMessageSize, NULL, NULL);

if (rslt) {

BYTE *decodedMessage = (BYTE *)malloc(decodedMessageSize);

//復号データのための領域を確保

CryptDeryptAndVerifyMessageSignature(&dparams, &vparams, 0,

signedAndEnvelopedMessage, signedAndEnvelopedMessageSize,

decodedMessage, &decodedMessageSize, NULL, NULL);

//復号データを decodeMessageが指す領域に格納

}

106

5 主要なセキュリティ APIと機能との関係

この章では、前節でまとめたセキュリティ APIの機能に関して、以下にあげる主要なセキュリティ APIの対応状況をまとめる。

JCA [JCA] JCE 1.2.2 [JCE] JSSE 1.0.3 [JSSE] Java Certification Path API [JPATH] CryptoAPI 2.0 [CryptoAPI] GSS-API [GSS-API] GCS-API [GCS-API] CSSM-API 2.3 [CSSM] PKCS #11 2.11 [PKCS11]

これらのセキュリティ APIは、3層アーキテクチャに従い具体的な暗号アルゴリズムから独立となるように設計されているので、厳密な意味ではセキュリティ APIがサポートする暗号アルゴリズムは存在しない。但し、ここでは、以下の原則に基

づいてセキュリティ APIとアルゴリズムの対応関係を述べる。

Javaと CryptoAPIに関しては、それぞれ、Sun MicrosystemsとMicrosoftが供給している CSPがサポートしているもののみを挙げた。

GSS-APIはセキュア通信プロトコルを抽象したセキュリティ APIであり、プリミティブな暗号機能はサポートしないので、アルゴリズムとの対応は記述

しない。 GCS-API と CSSM-API に関しては、それぞれ、[GCS-API]と[GSS-API]中でアルゴリズム識別子が与えられているものを挙げた。

PKCS #11に関しては、[PKCS11]中においてメカニズムが規定されているものを挙げた。

107

表 5-1 既存のセキュリティ APIと主要機能の対応

JCA

JCE

1.2.2

JSS

E 1.03

Java Certification P

ath

CryptoA

PI 2.0

GSS API

GC

S-A

PI

CS

SM

AP

I 2.3

PK

CS

#11 2.11

CTLに基づく証明書の検証 × × × × ○ × × × ×

チェインに基づく証明書の検証 × × × ○ ○ × × ○ ×

CRLに基づく証明書の無効化の検証 × × × ○ ○ × × ○ ×

証明書のストアへの登録/削除 × ○ × × ○ × × ○ ×

証明書のストア中での検索 × ○ × × ○ × × ○ ×

証明書ハンドリング

証明書チェインのストア中での検索 × × × ○ ○ ○ × ○ ×

抽象レベルのハンドシェイクプロトコルの実行 × × × × × ○ × × ×

抽象レベルでの保護メッセージの交換 × × × × × ○ × × ×

SSL/TLSのハンドシェイクプロトコルの実行 × × ○ × × × × × ×

セキュア通信 SSL/TLSのレコードレイヤプロトコルの実行 × × ○ × × × × × ×

公開鍵による鍵交換 × ○ × × ○ × ○ ○ ○

DH-KX × ○ × × ○ × ○ ○ ○

KEA × × × × × × ○ ○ ○

鍵交換

RSA-KX × × × × ○ × × ○ ×

単純な暗号化データの生成/復号 × ○ × × ○ × ○ ○ ○

AES × ○ × × ○ × × × ○

BLOWFISH × ○ × × × × × ○ ×

CAST × × × × × × × ○ ○

CDMF × × × × × × × ○ ○

DES × ○ × × ○ × ○ ○ ○

DES-EDE × ○ × × ○ × × ○ ○

IDEA × × × × × × × ○ ○

PBE × ○ × × × × × ○ ○

RC2 × ○ × × ○ × ○ ○ ○

RC4 × ○ × × ○ × ○ ○ ○

RC5 × ○ × × × × × ○ ○

SKIPJACK × × × × × × ○ ○ ○

暗号化/

復号

RSA × ○ ○ × ○ × ○ ○ ○

108

JCA

JCE

1.2.2

JSS

E 1.03

Java Certification P

ath

CryptoA

PI 2.0

GSS API

GC

S-A

PI

CS

SM

AP

I 2.3

PK

CS

#11 2.11

ストリーム上のデータの暗号化/復号 × ○ × × × × × × ×

完備な暗号オブジェクトの生成/復号 × ○ × × ○ × × ○ ×

PKCS #7 EnvelopedDataの生成 × × × × ○ × × × ×

PKCS #7 EnvelopedDataの復号 × × × × ○ × × × ×

鍵オブジェクトの生成 ○ × × × ○ × ○ ○ ×

鍵オブジェクトの暗号化/復号 × ○ × × × × × × ○

単純なハッシュ値の計算 ○ × × × ○ × ○ ○ ○

MD2 ○ × × × ○ × × ○ ○

MD5 ○ × × × ○ × ○ ○ ○

RIPE-MD × × × × × × × ○ ○

SHA-1 ○ × × × ○ × ○ ○ ○

SSL3-SHAMD5 × × × × ○ × × ○ ×

PKCS #7 HashedDataの生成 × × × × ○ × × × ×

メッセージダイジェスト

PKCS #7 HashedDataの検証と復号 × × × × ○ × × × ×

単純な署名値データの計算と検証 ○ × × × ○ × ○ ○ ○

RSA-MD2 ○ × × × ○ × × ○ ○

RSA-MD5 ○ × × × ○ × × ○ ○

RSA-RIPE-MD × × × × × × × ○ ○

RSA-SHA1 ○ × × × ○ × × ○ ○

SSL3-SS × × × × ○ × × ○ ○

DSA ○ × × × ○ × ○ ○ ○

デジタル署名

PKCS #7 SignedDataの生成と検証/復号 × × × × ○ × × × ×

単純なMACの計算と検証 × ○ × × ○ × ○ ○ ○

HMAC-MD5 × ○ × × ○ × × ○ ○

HMAC-SHA1 × ○ × × ○ × × ○ ○

PBMAC × ○ × × × × × ○ ○

CBC-MAC × × × × ○ × ○ × ×

MA

C

MD5-MAC × × × × × × × × ×

PKCS #7 SignedAndEnvelopedDataの生成 × × × × ○ × × × ×

PKCS #7 SignedAndEnvelopedDataの検証と復号 × × × × ○ × × × ×

109

参考文献

セキュリティ APIに関連する文献

[情経 1095] 13情経第 1095号 電子政府情報セキュリティ技術開発事業 セキュリティ関連 API に関する調査, 情報処理振興事業協会, 平成13年

[J2SE] Java 2 Platform, Standard Edition, v 1.4.2 API Specification, http://java.sun.com/j2se/1.4.2/docs/api/index.html

[JCA] Java Cryptography Architecture API Specification & Reference, http://java.sun.com/j2se/1.4.2/docs/guide/security/CryptoSpec.html, 2002

[JCE] Java Cryptography Extension 1.2.2 API Specification & Reference, http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html, 2002

[JSSE] Java Secure Socket Extension (JSSE) 1.0.3 API User’s Guide, http://java.sun.com/products/jsse/doc/guide/API_users_guide.html

[JPATH] Java Certification Path API Programmer’s Guide, http://java.sun.com/j2se/1.4.2/docs/guide/security/certpath/CertPathProgGuide.html, 2003

[JAAS] Java Authentication and Authorization Service (JAAS) Reference Guide, http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html, 2001

[CryptoAPI] CryptoAPI 2.0, http://msdn.microsoft.com/library

[GSS-API] RFC 1508, Generic Security Service Application Program Interface, IETF, September 1993

[GSS-API Java] RFC 2853, Generic Security Service API Version 2: Java Bindings, IETF, June 2000

110

[GSS-API Kerberos] RFC 1964, The Kerberos Version 5 GSS-API Mechanism, IETF, June 1996

[GSS-API SPKM] RFC 2025, The Simple Public-Key GSS-API Mechanism (SPKM), IETF, 1996

[GCS-API] Generic Cryptographic Service API (GCS-API) Base, http://www.opengroup.org/onlinepubs/008355799/toc.pdf, 1996

[CSSM] Common Security: CDSA and CSSM Version 2.3, Open Group, 2000

[PKCS11] PKCS #11 v2.11: Cryptographic Token Interface Standard, RSA Laboratory, 2001

暗号技術の規格に関する文献

[PKCS1] PKCS #1 v2.1: RSA Encryption Standard, RSA Laboratory, 2002

[PKCS1v1.5] PKCS #1 v1.5: RSA Encryption Standard, RSA Laboratory, 1993

[PKCS3] PKCS #3 v1.4: Diffie-Hellman Key-agreement Standard, RSA Laboratory, 1993

[PKCS5] PKCS #5 v2.0: Password-based Encryption Standard, RSA Laboratory, 1999

[PKCS6] PKCS #6 v1.5: Extended-certificate Syntax Standard, RSA Laboratory, 1993

[PKCS7] PKCS #7 v1.5: Cryptographic Message Syntax Standard, RSA Laboratory, 1993

[PKCS7v16] Extensions and Revisions to PKCS #7, B. Kaliski et al., 1997

[PKCS11] PKCS #11 v2.11: Cryptographic Token Interface Standard, RSA Laboratory, 2001

[DES] FIPS PUB 46, Data encryption standard, 1977

[DES Mode] FIPS PUB 81, DES modes of operation, 1980

[DES MAC1]

111

FIPS PUB 113, Computer data authentication, 1985

[DES MAC2] ISO 8731-1: Banking – Approved algorithm for message authentication – Part 1: DEA, ISO

[SHA] FIPS PUB 180, Secure hash standard, NIST, 1993

[SHA1] FIPS PUB 180-1, Secure hash standard, NIST, 1995

[Skipjack] FIPS PUB 185, Escrowed Encryption Standard (EES), NIST, 1994

[DSS] FIPS PUB 186, Digital signature standard, NIST, 1994

[AES] FIPS PUB 197, Advanced encryption standard, NIST, 2002

[HMAC SHA1] FIPS PUB 198, The Keyed-Hashed Message Authentication Code, NIST, 2002

[DES EDE] ISO 8732, Banking – Key management (wholesale), ISO, 1988

[PEM] RFC 1423, Privacy Enhancement for Internet Electronic Mail: Part III: Algorithms, Modes and Identifiers, IETF, 1993

[MD2] RFC1319, The MD2 message-digest algorithm, IETF 1992

[MD4] RFC 1320, The MD4 message-digest algorithm, IETF, 1992

[MD5] RFC 1320, The MD5 message-digest algorithm, IETF, 1992

[MD5 MAC] RFC 1828, IP authentication using keyed MD5, IETF, 1995

[RC5] RFC 2040, The RC5, RC5-CBC, RC5-CBC-Pad, and RC5-CTS Algorithms, IETF, 1996

[HMAC] RFC 2104, HMAC: Keyed-Hashing for Message Authentication, IETF,

[SSL3.0] The SSL 3.0 Protocol, A.Frier et al, Netscape Communications Corp., 1996

[TLS1.0] RFC 2246, The TLS Protocol Version 1.0, IETF, 1999

[SJKEArfc] RFC 2773, Encryption using KEA and SKIPJACK, IETF, 2000

112

[TLS1.1] The TLS Protocol Version 1.1, Internet Draft, IETF, 2002

[X9.52] ANSI X9.52: Triple Data Encryption Algorithm Modes of Operation, ANSI, 1996

[FOR] NSA X22, Document # PD4002103-1.01, FORTEZZA: Application Implementers Guide, April 6, 1995

その他の文献

[RSA] A Method for Obtaining Digital Signatures and Public-Key Cryptosystems, R. Rivest, A. Shamir, and L. Adleman, Communication of the ACM, v.21, n.2, Feb 1978, pp.120 – 126

[DH] New Directions in Cryptography, IEEE Transactions on Informative Theory, V.IT-22, n.6, Jun 1977, pp.74 – 84

[BCK] Keying Hash Functions for Message Authentication, M.Bellare et al., Proceedings of Advances in Cryptology – Crypto 96, LNCS vol 1109, 1996

[3DES] Hellman Presents No Shortcut Solutions To DES, W.Tuchman, IEEE Spectrum, v.16, n.7, July 1979, pp.40 – 41

[IDEA] On the Design and Security of Block Ciphers, X. Lai, ETH Series in Information Processing, v.1, Konstanz: Hartung-Gorr Verlag, 1992

[RC4] A Stream Cipher Encryption Algorithm, R. Thayer and K. Kaukonen

[BLE] Chosen Ciphertext Attacks against Protocol Based on RSA Encryption Standard PKCS #1, Advances in Cryptology – Proceeding of Crypto’98, LNCS vol.1462, pp.1 – 12, 1998

[SH] OAIP reconsidered, Advance in Cryptology – Proceeding of Crypto’01, LNCS vol.2139, pp 239 – 259, 2001

[FOPS] RSA-OAEP is secure under the RSA assumption, E. Fujisaki et al., Proceeding of Crypto’01, LNCS vol.2139, pp 260 – 274, 2001

[SJKEA] Skipjack and KEA Algorithm Specification version 2.0, http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf, NIST,

113

1998

[SET] SET Secure Electronic Transaction Specification, http://www.setco.org/download.html#spec, 1997

[AppCrpt] Applied Cryptography, B.Schneier, John Wiley & Sons, Inc., 1996

[HandBook] Handbook of Applied Cryptography, K.H.Rosen, CRC Press, 1996

[暗号] 暗号利用技術ハンドブック, 電子商取引実証推進協議会, 平成 10年