C# 从十进制值序列号获取证书失败

C# 从十进制值序列号获取证书失败,c#,encryption,cryptography,x509certificate,C#,Encryption,Cryptography,X509certificate,我使用EncryptedXml类来解密xml文档的一部分。 内调用以下.Net方法: public virtual SymmetricAlgorithm GetDecryptionKey (EncryptedData encryptedData, string symmetricAlgorithmUri) xml文档的节点使用自签名证书加密。 以下是xml密钥信息详细信息: <KeyInfo> <ds:X509Data xmlns:ds="http://www.w3.or

我使用EncryptedXml类来解密xml文档的一部分。 内调用以下.Net方法:

public virtual SymmetricAlgorithm GetDecryptionKey (EncryptedData encryptedData, string symmetricAlgorithmUri) 
xml文档的节点使用自签名证书加密。 以下是xml密钥信息详细信息:

<KeyInfo>
 <ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
   <ds:X509IssuerSerial>
  <ds:X509IssuerName>CN=certName</ds:X509IssuerName>
  <ds:X509SerialNumber>-180xxx</ds:X509SerialNumber>
  </ds:X509IssuerSerial>
 </ds:X509Data>
</KeyInfo>
然后我反思了.Net代码,发现它是这样执行的:

public static void GetFromSerial(string serialName, string serialNumber)
{
    X509Certificate2Collection collection = new X509Certificate2Collection();
    X509Store[] stores = new X509Store[2];
    string storeName = "My";

    stores[0] = new X509Store(storeName, StoreLocation.CurrentUser);
    stores[1] = new X509Store(storeName, StoreLocation.LocalMachine);

    for (int index = 0; index < stores.Length; index++)
    {
        X509Certificate2Collection filters = null;
        stores[index].Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
        filters = stores[index].Certificates;
        stores[index].Close();
        filters = filters.Find(X509FindType.FindByIssuerDistinguishedName, serialName, false);
        filters = filters.Find(X509FindType.FindBySerialNumber, serialNumber, false);

        if (filters != null)
            collection.AddRange(filters);
    }
}
我这里的序列号是空的

然后我将序列号转换为十六进制值。并且尝试了同样的方法,效果非常好

这里的问题是我有一个负的大整数还是别的什么?
负数很可能是因为我使用的是自签名证书。

问题是整数格式的带负数的序列号不符合RFC 3280的要求,即:

4.1.2.2序列号 序列号必须是CA分配给的正整数 每份证书。它必须是唯一的每个证书颁发的 给定CA,即发卡机构名称和序列号标识唯一的 证明书CAs必须强制序列号为非负 整数

Microsoft代码遵循此标准。这将导致无法获取依赖于负序列号的证书


我必须颁发符合此标准的新自签名证书。

是否有足够的信息?谢谢。不,这与搜索证书存储时十六进制值的格式有关。我的问题是在搜索大整数格式的序列号和十六进制格式的序列号时.Net类的行为不一致。问题是定义X5.09证书的ASN.1将整数定义为有符号值。如果第一个字节在无符号编码中为80或更高,则应使用00字节填充。现在,如果将有符号值与无符号值进行比较,则会失败。尝试对负数进行编码,添加一个00字节,然后再次解析结果。它可能只是验证了这一点。或者使用正确编码的数字生成自签名证书。我还要补充一个答案。
public static void GetFromSerial(string serialName, string serialNumber)
{
    X509Certificate2Collection collection = new X509Certificate2Collection();
    X509Store[] stores = new X509Store[2];
    string storeName = "My";

    stores[0] = new X509Store(storeName, StoreLocation.CurrentUser);
    stores[1] = new X509Store(storeName, StoreLocation.LocalMachine);

    for (int index = 0; index < stores.Length; index++)
    {
        X509Certificate2Collection filters = null;
        stores[index].Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
        filters = stores[index].Certificates;
        stores[index].Close();
        filters = filters.Find(X509FindType.FindByIssuerDistinguishedName, serialName, false);
        filters = filters.Find(X509FindType.FindBySerialNumber, serialNumber, false);

        if (filters != null)
            collection.AddRange(filters);
    }
}
filters = filters.Find(X509FindType.FindBySerialNumber, serialNumber, false);