@xingzhougmu commented on Sat Sep 02 2017
cannot import X509Certificate from file in .net core 2.0
The following code works perfectly in .net core 1.0, however, does not in .net core 2.0.
X509Certificate clientCert = new X509Certificate(Directory.GetCurrentDirectory() + "/Certs/Production/CN_Certificate.crt");
Under .net core 2.0, the exception is as below:
{Interop+AppleCrypto+AppleCommonCryptoCryptographicException: Unknown format in import.
at Interop.AppleCrypto.X509ImportCertificate(Byte[] bytes, X509ContentType contentType, SafePasswordHandle importPassword, SafeKeychainHandle keychain, Boolean exportable, SafeSecIdentityHandle& identityHandle)
at Internal.Cryptography.Pal.CertificatePal.FromBlob(Byte[] rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName)
at Test.Program.Main(String[] args) in /Users/xzhou/Projects/Test/Program.cs:line 40}
For some issues, you will get a quicker and better response if you file it at a more specific .NET repo. For example, if the problem is with ASP.NET Core, you are encouraged to use the aspnet/home repo.
@xingzhougmu can you share a file which produces that behavior?
I created a reproducible case that demonstrates the error. I don't have a Windows machine available to me right now but I have used similar code on Windows without issue.
https://gist.github.com/chrishoffman/4917a03870d2e3e8489af714495de537
Actually, I was able to get the above code to work by base64 decoding. This code was previously developed on .NET core 1.1 and worked there. Maybe something changed in how the bytes were interpreted between the versions?
@chrishoffman For best results use either the DER-binary or the PEM (Base64 with the header and footer). Plain base64 isn't anything I had any idea Windows would load until recently :).
Maybe something changed in how the bytes were interpreted between the versions?
Yep, all of certificates and TLS and asymmetric cryptography was rewritten on macOS for 2.0 (Security.framework instead of OpenSSL)
Using the native stack sounds to great to me. I am curious what the compatibility break was introduced in 2.0 but it seems easy enough to work around. It is possible that 1.1 allowed for base64 encoded DER as input while 2.0 does not. Thanks for the continued advancement.
Hi,
I'm facing a similar issue; I have code that was working on framework, but it's not working on core/standard. I have a Azure Functions project I'm converting from 1.x to 2.0. I'm validating an Outlook add-in Identity token, and I'm using this code from another sample to create certs from the metadata URL..
My actual code:
```C#
if (string.Compare(key.KeyInfo.Thumbprint, Header.X5t, StringComparison.InvariantCulture) == 0 && string.Compare(key.KeyValue.Type, "x509Certificate", StringComparison.InvariantCulture) == 0)
{
try
{
var cert = new X509Certificate2(Encoding.UTF8.GetBytes(key.KeyValue.Value));
var secKey = new X509SecurityKey(cert);
signingKeys.Add(secKey);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
Sample response from the Exchange metadata URL
```javascript
{
"id": "_47632aae-5dfa-4ddb-a15a-8dbe6c35a007",
"version": "1.0",
"name": "Exchange",
"realm": "*",
"serviceName": "00000002-0000-0ff1-ce00-000000000000",
"issuer": "00000002-0000-0ff1-ce00-000000000000@*",
"allowedAudiences": [
"00000002-0000-0ff1-ce00-000000000000@*"
],
"keys": [
{
"usage": "signing",
"keyinfo": {
"x5t": "BgD59nRiBzfnNATih8RagYy3zrg"
},
"keyvalue": {
"type": "x509Certificate",
"value": "MIIHSjCCBTKgAwIBAgITFgAAbj8rLop6Gl4g1gAAAABuPzANBgkqhkiG9w0BAQsFADCBizELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEVMBMGA1UECxMMTWljcm9zb2Z0IElUMR4wHAYDVQQDExVNaWNyb3NvZnQgSVQgVExTIENBIDQwHhcNMTcxMjE0MjMyNTE4WhcNMTkxMjE0MjMyNTE4WjAqMSgwJgYDVQQDEx9lc3RzY2xpZW50LmNvcmVhdXRoLm91dGxvb2suY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+etM0+/LhZZ1QgUk9ZwhW9tfQlqveV10DRHhrqKxPfNeI5YRASRHtsFqXcwfE0OQASDF7bWQPCA1TcECaj6wkJZjEGJEB/WOZ7b3Eo3QQf7BBAqIbqn4Rv+XQpm0bPUcfiTusk1k72cMAPCqd93m6zx7yXe5z7ZHPH8oyOHtlMvvcH4cFPWMwG/S2GPpyCKAGv8FW2nzmZWwSr76wFebBPX98HCEcxhJkTNVe1+5m5bQBGdEmWni1d6IsIg29VQgx1RwuiI9m6XA+c0MZJN1kAkR2g5HEtzeJ1JSrFjp2ZSxLWIzuHThqSZ+f94DCaKBygb+A3+AvyA1fRRXUzQNwIDAQABo4IDBTCCAwEwCwYDVR0PBAQDAgSwMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATB4BgkqhkiG9w0BCQ8EazBpMA4GCCqGSIb3DQMCAgIAgDAOBggqhkiG9w0DBAICAIAwCwYJYIZIAWUDBAEqMAsGCWCGSAFlAwQBLTALBglghkgBZQMEAQIwCwYJYIZIAWUDBAEFMAcGBSsOAwIHMAoGCCqGSIb3DQMHMB0GA1UdDgQWBBRFRZN8SQgkfAd907K1/y/VgnDMQTAfBgNVHSMEGDAWgBR6e4zBz+egyhzUa/r74TPDDxqinTCBrAYDVR0fBIGkMIGhMIGeoIGboIGYhktodHRwOi8vbXNjcmwubWljcm9zb2Z0LmNvbS9wa2kvbXNjb3JwL2NybC9NaWNyb3NvZnQlMjBJVCUyMFRMUyUyMENBJTIwNC5jcmyGSWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvbXNjb3JwL2NybC9NaWNyb3NvZnQlMjBJVCUyMFRMUyUyMENBJTIwNC5jcmwwgYUGCCsGAQUFBwEBBHkwdzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9tc2NvcnAvTWljcm9zb2Z0JTIwSVQlMjBUTFMlMjBDQSUyMDQuY3J0MCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC5tc29jc3AuY29tMD4GCSsGAQQBgjcVBwQxMC8GJysGAQQBgjcVCIfahnWD7tkBgsmFG4G1nmGF9OtggV2E0t9CgueTegIBZAIBGjBNBgNVHSAERjBEMEIGCSsGAQQBgjcqATA1MDMGCCsGAQUFBwIBFidodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL21zY29ycC9jcHMwJwYJKwYBBAGCNxUKBBowGDAKBggrBgEFBQcDAjAKBggrBgEFBQcDATAqBgNVHREEIzAhgh9lc3RzY2xpZW50LmNvcmVhdXRoLm91dGxvb2suY29tMA0GCSqGSIb3DQEBCwUAA4ICAQAEM6kYpbLe8lN40keaJSZTBsNFGF8iddZgv6LldFY3Tp0YABoQeQofxwdKyd20AbBBSYqhok5pVq5pNEwM3yfii99a2WX0FWog4kGDN2G2MqK/t22TalvDGD1hqjw/Sannxom8JA8FnwzOV2XqI9OrsNHvVK0wUSfQK6uQMGB2JnNSDZYm+DXbMaAwKRV+psfblBLoNfYHoCCDo+KVlLCZ57iQXY+FB0DqsgiGuxuwRl9jwHyhVh8pJSEU09rzZos9qpX/v55TbMqtshEy+BEeMpWcyWPzCHlOF0bnTQ8rCbLotJNQEVVTZK8dNuIT9oNIvjPYrjkATMgX6LwwdNNWYOzuuUm8S/OeZPCFQnbsg0ZXOf3zXFoAKpX+sJ19hZR8atF36FnvCQ8oQqlHyymldBQ/mfh8NfY/lCtFgKnzginjRNq8liMiXPiuiXb7Ru8NFpEVAGvi/6MQp/17DzhVzxF0+PsAlYah1PK/KYcea6nOfD0eldp4XAjHmBgw4f19d4quze+hrRVzqUBawVtXdjtkGD72A4y17CIQrh2AcOuXHQwzX40S+NxPfSzCKkq6wBNg/sZ1CgASWxcagDyqevuqk81BfrauGL8SBmJRvc2LqS4Z3z4Cn66r3Q4tiD7QCKoRef+KUASP/ir/+Gqd6NZ146S28qITFKEMG073DQ=="
}
},
{
"usage": "signing",
"keyinfo": {
"x5t": "enh9BJrVPU5ijV1qjZjV-fL2bco"
},
"keyvalue": {
"type": "x509Certificate",
"value": "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"
}
}
],
"endpoints": [
{
"location": "https://bn4pr07mb2147.namprd07.prod.outlook.com:444/autodiscover/metadata/json/1/",
"protocol": "OAuth2",
"usage": "metadata"
}
]
}
I get a Interop+AppleCrypto+AppleCommonCryptoCryptographicException: Unknown format in import. exception.
Any ideas?
Looks like you also have base64, rather than using Encoding.UTF8.GetBytes, use Convert.FromBase64String.
You are 100% correct! Thank you sir.
I'm trying to load this cert but i'm also getting
[23:27:03 ERR] Unknown format in import.
Interop+AppleCrypto+AppleCommonCryptoCryptographicException: Unknown format in import.
``` c#
var certByte = System.IO.File.ReadAllBytes("./stg-myinfo-2018.pem");
var x509Cert = new X509Certificate2(certByte);
I've cloned that repo and it seems to be able to load the certificate just fine using nodejs.
I've also tried using
```c#
var certString = <omitted for brevity>;
var certByte = Convert.FromBase64String(certString);
var cert = new X509Certificate2(certByte);
and also Encoding.UTF8.GetBytes, none of them seems to work, is it something wrong with the cert or am i missing something :frowning_face:
@murugaratham That's an RSA private key in PKCS#8 format, not a certificate.
C#
RSA rsa = RSA.Create();
rsa.ImportPkcs8PrivateKey(thatFileAfterBase64Decode);
@bartonjs which namespace/extension does ImportPkcs8PrivateKey belong to? i'm getting
c#
'RSA' does not contain a definition for 'ImportPkcs8PrivateKey' and no accessible extension method 'ImportPkcs8PrivateKey' accepting a first argument of type 'RSA' could be found (are you missing a using directive or an assembly reference?) (CS1061)
Oh my, i just found on MS docs that it is on .net core 3.0 only, are they other options?
If you're on Windows, you can use the Cng package, and do
C#
using (CngKey key = CngKey.Import(blob, CngKeyBlobFormat.Pkcs8PrivateBlob))
using (RSA rsa = new RSACng(key))
{
...
}
If you're on Linux or macOS then there's no other built-in solution; but you could try something like https://stackoverflow.com/questions/50227580/create-x509certificate2-from-pem-file-in-net-core/50236577#50236577.
Thanks for your input @bartonjs, I've used pem-utils, https://github.com/huysentruitw/pem-utils
For dotnetcore on Mac it's serving my use case.
I'm trying to import a .cert file but i get the same error describled in this issue.
Any news?
@EltonAlvess what sort of format is your certificate file in?
I was able to resolve this issue by creating a pkcs12 file from my cert & key. You can use the following command.
openssl pkcs12 -export -out Cert.p12 -in your-cert.pem -inkey your-key.pem
And then
var certificate = new X509Certificate2(your-p12-bytes, your-pass);
Most helpful comment
Looks like you also have base64, rather than using Encoding.UTF8.GetBytes, use Convert.FromBase64String.