証明書を使って署名・暗号化を行ってメール送信したいということがありますが、どうやって組めばいいのかいろいろと探してたらありました。
このサンプルソースでは署名はしてないですが、MSサポートオンラインにサンプルがあります。日本語でおkな自動翻訳がされてます。そのサンプルの一部をC#で書きました。CAPICOMを使っていますのでダウンロードしてインストールする必要があります。
また、COMコンポーネントをシステムに登録するために
取得した証明書(smime.p7m)を
このサンプルソースでは署名はしてないですが、MSサポートオンラインにサンプルがあります。日本語でおkな自動翻訳がされてます。そのサンプルの一部をC#で書きました。CAPICOMを使っていますのでダウンロードしてインストールする必要があります。
また、COMコンポーネントをシステムに登録するために
regsvr32 capicom.dllも忘れずに。
ファイル名を指定して実行→mmc コンソール→スナップインの追加と削除→追加→証明書 ストアの任意の場所に証明書をインポート でインストールしておく必要があります。サンプルソース
using System;
using System.Text;
using CAPICOM;
using CDO;
using ADODB;
using System.IO;
using System.Web.UI;
namespace ConsoleApplication
{
class Program
{
static void Main( string[] args )
{
Message msg = new Message();
msg.To = "hoge@domain.com";
msg.From = "moge@domain.com";
msg.Subject = "subject";
msg.TextBody = "body";
Program inst = new Program();
inst.EnvelopeMessage( msg ).Send();
return;
}
private void SetConfigure( Message prmMsg )
{
prmMsg.Configuration.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"].Value = SMTPSRV;
prmMsg.Configuration.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"].Value = 25;
prmMsg.Configuration.Fields["http://schemas.microsoft.com/cdo/configuration/sendusing"].Value = 2;
prmMsg.Configuration.Fields.Update();
}
private Certificate GetCertificate()
{
Store store = new Store();
// 証明書をインポートした場所
store.Open(
CAPICOM_STORE_LOCATION.CAPICOM_LOCAL_MACHINE_STORE,
CAPICOM.Constants.CAPICOM_OTHER_STORE,
CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_EXISTING_ONLY |
CAPICOM_STORE_OPEN_MODE.CAPICOM_STORE_OPEN_READ_ONLY
);
Certificate retCert = null;
foreach( Certificate tmpCert in store.Certificates )
{
// 証明書→詳細設定の拇印
// Certificate.Thumbprintは、半角スペースを含まないみたい。
if( tmpCert.Thumbprint.ToLower().Equals("<your thumb print>") )
{
retCert = tmpCert;
break;
}
}
return retCert;
}
public Message EnvelopeMessage( Message prmMsg )
{
UtilitiesClass util = new UtilitiesClass();
Message secureMsg = new Message();
secureMsg.DataSource.OpenObject( prmMsg, "IMessage" );
secureMsg.BodyPart.ContentMediaType = "application/pkcs7-mime; smime-type=enveloped-data";
secureMsg.BodyPart.ContentTransferEncoding = "base64";
secureMsg.BodyPart.Fields[ "urn:schemas:mailheader:content-disposition"].Value = "attachment;FileName=smime.p7m";
secureMsg.BodyPart.Fields[ "urn:schemas:mailheader:content-description"].Value = "S/MIME Encrypted Message";
secureMsg.BodyPart.Fields.Update();
Certificate cert = null;
if ((cert = GetCertificate()) == null)
throw new Exception("証明書が見つからない");
EnvelopedData envlpInst = new EnvelopedDataClass();
envlpInst.Recipients.Add(cert);
ADODB.Stream srcStrm = prmMsg.BodyPart.GetStream();
srcStrm.Type = StreamTypeEnum.adTypeBinary;
envlpInst.Content = util.ByteArrayToBinaryString( srcStrm.Read( srcStrm.Size ) );
String cryptStr = envlpInst.Encrypt( CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64 );
ADODB.Stream destStrm = secureMsg.BodyPart.GetDecodedContentStream();
destStrm.Type = StreamTypeEnum.adTypeBinary;
destStrm.Write( Convert.FromBase64String( cryptStr ) );
destStrm.Flush();
destStrm.Close();
// smtp設定
SetConfigure( secureMsg );
return secureMsg;
}
}
}



