Encryption EnvelopedCms能否用于识别加密证书?

Encryption EnvelopedCms能否用于识别加密证书?,encryption,certificate,Encryption,Certificate,我正在一个.NET系统上工作,该系统接收加密文件,并使用EnvelopedCms对象对其进行解密 解密过程工作正常,但我希望能够确定发送方在加密时实际使用的证书的指纹 这样做的原因是,当证书即将到期,并且要求发件人使用一个新的证书,该证书的有效起始日期与到期证书的有效截止日期重叠时,我希望能够识别哪些发件人进行了切换,哪些没有进行切换 在旧证书实际过期之前,两个私钥都将可用,因此无论使用哪一个私钥,文件都将成功解密 我目前拥有的代码是: Dim ecms As New Enveloped

我正在一个.NET系统上工作,该系统接收加密文件,并使用EnvelopedCms对象对其进行解密

解密过程工作正常,但我希望能够确定发送方在加密时实际使用的证书的指纹

这样做的原因是,当证书即将到期,并且要求发件人使用一个新的证书,该证书的有效起始日期与到期证书的有效截止日期重叠时,我希望能够识别哪些发件人进行了切换,哪些没有进行切换

在旧证书实际过期之前,两个私钥都将可用,因此无论使用哪一个私钥,文件都将成功解密

我目前拥有的代码是:

    Dim ecms As New EnvelopedCms()
    Try
        ecms.Decode(data)
    Catch ex As Exception
        DecryptError = True
        DecryptErrorMessage = ex.Message
    End Try
    Try
        ecms.Decrypt()
    Catch ex As Exception
        DecryptError = True
        DecryptErrorMessage = ex.Message
    End Try
    If DecryptError = False Then
        ActualEncryptionCertificate = MyCertificate
        If UCase(MyCertificate) <> UCase(ActualEncryptionCertificate) Then
            DecryptError = True
            DecryptErrorMessage = "Unexpected encryption certificate used."
        End If
        MessageData = ecms.Encode()
    End If
Dim ECM作为新的信封CMS()
尝试
ECM.解码(数据)
特例
解密错误=True
DecryptErrorMessage=ex.Message
结束尝试
尝试
ecms.Decrypt()
特例
解密错误=True
DecryptErrorMessage=ex.Message
结束尝试
如果DecryptError=False,则
ActualEncryptionCertificate=MyCertificate
如果是UCase(菌丝体证书)UCase(实际加密证书),则
解密错误=True
DecryptErrorMessage=“使用了意外的加密证书。”
如果结束
MessageData=ecms.Encode()
如果结束
“数据”包含密码文本,“MyCertificate”包含我们希望他们使用的证书的指纹,其目的是“ActualEncrpytionCertificate”包含他们实际使用的证书的指纹,但正如您所看到的,这目前只是一个占位符

我查看了EnvelopedCms对象的属性,希望找到一个证书集合,但这并不存在。有一个RecipientInfos集合,但它似乎不包含任何有关加密证书的信息


我是否处于“隐藏到零”状态,或者是否有其他方法从EnvelopedCms对象中标识证书?

API不会发出匹配的证书,并且接受证书的
解密
重载仍将始终在Windows证书存储中搜索,因此,唯一可行的选择是根据RecipientInfo值进行匹配

请注意,
IssuerAndSerialNumber
匹配有两种不同的实现。第一个更有效,因为它不会向垃圾收集器抛出额外的数据。第二个是,生命周期管理在
SubjectKeyIdentifier
IssuerAndSerialNumber
变量之间是对称的。如果在调用
FindRecipientCerts
后不需要将证书返回给任何人,那么您可能需要第一个证书(因为您不需要关心谁调用了
Dispose

私有静态X509Certificate2Collection FindRecipientCerts(
X509证书收集干草堆,
收件人信息(收件人)
{
SubjectIdentifier标识符=recipient.RecipientIdentifier;
if(identifier.Type==SubjectIdentifierType.IssuerAndSerialNumber)
{
X509Certificate2Collection coll=新的X509Certificate2Collection();
X509IssuerSerial issuerSerial=(X509IssuerSerial)identifier.Value;
#如果需要,请进行克隆
foreach(干草堆中的X509Certificate2 cert)
{
如果(cert.SerialNumber==发行人serial.SerialNumber&&
证书颁发者==颁发者序列.颁发者名称)
{
coll.Add(证书);
}
}
返回coll;
#否则
//要减少生成的克隆数,请对IssuerName执行本地筛选,然后
//对SerialNumber使用克隆查找方法。
foreach(干草堆中的X509Certificate2 cert)
{
if(cert.Issuer==issuerSerial.IssuerName)
{
coll.Add(证书);
}
}
返回集合查找(
X509FindType.FindBySerialNumber,
issuerSerial.SerialNumber,
假);
#恩迪夫
}
else if(identifier.Type==SubjectIdentifierType.SubjectKeyIdentifier)
{
返回干草堆。找到(
X509FindType.FindBySubjectKeyIdentifier,
标识符。值,
假);
}
其他的
{
抛出新的InvalidOperationException();
}
}

很抱歉用C#回答您的VB问题。

非常感谢您的回答,当我查看RecipientInfos集合时,我似乎在解决方案的最远处。C#答案没有问题,我每天都在阅读它。我唯一关心的是使用序列号来识别证书,而不是指纹。据我所知,可以使用像MakeCert这样的工具,使用-#参数创建两个具有相同序列号的证书,但是没有两个证书可以具有相同的指纹,因为它是整个证书(包括公钥)的散列。如果我的用户从来不会生成带有重复序列号的证书,我想不出一个好的理由让他们这么做,我的状态很好。再次感谢。@标记CMS规范,并假定其具有合格的证书颁发机构(同一发行人不得重复序列号)。这两种方法是CMS结构识别证书的唯一方法。