简体   繁体   English

无法将密钥文件添加到 X509Certificate2

[英]Unable to add key file to X509Certificate2

Environment: VS 2019, Core 3.1, C# 8.0环境:VS 2019,Core 3.1,C# 8.0

I'm getting the following error while trying to add a .cer and .key file to my httpClientHandler:尝试将 .cer 和 .key 文件添加到我的 httpClientHandler 时出现以下错误:

    {"ASN1 corrupted data."}
        Data: {System.Collections.ListDictionaryInternal}
        HResult: -2146233087
        HelpLink: null
        InnerException: null
        Message: "ASN1 corrupted data."
        Source: "System.Security.Cryptography.Algorithms"
        StackTrace: "   at System.Security.Cryptography.Asn1.AsnReader.CheckExpectedTag(Asn1Tag tag, Asn1Tag expectedTag, UniversalTagNumber tagNumber)\r\n   at System.Security.Cryptography.Asn1.AsnReader.ReadSequence(Asn1Tag expectedTag)\r\n   at System.Security.Cryptography.Asn1.RSAPrivateKeyAsn.Decode(AsnReader reader, Asn1Tag expectedTag, RSAPrivateKeyAsn& decoded)\r\n   at System.Security.Cryptography.Asn1.RSAPrivateKeyAsn.Decode(Asn1Tag expectedTag, ReadOnlyMemory`1 encoded, AsnEncodingRules ruleSet)\r\n   at System.Security.Cryptography.Asn1.RSAPrivateKeyAsn.Decode(ReadOnlyMemory`1 encoded, AsnEncodingRules ruleSet)\r\n   at System.Security.Cryptography.RSAKeyFormatHelper.FromPkcs1PrivateKey(ReadOnlyMemory`1 keyData, AlgorithmIdentifierAsn& algId, RSAParameters& ret)\r\n   at System.Security.Cryptography.RSA.ImportRSAPrivateKey(ReadOnlySpan`1 source, Int32& bytesRead)\r\n   at BnyMellon.Program.CreateFromCertFile(String cerFile, String keyFile) in C:\\Users\\bbernzweig.AD\\source\\repos\\HttpClientExample\\
    BnyMellon\\Program.cs:line 150"
        TargetSite: {Void CheckExpectedTag(System.Security.Cryptography.Asn1.Asn1Tag, System.Security.Cryptography.Asn1.Asn1Tag, System.Security.Cryptography.Asn1.UniversalTagNumber)}

Error is raised here on line rsa.ImportRSAPrivateKey(privateKeyBytes, out _); rsa.ImportRSAPrivateKey(privateKeyBytes, out _);线上rsa.ImportRSAPrivateKey(privateKeyBytes, out _);错误:

private static X509Certificate2 CreateFromCertFile(string cerFile, string keyFile)
{
    try
    {
        var cert = new X509Certificate2 (cerFile);
        var privateKeyBytes = LoadPrivateKeyBytes(keyFile);

        using var rsa = RSA.Create();
        rsa.ImportRSAPrivateKey(privateKeyBytes, out _);
        var certWithKey = cert.CopyWithPrivateKey(rsa);

        cert.Dispose();
        return certWithKey;
    }
    catch(Exception e)
    {
        Console.WriteLine(e);
    }

    return null;
}

Called from:调用自:

var clientCertificate = new X509Certificate2();
clientCertificate = CreateFromCertFile(certificateFile, keyFile);  
httpClientHandler.ClientCertificates.Add(clientCertificate);

Note: I'm able to make the request using both of these files via curl and Postman without any problem.注意:我可以通过 curl 和 Postman 使用这两个文件发出请求,没有任何问题。

I'm trying to attaching both files to the request so not tied to this specific approach.我正在尝试将这两个文件附加到请求中,以便与这种特定方法无关。 If there is a better way I'm interested in hearing about it.如果有更好的方法,我有兴趣听听。

Super late to this, and faced the same problem ASN1 corrupted data and managed to resolve my problem from both your question and the question answered by @bartonjs太晚了,遇到了同样的问题ASN1 corrupted data并设法从您的问题和@bartonjs 回答的问题中解决了我的问题

The advice on Create X509Certificate2 from Cert and Key, without making a PFX file question is 从 Cert 和 Key 创建 X509Certificate2的建议,而不提出 PFX 文件问题是

using (RSA rsa = RSA.Create())
{
    rsa.ImportRSAPrivateKey(binaryEncoding, out _);
    // do stuff with the key now
}

The clue for me was binaryEncoding , the answer is commented as part of the same question is...我的线索是binaryEncoding ,答案被评论为同一问题的一部分是......

if you had a PEM you need to "de-PEM" it, by extracting the contents between the BEGIN and END delimiters and running it through Convert.FromBase64String in order to get binaryEncoding如果你有一个 PEM,你需要通过提取 BEGIN 和 END 分隔符之间的内容并通过Convert.FromBase64String运行它来“de-PEM”它以获得binaryEncoding

So based on your code... the following imports the PEM file without issue.因此,根据您的代码...以下内容可以毫无问题地导入 PEM 文件。

        private static byte[] LoadPrivateKeyBytes(string keyFile)
        {
            // remove these lines
            // -----BEGIN RSA PRIVATE KEY-----
            // -----END RSA PRIVATE KEY-----
            var pemFileData = File.ReadAllLines(keyFile).Where(x => !x.StartsWith("-"));

            // Join it all together, convert from base64
            var binaryEncoding = Convert.FromBase64String(string.Join(null, pemFileData));

            // this is the private key byte data
            return binaryEncoding;
        }

        private static X509Certificate2 CreateFromCertFile(string cerFile, string keyFile)
        {
            try
            {
                var cert = new X509Certificate2(cerFile);
                var privateKeyBytes = LoadPrivateKeyBytes(keyFile);

                using var rsa = RSA.Create();
                rsa.ImportRSAPrivateKey(privateKeyBytes, out _);
                var certWithKey = cert.CopyWithPrivateKey(rsa);

                cert.Dispose();
                return certWithKey;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

#pragma warning disable CS8603 // Possible null reference return.
            return null;
#pragma warning restore CS8603 // Possible null reference return.
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM