ホーム 主筆 その他ソフト その他情報 Syuhitu.org English

Windows関連

スクリーンセーバー作成法

半透明ウインドウの性能

bootfont.bin

キャビネット形式

ウインドウスタイルをいじる

Java製ソフトをServiceに登録する

イベントログにメッセージを出力する

コントロールパネルにアイコンを追加する

スクリプトによる拡張1

スクリプトによる拡張2

ガジェットの作成

大容量メモリ

メモリ搭載量の下限に挑む

スパースファイルにする

表示されるアイコンの種類を調べてみた

メモリマップIOとエラー処理

ファイルを作る順番と速度の関係

Cryptography API: Next Generationを使う

Windows 10のアクセントカラー

iSCSIディスクにバックアップを取る

サーバプロセスを分離して実装する

サーバプロセスを分離して実装する - F#

レジストリに大量に書き込む

Solaris関連

OpenGL

Solaris設定

ディレクトリの読み込み

主筆プラグイン開発

マルチスレッドでの開発

door

音を出す

Blade100の正しい虐め方

パッケージの作成

画像入出力

BMPファイル

ICOファイル

ANIファイル

JPEGファイル

減色アルゴリズム

減色アルゴリズムの並列化

その他アルゴリズムなど

自由軸回転

Base64

文字列操作

CPU利用率の取得

正規表現ライブラリ

メタボールを作る

メタボールを作る2

正規表現とNFA・DFA

C言語の構文解析

液晶ディスプレイを解体してみた

iSCSIの理論と実装

単一フォルダにファイルを沢山作る

USB-HUBのカスケード接続

SafeIntの性能

VHDファイルのフォーマット

USBメモリに書き込み続けてみた

CNG:共通鍵暗号アルゴリズムの比較

2016年2月6日公開

CNGでサポートされる共通鍵暗号のアルゴリズムについて、簡単に比較してみる。

サポートされるアルゴリズム

サポートされるアルゴリズムと、暗号利用モードの一覧を示す。

定数アルゴリズムCBCCCMCFBECBGCMサポートOS
BCRYPT_3DES_ALGORITHMトリプルDES Windows Vista以降
BCRYPT_3DES_112_ALGORITHMトリプルDES 112bit Windows Vista以降
BCRYPT_AES_ALGORITHMAES Windows Vista以降
BCRYPT_DES_ALGORITHMDES Windows Vista以降
BCRYPT_DESX_ALGORITHMDES-X Windows Vista以降
BCRYPT_RC2_ALGORITHMRC2 Windows Vista以降
BCRYPT_RC4_ALGORITHMRC4 Windows Vista以降
BCRYPT_XTS_AES_ALGORITHMXTS-AES Windows 10以降

RC4はストリーム暗号のためだと思われるが、暗号利用モードは指定できない。XTS-AESは「暗号利用モードがXTSのAES」であるため、そもそも暗号利用モードは指定できない。BCryptSetProperty関数やBCryptGetProperty関数でも、暗号利用モードとしてはBCRYPT_CHAIN_MODE_NAしか指定できない。

RC4とXTS-AESを除き、デフォルトでは暗号利用モードはCBCが利用される。

ブロック幅と鍵長

暗号化アルゴリズムごとのサポートされるブロック長と鍵長を示す。

定数ブロック長鍵長
BCRYPT_3DES_ALGORITHM8byte192bit
BCRYPT_3DES_112_ALGORITHM8byte128bit
BCRYPT_AES_ALGORITHM16byte128bit, 192bit, 256bit
BCRYPT_DES_ALGORITHM8byte64bit
BCRYPT_DESX_ALGORITHM8byte192bit
BCRYPT_RC2_ALGORITHM8byte16bit, 24bit, 32bit, 40bit, 48bit, 56bit, 64bit, 72bit, 80bit, 88bit, 96bit, 104bit, 112bit, 120bit, 128bit 
BCRYPT_RC4_ALGORITHM1byte8bit, 16bit, 24bit ……512bitまでの値(8bit単位)
BCRYPT_XTS_AES_ALGORITHM16byte256bit, 384bit, 512bit

ブロック長は、BCryptGetProperty関数でBCRYPT_BLOCK_LENGTHを指定して取得した値を記載している。バイト単位の値が取得できるとMSDNには記載されている。

鍵長は、BCryptGetProperty関数でBCRYPT_KEY_LENGTHSを指定して取得した値を記載している。現在Microsoftが公開しているMSDNのページにはビット単位の値が取得されると記載されている。おそらくそれが正しいのだろう。Visual Studio 2010のヘルプの記載ではバイト単位と書かれているので不思議に思ったのだが、たぶんビット単位の誤記だろう。

キーオブジェクトのバイト長

暗号鍵を生成するときに必要になる、キーオブジェクトのサイズを示す。

定数キーオブジェクトのサイズ
CBC CCM CFB ECB GCM
BCRYPT_3DES_ALGORITHM522byte   522byte 522byte  
BCRYPT_3DES_112_ALGORITHM514byte   514byte 514byte  
BCRYPT_AES_ALGORITHM618byte 618byte 618byte 618byte 3,206byte
BCRYPT_DES_ALGORITHM506byte   506byte 506byte  
BCRYPT_DESX_ALGORITHM538byte   538byte 538byte  
BCRYPT_RC2_ALGORITHM374byte   374byte 374byte  
BCRYPT_RC4_ALGORITHM630byte
BCRYPT_XTS_AES_ALGORITHM1,126byte

プログラム例

速度の比較

やはり気になるのは性能だろう。ということで、比較してみた。

実行環境は、CPUがCore i7-5930K 3.5GHz、暗号・復号対象のデータはメモリ上に確保された512MBのデータである。

アルゴリズム 利用モード 暗号化 復号
バイト数算出(※1) 暗号化(※2)バイト数算出(※3) 復号(※4)
トリプルDESCBC 0 ms17,359 ms 0 ms17,562 ms
トリプルDESCFB0 ms 142,281 ms0 ms 140,562 ms
トリプルDESECB 0 ms17,047 ms 0 ms17,031 ms
トリプルDES 112ビットCBC0 ms 17,359 ms0 ms 17,610 ms
トリプルDES 112ビット CFB0 ms142,344 ms0 ms140,500 ms
トリプルDES 112ビットECB 0 ms17,047 ms 0 ms17,000 ms
AESCBC0 ms 1,172 ms0 ms 125 ms
AESCCM(※5) 0 ms1,024 ms 0 ms2,944 ms
AESCFB0 ms 21,547 ms0 ms 19,672 ms
AESECB 0 ms125 ms 0 ms297 ms
AESGCM0 ms 250 ms0 ms 250 ms
DESCBC 0 ms17,360 ms 0 ms17,578 ms
DESCFB0 ms 143,094 ms0 ms 140,922 ms
DESECB 0 ms16,890 ms 0 ms17,172 ms
DES-XCBC0 ms 17,609 ms0 ms 17,938 ms
DES-XCFB 0 ms146,469 ms 0 ms144,687 ms
DES-XECB0 ms 17,250 ms0 ms 17,516 ms
RC2CBC 0 ms9,953 ms  0 ms5,485 ms
RC2CFB0 ms 82,719 ms0 ms 80,860 ms
RC2ECB 0 ms9,406 ms 0 ms5,078 ms
RC4 0 ms 1,219 ms0 ms 1,218 ms

※1 暗号化のバイト数算出とは、BCryptEncrypt関数に対して出力先のバッファを指定せず、出力される暗号文のバイト数の取得のみを行った場合の時間を示す。

※2 暗号化は、BCryptEncrypt関数に対して出力先のバッファを指定して、実際に暗号文を取得した場合の時間を示す。

※3 復号のバイト数算出とは、BCryptDecrypt関数に対して出力先のバッファを指定せず、出力される平文のバイト数の取得のみを行った場合の時間を示す。

※4 復号は、BCryptDecrypt関数に対して出力先のバッファを指定して、実際に平文を取得した場合の時間を示す。

※5 AESのCCMモードだけは、なぜか1回で512MBのデータを暗号/復号することができなかった。そのため、8MBの領域を暗号(所要時間16ms)/復号(所要時間46ms)を元に512MBに割り戻した時間(つまり64倍した値)を記載している。

上記の表だけだとわかりにくいため、グラフにしてみた。


余談だが、以下のような処理で平文のバッファに乱数を設定するのに5,907ms要する。

  Tick1 = GetTickCount();
  for ( size_t i = 0; i < BufSize; i++ )
	  pPlainText[i] = rand();
  printf( "平文の乱数設定に要した時間 = %d\n", GetTickCount() - Tick1 );

さらに、単純なメモリコピー(memcpy関数を使用)で140ms要する。

  Tick1 = GetTickCount();
  memcpy( pEncriptData, pPlainText, BufSize );
  printf( "単純なコピーに要する時間 = %d\n", GetTickCount() - Tick1 );

CNGではAESについてはCPUの強化命令を使用するらしいとはいえ、場合によってはmemcpyと同等な速度をたたき出すわけで、もうAES以外選択肢はないのだろう。

<< 「Cryptography API: Next Generationを使う」に戻る


連絡先 - サイトマップ - 更新履歴
Copyright (C)  2000 - 2016 nabiki_t All Rights Reserved.