VNCrypt.DLL(高強度の暗号化・復号化DLL) 開発者マニュアル
個人使用・非商用利用に関してはフリーです。本DLL全体の著作権はとつげき東北が保有します。メールはこちら


このDLLは、以下のような機能・関数を提供します。

[暗号化・復号化・圧縮・展開関係]
・任意のファイル・フォルダを、VNCrypt暗号化ファイルにする機能
・任意のVNCrypt暗号化ファイルを、復号化してファイルに保存する機能
・任意のファイル・フォルダをLZH書庫に圧縮する機能
・任意のLZH書庫を展開する機能
[SHA関係]
・任意の文字列のSHA-1ハッシュ値を得る関数
・任意の文字列のSHA-512ハッシュ値を得る関数
[真性乱数・擬似乱数関係]
・ハードウェア乱数生成の機能(hdrand.c)
・超長周期擬似乱数、MT(メルセンヌツイスター)の手軽な利用
・超長周期擬似乱数、MTに基づく、安全な擬似乱数の手軽な利用(SHRAND)

ただし、ハードウェア乱数の使用のためには書き込み可能なテンポラリフォルダが必要です。
Windows95以降対象、またCPUはPentium以降に対応。



★使用法★

通常のDLLと同様です。現バージョンにはヘッダファイルがありません。

//★以下はヘッダ部分に記述
//インポート関数の型定義(下の各関数の説明を読んで、同じ型で定義します)
typedef int (*BVNencrypt)(char *,char *,char *,char *,int,int,int,int,int,int,int);
typedef int (*BVNencryptEx)(char *,char *,char *,char *,int,int,int,int,int,int,int,int,int);
typedef int (*BVNdecrypt)(char *,char *,char *,char *,int,int,int);
typedef int (*BVNdecryptEx)(char *,char *,char *,char *,int,int,int);
typedef int (*BVNvirtualdecrypt)(char *,char *,char *,char *,int,int,int);
typedef int (*BVNCfilecheck)(char *);
typedef int (*BVNCgetversion)(void);
typedef int (*BVNCinitialize)(void);
typedef int (*BVNChdrand32)(void);
typedef int (*BVNChdrandbit)(void);
typedef void (*BVNCinit_by_array)(unsigned long *, unsigned long);
typedef unsigned long (*BVNCgenrand)(void);
typedef int (*BVNChdrandpool)(int);
typedef int (*BLZHdecode)(char *,char *,char *);
typedef int (*BLZHencode)(char *,char *,int);
typedef int (*BVNCfilelist)(char *);
typedef int (*BLZHeEx)(char *);
typedef unsigned int (*BVNCSHA1)(char *,int,char *);
typedef unsigned int (*BVNCSHA512)(char *,int,char *);
typedef int (*BSHRAND)(void);
typedef void (*BSHRAND_init)(unsigned long *, unsigned long);

//インポート関数型の関数へのポインタ変数宣言
BVNencrypt VNencrypt;
BVNencryptEx VNencryptEx;
BVNdecrypt VNdecrypt;
BVNdecrypt VNdecryptEx;
BVNvirtualdecrypt VNvirtualdecrypt;
BVNCgetversion VNCgetversion;
BVNCfilecheck VNCfilecheck;
BVNCinitialize VNCinitialize;
BVNChdrand32 VNChdrand32;
BVNChdrandbit VNChdrandbit;
BVNCinit_by_array VNCinit_by_array;
BVNCgenrand VNCgenrand;
BVNChdrandpool VNChdrandpool;
BLZHdecode LZHdecode;
BLZHencode LZHencode;
BVNCfilelist VNCfilelist;
BLZHeEx LZHeEx;
BVNCSHA1 VNCSHA1;
BVNCSHA1 VNCSHA512;
BSHRAND SHRAND;
BSHRAND_init SHRAND_init;


//★以下をボタンクリックイベント内に記述
//注意! VisualC++の場合、キャストの制限が違います。
//xx = ( XX )::GetProcAddress( hDll, "_xx" );
//のような部分でキャストエラーが出るようです。
//コンパイラの指示通り、ここを
//xx = ( XX )::GetProcAddress( (struct HINSTANCE__ *)hDll, "_xx" );
//に直してやることで、コンパイルできます。
{
int errc=0;
HANDLE hDll = ::LoadLibrary( "VNCrypt.dll" ); //DLLをロード
if(hDll==NULL){ShowMessage("DLLオープンできません");return;} //DLLロードのエラーチェック

//DLLから必要な関数をインポート
//DLL関数インポートのエラーチェック。この例では2つの関数だけをチェックしている。
if((VNencrypt = (BVNencrypt)::GetProcAddress(hDll,"_VNencrypt"))==NULL)errc=1;
if((VNencryptEx = (BVNencryptEx)::GetProcAddress(hDll,"_VNencryptEx"))==NULL)errc=1;
if((VNdecrypt = (BVNdecrypt)::GetProcAddress(hDll,"_VNdecrypt"))==NULL)errc=1;
if((VNdecryptEx = (BVNdecryptEx)::GetProcAddress(hDll,"_VNdecryptEx"))==NULL)errc=1;
if((VNvirtualdecrypt = (BVNvirtualdecrypt)::GetProcAddress(hDll,"_VNvirtualdecrypt"))==NULL)errc=1;
if((VNCfilecheck = (BVNCfilecheck)::GetProcAddress(hDll,"_VNCfilecheck"))==NULL)errc=1;
if((VNCinitialize = (BVNCinitialize)::GetProcAddress(hDll,"_VNCinitialize"))==NULL)errc=1;
if((VNCgetversion = (BVNCgetversion)::GetProcAddress(hDll,"_VNCgetversion"))==NULL)errc=1;
if((VNChdrand32 = (BVNChdrand32)::GetProcAddress(hDll,"_VNChdrand32"))==NULL)errc=1;
if((VNChdrandbit = (BVNChdrandbit)::GetProcAddress(hDll,"_VNChdrandbit"))==NULL)errc=1;
if((VNCinit_by_array = (BVNCinit_by_array)::GetProcAddress(hDll,"_VNCinit_by_array"))==NULL)errc=1;
if((VNCgenrand = (BVNCgenrand)::GetProcAddress(hDll,"_VNCgenrand"))==NULL)errc=1;
if((VNChdrandpool = (BVNChdrandpool)::GetProcAddress(hDll,"_VNChdrandpool"))==NULL)errc=1;
if((LZHdecode = (BLZHdecode)::GetProcAddress(hDll,"_LZHdecode"))==NULL)errc=1;
if((LZHencode = (BLZHencode)::GetProcAddress(hDll,"_LZHencode"))==NULL)errc=1;
if((VNCfilelist = (BVNCfilelist)::GetProcAddress(hDll,"_VNCfilelist"))==NULL)errc=1;
if((LZHeEx = (BLZHeEx)::GetProcAddress(hDll,"_LZHeEx"))==NULL)errc=1;
if((VNCSHA1 = (BVNCSHA1)::GetProcAddress(hDll,"_VNCSHA1"))==NULL)errc=1;
if((VNCSHA512 = (BVNCSHA512)::GetProcAddress(hDll,"_VNCSHA512"))==NULL)errc=1;
if((SHRAND = (BSHRAND)::GetProcAddress(hDll,"_SHRAND"))==NULL)errc=1;
if((SHRAND_init = (BSHRAND_init)::GetProcAddress(hDll,"_SHRAND_init"))==NULL)errc=1;

if(errc==1){ShowMessage("DLLに必要な関数がありません。");FreeLibrary(hDll);Application->Terminate();}
//★以下を自由にコーディングする


//★以下は全ての動作を終了した後に一度だけ行う
//DLLの開放
FreeLibrary( hDll );
}



★基本的な使い方例★

基本的な動作の流れとしては、次のようになります。

・暗号化
まず、VNCinitialize()によって乱数源を準備します。
VNCfilelist()を用いて対象ファイル・フォルダを列挙しておき、VNencryptEx()をLZHmode=3で用いれば、複数のファイルやフォルダをまとめて暗号化できます。

・圧縮
VNCfilelist()を用いて対象ファイル・フォルダを列挙しておき、LZHeEx()を用いれば、複数のファイルやフォルダをまとめてLZHファイルにできます。

・復号化
VNdecryptEx()を呼び出せば復号化できます。

・展開
LZHdecode()を呼び出せば展開できます。



★関数マニュアル★


int VNCinitialize()

全ての関数に先立って、必ず一度以上実行する。
初期化が行われると同時に、ハードウェア乱数を使用するための準備を行う。
PCのシステム構成だけでなく偶然性によって返り値はばらつく。
最初は大きな値の返り値を期待して呼び出す。
何度か試行しても大きな値の返り値が得られない場合、小さな値の返り値を期待して呼び出す。
最終的に1以上の返り値が得られれば、このDLLは一応動作する(ただし例えば返り値10の場合と1の場合では、実行パフォーマンスにかなりの差が生ずる)。

引数
なし

返り値
0以下 ハードウェア乱数生成失敗
1以上 そのビット数のハードウェア乱数が使える


VNencrypt(char filename[MAX_PATH],char filename2[MAX_PATH],char filename3[MAX_PATH],char KEYS[],int keybyte,int ints,int paddingmode,int padsize,int restricted,int poly_num,int rewritemode,int SHA1mode)

使われなくなりました。


int VNencryptEx(char filename[MAX_PATH],char filename2[MAX_PATH],char filename3[MAX_PATH],char KEYS[],int keybyte,int ints,int paddingmode,int padsize,int restricted,int poly_num,int rewritemode,int LZHmode,int SHA1mode)

指定ファイルを暗号化する。
v1.90以降では、VNCfilelist()関数と併用して、LZHmode=3で利用することが推奨される。

引数
filename 入力ファイル名(パス付き)
filename2 出力ファイル名(パス付きも可)
filename3 元ファイル名(復号時に、この名前のファイルに復号化される。パスを含んではならない)
KEYS 鍵の文字列。
keybyte キーのバイト数
ints 無効なパラメータ。0を指定すること。
paddingmode 0 パディングしない 1 randでパディング 2 hdrandでパディング。通常使用時においては1で充分である。
padsize パディングの式に与えるp。大きければ大きいほど暗号ファイルは大きくなるが、鍵の長さなどが特定されにくくなる。通常使用時には50以下で充分。
//    なおパディングバイト数を算出する式は r=VNhdrand32()%p+VNhdrand32%/p+8 であり、実際に暗号ファイルに書き出されるバイト数はr*2になる。
restricted 非公開パラメータ。0を指定すること。
poly_num MT系列2のintをいくつ重合するか。通常使用においては2または4が望ましい。詳細についてはVNCryptのフォーマット参照。最小値は1、最大値は65535。
rewritemode 出力ファイルと同名のファイルが存在するときに上書きするかどうか。0しない、1する。
LZHmode 圧縮のモード。0-圧縮なしファイル暗号化 1-圧縮付ファイル暗号化 2-圧縮付フォルダ暗号化 3-VNCfilelist()で登録したファイル・フォルダを暗号化
SHA1mode SHAモード。詳しくはフォーマットを参照。VNCrypt.exeにおける「XORモード」の指定と同様。

返り値
1 暗号化成功
-1 何らかの失敗(ファイルが存在しないなど)
-2 hdrand失敗
-3 鍵が長すぎる
-4 padsizeが0以下
-5 poly_numが0以下かまたは規定値より大きい
-6 入力ファイルが開けない
-7 既に出力ファイル名が存在する(rewrite=0の時のみ)
-8 出力できない(書き込み禁止など)


int VNCfilelist(char * filename)

暗号化(または圧縮)すべきファイル・フォルダを1つ追加する。
V1.90以降の暗号化では常に、VNencryptExの前にこの関数を用いて暗号化すべきファイル・フォルダを指定しておき、VNencryptExをLZHmode=3で呼び出すべきである。

引数
filename 追加すべきファイル名またはフォルダ名、ただしここで「/d」を指定すると、これまで追加したファイル・フォルダをすべて消去する。

返り値
0または1 成功
負数 失敗


int LZHeEx(char * filename)

VNCfilelistで指定したファイル・フォルダをまとめて1つの書庫に圧縮する。

引数
filename 書庫名。

返り値
1 成功
負数 失敗


「c:\aaa.txt」「c:\bbb.txt」の2つのファイルと、「c:\ccc」というフォルダをまとめて圧縮して「c:\ddd.lzh」として出力するには
{
VNCfilelist("/d"); //リストの初期化
VNCfilelist("c:\\aaa.txt"); //リストに「c:\aaa.txt」を追加
VNCfilelist("c:\\bbb.txt"); //リストに「c:\bbb.txt」を追加
VNCfilelist("c:\\ccc"); //リストに「c:\ccc」フォルダを追加
LZHeEx("c:\\ddd.lzh"); //圧縮
}


int LZHdecode(char filename1[MAX_PATH],filename2[MAX_PATH],filename3[MAX_PATH])

LZHファイルを展開する。

引数
filename1 書庫名。
filename2 書庫名のパス。filename1でフルパスを指定している場合は不要。
filename3 展開すべきフォルダのパス。「c:\〜〜〜\folder」という形で指定すると、folderという名前のフォルダ上に展開される。

返り値
1 成功


「c:\aaa\bbb.lzh」を「c:\ddd」フォルダ上に展開したい時は
LZHdecode("c:\\aaa\\bbb.lzh",NULL,"c:\\ddd");
または
LZHdecodeEx("bbb.lzh","c:\\aaa","c:\\ddd");
などとする。
書庫をfilename1とfilename2に分けて指定できるのは便宜のためであって、必ずしもこの方式に従う必要はない。


VNdecrypt(char filename[MAX_PATH],char filename2[MAX_PATH],char *outfilename,char KEYS[],int keybyte,int rewritemode,int ints)

使われなくなりました。


int VNdecryptEx(char filename[MAX_PATH],char filename2[MAX_PATH],char *outfilename,char KEYS[],int keybyte,int rewritemode,int ints)

指定ファイルを復号化する。

引数
filename 入力ファイル名(パス付き)
filename2 出力フォルダパス
outfilename 実際に出力されたファイル名(vncファイルから得られる)
KEYS 鍵の文字列。
keybyte キーのバイト数(このDLLでは、2500までの動作が保障される)
rewriteMODE 出力ファイルと同名のファイルが存在するときに上書きするか。0しない、1する。通常は0で運用すべきである。
ints 無効なパラメータ(0を指定すること)

返り値
1 復号化成功
-1 何らかの失敗(ファイルが存在しないなど)
-2 VNCファイルではない
-3 復号化不可能なバージョン
-4 重合数が1より小さいか規定値より大きい
-5 暗号化されたアドレスが、実際のファイルの大きさより大きい
-6 入力ファイルが開けない
-7 出力ファイルが既にある(rewrite=0の時のみ) 注意:バージョンによってはこの返り値は返らず、常に上書き処理される
-8 出力できない(書き込み禁止など)
-9 異常なメモリ書き込みを要求するVNC(復号化鍵が違うなど)。なお、通常、誤ったキーを指定するとこの返り値が返る確率が高い。


int VNvirtualdecrypt(char filename[MAX_PATH],char filename2[MAX_PATH],char *outfilename,char KEY[],int keybyte,int rewritemode,int ints)

最初に一度VNdecryptEx()を行ってから、鍵以外を同じパラメータにしてこの関数を呼ぶ。
すると、別の鍵でVNdecryptExを行うのと同様の返り値を得られる(ただし復号化は行われない)。
つまり、複数の鍵で連続的に復号化を試してみる場合に用いると、通常のdecryptのような無駄な作業(読み込みなど)をせずに復号化テストを行える。
返り値が1だったときに、その鍵で本当の復号化(VNdecryptEx)を行えばよい。

返り値
VNdecryptExと同じ。

返り値
VNdecryptExと同じ。


int VNCfilecheck(char filename[MAX_PATH])

ファイルがVNCファイルであるかどうか、またその暗号化バージョンはいくらかを得る。

引数
filename 対象ファイル名(パス付き)

返り値
正の整数 VNCバージョンの100倍の整数値
-1 ファイル自体が存在しない、またはフォルダである
-2 VNCファイルではない普通のファイル
-4 重合度が0以下か規定値以上(エラー)
-5 filenameがヌルストリング


int VNCgetversion(void)

DLLのバージョンを得る。

引数 
なし

返り値
DLLのバージョンの100倍の整数値。


unsigned int VNCSHA1(char * str,int bytes,char *odigit)

文字列から、SHA-1ハッシュ値(160ビット)を取得する。

引数
str 元の文字列
bytes 文字列のバイト数
odigit ハッシュの文字列(160ビット)を格納するバッファへのポインタ

返り値
ハッシュ値の各々の4バイト(32ビット)をXORした値。


unsigned int VNCSHA512(char * str,int bytes,char *odigit)

文字列から、SHA-512ハッシュ値(512ビット)を取得する。

引数
str 元の文字列
bytes 文字列のバイト数
odigit ハッシュの文字列(512ビット)を格納するバッファへのポインタ

返り値
ハッシュ値の各々の4バイト(32ビット)をXORした値。


「test.txt」という名前のファイルのSHA-512ハッシュ値を計算して表示するサンプル。

char filename[MAX_PATH]; //ファイル名
strcpy(filename,"test.txt"); //
char *cBUF; //ファイル内容保持用
HANDLE hFILE;
DWORD wFSIZE,wGSIZE;

// ファイルを開く
hFILE = ::CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
// ファイルサイズの取得
wFSIZE = ::GetFileSize(hFILE,NULL);
// ファイルサイズが0xFFFFFFFFの場合はファイルオープン失敗
if (wFSIZE != 0xFFFFFFFF) {
// メモリを確保する
cBUF = (char*)malloc(wFSIZE + 1);
// ファイルを一括で読込む
::ReadFile(hFILE,cBUF,wFSIZE,&wGSIZE,NULL);
// ファイルを閉じる
::CloseHandle(hFILE);

char dig[64+4]; //ハッシュしたデータを保持するため
VNCSHA512(cBUF,wFSIZE,dig); //ハッシュ実行
MessageBox(NULL,dig,NULL,NULL); //結果表示

free(cBUF);
}
else
{
MessageBox(NULL,"ファイルが不適切です",NULL,NULL);
return;
}


int VNChdrand32(void)

ハードウェア乱数から32ビットの乱数を得る。

引数
なし

返り値
32ビットの真の乱数。


int VNChdrandbit(void)

ハードウェア乱数から1ビットの乱数を得る。

引数
なし

返り値
0または1(真の乱数)


void VNCinit_by_array(unsigned long MTSeed[625],int t)

MT擬似乱数を、624*32ビットの配列で初期化する。
VNCgenrandの前に少なくとも一度は実行すること。

引数
MTseed[] 各々、0〜0xFFFFFFFFの値を持つ配列。ただし[0]の値だけは0xFFFF0000に固定すること。
t 定数。623に固定して用いる。

返り値
なし


unsigned long VNCgenrand(void)

MT擬似乱数から、32ビットの乱数を得る。

引数
なし

返り値
32ビット擬似乱数。

void SHRAND_init(unsigned long MTSeed[625], unsigned long t)

MT擬似乱数をもとにした、SHRAND擬似乱数を、624*32ビットの配列で初期化する。
SHRANDの前に少なくとも一度は実行すること。
MTと全く同じ要領で、SHAを用いた安全な擬似乱数列を得ることができる。

引数
MTseed[] 各々、0〜0xFFFFFFFFの値を持つ配列。ただし[0]の値だけは0xFFFF0000に固定すること。
t 定数。623に固定して用いる。

返り値
なし


int SHRAND(void)

SHRAND擬似乱数から、32ビットの安全な擬似乱数を得る。
(返り値の型がVNCgenrandと異なることに深い理由はない、というか適当 笑)

引数
なし

返り値
32ビット擬似乱数。