我正在编写一个简单的示例代码来演示如何使用X509证书进行加密和解密。
public static byte[] Encrypt(byte[] content, X509Certificate2Collection encryptingCertificates)
{
if (content == null)
{
throw new ApplicationException("NullContent");
}
if (encryptingCertificates == null || encryptingCertificates.Count == 0)
{
throw new ApplicationException("NoCertificates");
}
CmsRecipientCollection recipients = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, encryptingCertificates);
EnvelopedCms dataEnvelope = new EnvelopedCms(new ContentInfo(new Oid("1.2.840.113549.1.7.1"), content), new AlgorithmIdentifier(new Oid("2.16.840.1.101.3.4.1.2")));
dataEnvelope.Encrypt(recipients);
return dataEnvelope.Encode();
}
public static byte[] Decrypt(byte[] encryptedContent, X509Certificate2Collection decryptingCertificates)
{
if (decryptingCertificates == null || decryptingCertificates.Count == 0)
{
throw new ApplicationException("NoCertificates");
}
EnvelopedCms dataEnvelope = new EnvelopedCms();
dataEnvelope.Decode(encryptedContent);
dataEnvelope.Decrypt(decryptingCertificates);
ContentInfo contentInfo = dataEnvelope.ContentInfo;
return contentInfo.Content;
}
我遇到了一个问题 - 必须解密的代码(dataEnvelope.Decrypt(decryptingCertificates))抛出CryptographicException:Access denied。
CryptographicException: Access denied.
at System.Security.Cryptography.Pkcs.EnvelopedCms.DecryptContent(RecipientInfoCollection recipientInfos, X509Certificate2Collection extraStore)
at CertificateTestingTool.CertificateResolver.Decrypt(Byte[] encryptedContent, X509Certificate2Collection decryptingCerti
ficates)
at CertificateTestingTool.Program.Main(String[] args)
它发生在Windows Server 2012和Windows 8上。 我在win server 2008上检查了这段代码并赢了7它运行正常。
附加信息:我不使用PKI,我使用文件夹中的私钥(X509Certificate2Collection.Import(...))导入* .pfx文件,并且已成功导入。
public static X509Certificate2Collection GetCertificates(string certPath, string password)
{
X509Certificate2Collection certs = null;
var logger = Log.Logger;
certs = new X509Certificate2Collection();
var flags = X509KeyStorageFlags.DefaultKeySet;
certs.Import(certPath, password, flags);
return certs;
}
有人可以帮我这个吗?据我所知,在新的操作系统版本中引入了一些权限规则。
答案 0 :(得分:1)
导致此问题的原因是调用API CryptMsgControl时发生异常。
为什么它适用于win7但不适用于win8?
这是因为代码导入的证书使用的是KeySpec AT_SIGNATURE。这不是加密/解密的正确规范。它用于签署。 AT_KEYEXCHANGE是适合此目的的。
在Win7中,由于解析传统CAPI密钥的具体实现不严格执行KeySpec中的关键用法,因此不正确的规范有效。因此,AT_SIGNATURE允许加密/解密使用。
要解决此问题,我们需要使用certutil命令工具使用以下命令导入证书:
certutil -user -p -importpfx我的AT_KEYEXCHANGE
我们只需要确保pfx文件的KeySpec设置为1(AT_KEYEXCHANGE)。要检查这一点,我们可以使用命令certutil.exe -dump -v xyz.pfx
当我们使用指定了KeySpec AT_KEYEXCHANGE的certutil导入pfx时,我们正在修改pfx文件的KeySpec属性。之后,我们可以再次将它导出到pfx文件,然后我们可以使用上面提到的命令再次检查KeySpec,我们将看到KeySpec更改为AT_KEYEXCHANGE。
您可以找到更多详细信息here