#はじめに
opensslのdgstコマンドをC#で実装しようとしてハマったので、やり方を残しておこうと思います。
#前提条件
自分で作成した証明局が発行したクライアント証明書を使用しています。
以下の環境で動作確認を行いました。
Windows OS用のOpenSSL openssl 1.1.0k
.Net Framework 4.6
#opensslコマンドで電子署名
まず、opensslコマンドで電子署名の動作を確認します。
opensslでは、電子署名にopenssl dgstコマンドを使います。
以下のコマンドで、target.txtに秘密鍵:private-key.pemで署名した結果をsignatureに出力します。
openssl dgst -sha256 -sign private-key.pem -out signature target.txt
以下のコマンドで、公開鍵:public-key.pemと署名: signatureを使用して、target.txtを検証します。
openssl dgst -verify public-key.pem -signature signature target.txt
#C#で電子署名
C#では、RSACryptoServiceProviderのSignDataとVerifyDataメソッドを使います。
byteDataは署名を行うデータ、fileはpfxファイル名、pfxFilePasswardはpfxファイルのパスワードです。
ただし、以下の署名コードは、例外が発生して動作しません。
//pfxファイルを読み込み
var cert = new X509Certificate2(file, pfxFilePassward);
//秘密鍵の取り出し
var rsa = (RSACryptoServiceProvider)cert.PrivateKey;
//署名実行
//!!! 例外発生 !!!!
var signature = rsa.SignData(byteData, HashAlgorithm.Create("SHA256"));
//crtファイルを読み込み
var cert = new X509Certificate2(file);
//公開鍵の取り出し
var rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;
// 検証実行
var result = rsa.VerifyData(byteData, HashAlgorithm.Create("SHA256"), signature);
#署名の処理を変更
.Net Frameworkの問題で上記のコードではSHA256のアルゴリズムが使用できないようです。
以下の記事を参考にコードを変更しました。
Using certificate from store for RSACryptoServiceProvider
//pfxファイルを読み込み
var cert = new X509Certificate2(file, pfxFilePassward);
//秘密鍵の取り出し
var rsa = (RSACryptoServiceProvider)cert.PrivateKey;
//以下の処理を行わないとSHA256アルゴリズムが使用できない
var enhCsp = new RSACryptoServiceProvider().CspKeyContainerInfo;
var cspparams = new CspParameters(enhCsp.ProviderType, enhCsp.ProviderName, rsa.CspKeyContainerInfo.KeyContainerName);
var privKey = new RSACryptoServiceProvider(cspparams);
// 署名実行
var signature = privKey.SignData(byteData, HashAlgorithm.Create("SHA256"));
#最後に
opensslコマンドとC#が出力した電子署名をバイナリ比較して確認しましたが同じものでした。