C# 将RSASSA-PSS和RSAES-OAEP与MailKit一起使用
我必须与一些业务合作伙伴交换加密和签名的电子邮件。需要特定的算法,例如:C# 将RSASSA-PSS和RSAES-OAEP与MailKit一起使用,c#,cryptography,mimekit,C#,Cryptography,Mimekit,我必须与一些业务合作伙伴交换加密和签名的电子邮件。需要特定的算法,例如: 对于签名,RSASSA-PSS作为签名算法 对于加密,RSAES-OAEP用于密钥加密,AES-128 CBC用于内容加密 我在设置Mailkit时遇到了麻烦,实际上是在Mailkit和BouncyCastle的背后。 到目前为止,我的情况如下: 用于解密和签名验证 在windows应用商店中设置私钥后,可以使用WindowsSecureMimeContext对正文进行解密 验证签名不正确 case Multipart
- 对于签名,RSASSA-PSS作为签名算法
- 对于加密,RSAES-OAEP用于密钥加密,AES-128 CBC用于内容加密
case MultipartSigned signedBody:
try
{
using (var ctx = new WindowsSecureMimeContext(StoreLocation.LocalMachine))
{
var verifiedData = signedBody.Verify(ctx);
return verifiedData.All(o => o.Verify());
}
}
catch (Exception e)
{
throw new Exception("Error during signature verification.", e);
}
发件人的证书由通用CA签名,因此我再次使用WindowsSecureMimeContext,但使用的是verifiedData。All(o=>o.Verify())引发DigitalSignatureVerifyException(“验证数字签名失败:未知错误”-1073700864”。)
用于签名和加密
嗯,看起来很难
对于签名,我似乎需要BouncyCastle的PssSigner,我可以通过重写DkimSigner,尤其是DigestSigner属性来获得它
class TestSigner : DkimSigner
{
protected TestSigner(string domain, string selector, DkimSignatureAlgorithm algorithm = DkimSignatureAlgorithm.RsaSha256)
: base(domain, selector, algorithm)
{
}
public TestSigner(AsymmetricKeyParameter key, string domain, string selector, DkimSignatureAlgorithm algorithm = DkimSignatureAlgorithm.RsaSha256)
: base(key, domain, selector, algorithm)
{
}
public TestSigner(string fileName, string domain, string selector, DkimSignatureAlgorithm algorithm = DkimSignatureAlgorithm.RsaSha256)
: base(fileName, domain, selector, algorithm)
{
}
public TestSigner(Stream stream, string domain, string selector, DkimSignatureAlgorithm algorithm = DkimSignatureAlgorithm.RsaSha256)
: base(stream, domain, selector, algorithm)
{
}
public override ISigner DigestSigner => SignerUtilities.GetSigner(PkcsObjectIdentifiers.IdRsassaPss);
}
但是我不知道在哪里使用它。也许在使用mimessage.Sign()时,我对方法签名中所需的参数有点迷茫
对于加密,我可以在BouncyCastle的库中找到一个rsaesAppParameters,因为我不知道如何使用它
任何邮件专家的帮助都将不胜感激 A
DkimSigner
用于生成您不想做的DKIM签名。DKIM签名与S/MIME无关
使用RSASSA-PSS进行S/MIME签名
当前(使用System.Security
作为后端)不支持RSASSA-PSS,因此您需要使用Bouncy Castle后端
要使用Bouncy Castle后端,您需要使用其中一个衍生工具(或创建自己的衍生工具)。作为摆弄事物的临时解决方案,我可能建议使用,但对于长期使用,我建议查看-尽管您可能仍然希望将其子类化以使其工作
现在您正在使用Bouncy Castle S/MIME上下文,为了指定要使用RSASSA-PSS填充,您需要使用接受参数(如或)的API
下面是一个示例代码片段:
var signer = new CmsSigner ("certificate.pfx", "password");
// Specify that we want to use RSASSA-PSS
signer.RsaSignaturePaddingScheme = RsaSignaturePaddingScheme.Pss;
// Sign the message body
var signed = MultipartSigned.Create (ctx, signer, message.Body);
// replace the message body with the signed body
message.Body = signed;
使用AES-128 CBC(或任何其他特定算法)和RSAES-OAEP的S/MIME加密
首先,要使用S/MIME进行加密,您需要使用以下方法之一。[2]
采用MailboxAddress
的Encrypt()方法将根据提供的电子邮件地址进行证书查找,从而自动为您创建s和(或者,如果这些邮箱中的任何一个实际上是,则使用,如果该用户在您的数据库中有多个证书,或者您希望额外确保MimeKit选择了正确的证书,则这将非常有用)
当您向MimeKit提供MailboxAddress
es列表时,MimeKit将为您做的另一件事是,它将为所述用户查找存储在数据库中的受支持的加密算法
对于WindowsSecureMimeContext
,这涉及查看S/MIME功能X509证书扩展属性并解码支持的加密算法。但是,根据我的经验,很多时候,Windows证书存储中的X509证书上不存在此扩展,因此MimeKit必须假设仅支持3DES CBC
对于DefaultSecureMimeContext
,如果您已验证所述收件人的任何S/MIME签名邮件,则该用户的证书(链)和公布的加密算法将存储在MimeKit的自定义SQL数据库中(当您使用S/MIME对消息进行签名时,客户机通常会在S/MIME签名数据中包含S/MIME Capabilities属性)
现在您已经了解了它的工作原理,如果您想强制使用AES-128 CBC,那么您可以自己手动构建CmsRecipientCollection
当然,这需要为每个收件人创建一个新的CmsRecipient
。要创建此类,您真正需要的只是该收件人的X509证书
var recipient = new CmsRecipient (certificate);
由于要强制使用AES-128 CBC,现在只需覆盖此收件人支持的加密算法:
recipient.EncryptionAlgorithms = new EncryptionAlgorithm[] {
EncryptionAlgorithm.Aes128
};
(默认情况下,该属性将设置为证书的s/MIME功能扩展属性中列出的算法(按优先顺序),如果存在,否则它将只包含3DES CBC)
如果还要强制RSAES-OAEP,则需要设置:
recipient.RsaEncryptionPadding = RsaEncryptionPadding.OaepSha1;
将每个CmsRecipient
添加到您的CmsRecipient集合
中,然后将其传递到您首选的Encrypt()
方法,然后使用AES-128 CBC对其进行加密
注:
MultipartSigned.Create()
将在ApplicationPkcs7Mime.Sign()时生成一个multipart/signed
MIME部分
将创建一个应用程序/pkcs7 mime
mime部分。您想使用哪一个取决于您的决定,请记住,您的选择可能会影响与收件人正在使用的任何客户端的兼容性(我认为大多数客户端都支持这两种表单,但您可能需要检查以确保)SecureMimeContext
类(如自述文件中所述),然后您可以随意使用各种加密/解密/签名/验证/etc方法,这些方法不接受加密上下文参数,因为MimeKit将为您实例化默认上下文。否则,您需要向它们传递上下文您的验证异常看起来可能来自System.Security(您使用的是WindowsSec吗