暗号データ形式
鍵情報の交換
暗号処理を行う場合,鍵情報の読み書きを行う必要がある.すなわち,鍵情報をファイルに格納したり,ファイルから読み込む,あるいは通信を介して外部システムに鍵情報を転送したりする必要がある.
このとき,鍵情報の形式を考える必要がある.
鍵情報には,次のような形式が用いられている.
- PKCS#7/CMS
署名や暗号化によるデータの格納形式
- PKCS#8
秘密鍵情報を格納する形式(パスワード暗号で暗号化)
- PKCS#12
秘密鍵,証明書等の情報を格納する形式(暗号化,署名等)
- X509
公開鍵証明書の格納形式
上記の鍵情報をエンコードする代表的な方法に次のものがある.
- DER
ITU-T 勧告X.509で定義されているDER(Distinguished Encoding Rules) for ASN.1 は,DERを基にした代替の ITU-T 勧告 X.209 で定義されている
BER (Basic Encoding Rules) for ASN.1
よりも厳格なエンコード標準である.BERもDERもプラットフォームに依存せず,デバイスとアプリケーションとの間で送信するために,証明書やメッセージなどのオブジェクトをエンコードする手段を提供する.
証明書のエンコードにはほとんどのアプリケーションでDERが使用されるが,これは証明書の一部分(証明書要求の証明書要求情報)が,署名を受けるにはDERでエンコードされる必要があるためである. DER
証明書ファイルでは拡張子 .cer が使われる.
- PEM
メールでの転送が可能なBase64エンコードされたテキスト形式である.
ASN.1 (BER/DER)
- 概要
Abstract Syntax Notation One (ASN.1)は,任意のデータ構造を記述可能とするために導入された記法である.
ASN.1文法に沿って記述されたデータ構造のエンコード方法,デコード方法が以下に規定されている.
- BER: Basic Encoding Rules of ASN.1
- DER: Distinguished Encoding Rules of ASN.1
DERは,BERの規定における選択可能な部分を特定し,エンコードデータが一意に決定されるようにしたものである.
エンコードデータの基本構造は,以下のものである.
- Identifier octets
データの型(識別子)
- Length octets
データ長
- Contens octes
データ内容
与えられた値、あるいは型が他の型を参照している場合は参照された型をエンコードしたデータ
データの型には以下の種類がある.
- Simple type(Primitive)
基本的な型で,INTEGER,UTCTime,BIT STRING,OBJECT IDENTIFIERなどがある.
Simple typeを参照することにより新しい型が定義され,またその型も参照されることにより新しい型が定義される.
- Structured type(Constructed)
複数の型から組み立てることにより定義される型でキーワード SEQUENCE,SEQUENCE OF,SET,SET OFを用いる.
型は以下のように定義され,拡張される.
型名 ::= 型定義
(例) AlgorithmIdentifider ::= OBJECT IDENTIFIER
型名 ::= キーワード{
型参照名 型定義,
型参照名 型定義,...}
- 利用例
ASN.1は,複雑なデータ構造の記述やデータの流通性の確保に利用されている. 暗号関連では,以下に示すような暗号関連データのやり取りに利用されている.
- 公開鍵証明書
- 失効リスト(CRL)
- 署名データ,暗号化データ(PKCS#7)
- Personal Information Exchange Syntax(PKCS#12)
ASN.1によるデータフォーマット例を示す.
Validity ::= SEQUENCE {
notBefore UTCTime,
notAfter UTCTime }
CertificateInfo ::= SEQUENCE {
version [0] Version DEFAULT v1988,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo }
Version ::= INTEGER { v1988(0) }
CertificateSerialNumber ::= INTEGER
Validity ::= SEQUENCE {
notBefore UTCTime,
notAfter UTCTime }
SubjectPublicKeyInfo ::= SEQUENCE {
algorithmAlgorithmIdentifier,
subjectPublicKey BIT STRING }
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY ALGORITHM OPTIONAL }
また,DERエンコードの例を以下に示す.
Sequence Length Contents
30 0A
IA5String Length Contents
16 05 "Smith"
Boolean Length Contents
01 01 FF
オブジェクト識別子
公開鍵基盤(PKI)で利用する暗号アルゴリズムや公開鍵証明書内に格納する名前(subject)のタイプ(Country名やCommonNameなどの属性)は,オブジェクト識別子(OBJECT
IDENTIFIER)として登録されたものが利用される. オブジェクト識別子は世界中で唯一に特定可能なものとして,登録機関により管理されている.
例えば,ハッシュアルゴリズムのSHA-1は,
id-SHA1 OBJECT IDENTIFIER ::=
{iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26}
のように定義されており,この値の並び {1, 3, 14, 3, 2, 26} がオブジェクト識別子である.
Base64
Base64は,MIME RFC(RFC 2045)で定義された任意のオクテット値を65文字の英数字に符号化する方式である.
Base64エンコード方式は人間が可読でない任意のオクテット列を表現するためにデザインされている.65文字のUS-ASCIIのサブセット([A-Za-z0-9+/=])が使われ,1つの表示可能な文字に6ビットが割り当てられる.
暗号化された不可視文字データを含むデータをメール等で転送する際に,可視文字に変換するためなどに利用される.
オクテット値3つ(8ビット×3 = 24ビット)を4文字(6ビット×4)で表現する.そのため,データ量は3分の4倍,33%増加することになる.
Base64は6ビット単位であるが,オクテット列の長さと必ずしも一致する(6と8の公倍数の長さになる)とは限らないので,``=''を最後に付加(パディング)して調節される.この結果,Base64エンコードデータは必ず4の整数倍の長さになる.
Base64エンコードデータは,MIMEの制限上,一行当り76文字以下でなければならない. 区切りの改行文字列CRLFは,復号の時には無視される(これ以外でも,未定義の文字が現れたら無視される).
暗号関数の実装においては,各種データの表現形式の変換処理が必要になる.暗号パラメータや暗号処理結果などを外部とやり取りする場合は,これらのデータ形式が一致していることが必要である.
以下の変換処理が定義されている.
- ビット列からオクテット列への変換 (BS2OSP)
- オクテット列からビット列への変換 (OS2BSP)
- 整数からオクテット列への変換 (I2OSP)
- オクテット列から整数への変換 (OS2IP)
- 有限体の要素から整数への変換 (FE2IP)
- 整数から有限体の要素への変換 (I2FEP)
- 有限体の要素からオクテット列への変換 (FE2OSP)
- オクテット列から有限体の要素への変換 (OS2FEP)
- 楕円曲線上の点からオクテット列への変換 (ECP2OSP)
- オクテット列から楕円曲線上の点への変換 (OS2ECPP)
なお,これらの変換は一般に暗号ライブラリが吸収しており,アプリケーションプログラムが意識する必要は通常ない.
- ビット列の変換
- ビット列からオクテット列への変換:$\mathrm{BS2OSP}(B, l)$
ビット列 $B$ の長さが8の倍数となるまでビット0をビット列の先頭に付与し,その後にビット列を8ビットずつ切り出す.
$l$ ビット長のビット列 $B \Rightarrow \lceil l/8 \rceil$ 長オクテット列 $M$
- オクテット列からビット列への変換:$\mathrm{OS2BSP}(M, l)$
オクテット列 $M$ を先頭にパディングビットを持つビット列とみなし,先頭のパディングビット(0 のビット)を削除する.
$\lceil l/8 \rceil$ 長オクテット列 $M \Rightarrow l$ ビット長のビット列
- 整数の変換
- 整数からオクテット列への変換:$\mathrm{I2OSP}(x, l)$
整数 $x$ を $256$進表現する.
非負整数 $x \Rightarrow \lceil l/8 \rceil$ 長オクテット列 $M$
- オクテット列から整数への変換:$\mathrm{OS2IP}(M, l)$
オクテット列 $M$ を整数の $256$進表現とみなす.
$\lceil l/8 \rceil$ 長オクテット列 $M \Rightarrow$ 整数 $x$
- 有限体要素の変換
- 有限体の要素から整数への変換:$\mathrm{FE2IP}(a)$
有限体の要素 $a$ を整係数の多項式で表し,多項式の係数の数列により表現する.
$q$ を有限体の標数とし,多項式の係数列を整数の $q$ 進表現とみなす.
位数 $q^m$ の有限体($q$ は素数,$m \gt 0$ は整数)の要素 $a \Rightarrow$ 整数 $x$
- 整数から有限体の要素への変換:$\mathrm{I2FE}(x)$
有限体の要素を整係数の多項式で表し,多項式の係数の数列により表現する.
$q$ を有限体の標数とし,整数 $x$ を $q$ 進の位取り記法で表現し,各桁を多項式の係数とみなす.
$x$ ($0$ 以上 $q^m - 1$ 以下) $\Rightarrow$ 有限体の要素 $a$
- 楕円曲線上の点
- 楕円曲線上の点からオクテット列への変換:$\mathrm{ECP2OSP}$
圧縮フォーマットの場合,先頭オクテットに圧縮を利用する旨の指示と圧縮された $Y$座標,その後に $X$座標を配置する.
圧縮フォーマットを用いない場合,先頭オクテットに圧縮を利用しない旨の指示を,続いて $X$座標,$Y$座標を配置する.
- オクテット列から楕円曲線上の点への変換:$\mathrm{OS2ECPP}$
圧縮フォーマットが用いられているなら,先頭のオクテットより圧縮された $Y$座標を取り出し,その後に続くオクテット列より $X$座標を取り出す.その後に完全な $Y$座標を求める($X$座標から
$Y$座標を計算).
圧縮フォーマットが用いられていない場合,先頭オクテットを除いたオクテット列より順次 $X$座標,$Y$座標を取り出す.