ちょっと理由があってCtyptAPI(Win32API)によるRSA署名をする必要がありました。あんまり日本語の情報が無いようなので簡単にまとめておきましょう。まずCtyptAPIによるRSA署名の簡単な手順をまとめます。
1>CryptAcquireCertificatePrivateKey() で証明書から秘密鍵取得
2>CryptCreateHash() でハッシュ関数の初期化
3>CryptHashData() で署名対象のハッシュ計算
4>CryptSignHash() を空読みして署名値サイズの取得
5>CryptSignHash() 署名の実行
6>バイトを反転して署名値を取得
7>後始末(CryptDestroyHash()等)
基本的にはこれだけなのですが注意が必要なのは6>の
バイト反転でしょうか。.NETの
RSACryptoServiceProvider.SignData メソッドで署名した署名値と、
CryptSignHash() で署名した署名値とは、バイト反転させないと同じになりません。これを忘れると当然検証に失敗してしまいますのでご注意を。
もう1つ注意した方が良いのはRSACryptoServiceProvider.SignData メソッドの署名値はハッシュOIDを含んでいる一般的な形式です。CryptSignHash() の4番目の引数 dwFlags は必ずゼロにして何も指定しないようにします。CRYPT_NOHASHOID 等を指定するとハッシュOIDが含まれないので RSACryptoServiceProvider.SignData メソッドと互換性が取れなくなります。