EternalWindows
自己署名入り証明書 / シリアル番号

証明書を発行するCAは、自身が発行した証明書を一意に識別できるように、 シリアル番号を設定します。 シリアル番号は正の整数値であり、そのサイズは最高で20バイトです。 シリアル番号は、あらゆる証明書の中で一意の値である必要はありませんが、 少なくとも、1つのCAが発行する証明書のシリアル番号は、一意の値でなければなりません。 シリアル番号は主に、CRL(証明書失効リスト)の中で失効される証明書を識別するために利用されます。

CryptoAPIには、CryptGenRandomという乱数を生成する関数が用意されています。 この関数には、生成する乱数のサイズも指定することができるので、 できるだけ大きなサイズを指定することにより、一意の値を取得しやすくなります。

BOOL WINAPI CryptGenRandom(
  HCRYPTPROV hProv, 
  DWORD dwLen, 
  BYTE *pbBuffer 
);

hProvは、CSPのハンドルを指定します。 dwLenは、pbBufferに指定したバッファのサイズを指定します。 pbBufferは、生成された乱数を受け取るバッファを指定します。

シリアル番号は一意の値が望まれると共に、その値は負の値になってはならないとされています。 CryptGenRandomが返す値は、正と負のどちらも考えられますから、 負の値が返った場合は、正の値が返るまでCryptGenRandomを呼び出すか、 正の値を強制的に負の値にするような仕組みが必要です。 後者の例を次に示します。

BYTE serialNumber[4];

CryptGenRandom(hProv, sizeof(serialNumber), serialNumber);
serialNumber[sizeof(serialNumber) - 1] &= 0x7f;
certInfo.SerialNumber.cbData = sizeof(serialNumber);
certInfo.SerialNumber.pbData = serialNumber;

C言語の教本などで書かれているように、ある値が正か負であるかどうかは、 最上位ビットが0か1かで決定することになります。 ある値に対して0x7fと論理積をとった場合、その値の最上位ビットのみを0に変更できるため、 これをバッファの最上位バイトの値に対して行えばよいことになります。


戻る