4

I'm trying to implement authentication for MasterCard Match, as part of their following documentation, they have a sample private key:

https://developer.mastercard.com/portal/display/api/OAuth+Validation

On that page, they have two versions of the key, one in base64 encoded text, visible on the page, and a .p12 file downloadable.

How do I import this key to use as an x509certificate2?

Whatever I try I get the message "Cannot find the requested object.".

I tried digging into it with the .net source, but I get a dead end at an imported object

[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern uint _QueryCertFileType(string fileName);

I've tried the following, and all of them fail with the same aforementioned message

new X509Certificate2(@"c:\test\mc-openapi-csr.pem")
new X509Certificate2(@"c:\test\mc-openapi-csr.pem", "mcapi")
new X509Certificate2(@"c:\test\mc-openapi-csr.pem", "mckp")

so I copied the text block into "copied.txt", and tried using that file, I've also tried reading the bytes in, and passing them in manually, I've also tried using

X509Certificate.CreateFromCertFile(fileName)

with both files.

Any ideas? Is the certificate bad? Am I using the wrong class? What does that error message mean?

--Update-- At Bad Zombie's suggestion, I tried BouncyCastle:

    var pem = new Org.BouncyCastle.OpenSsl.PemReader(File.OpenText(fileName));
    RsaPrivateCrtKeyParameters rsaParameters = (RsaPrivateCrtKeyParameters)pem.ReadObject();
    using (var rsa = new RSACryptoServiceProvider())
    {
        rsa.ImportParameters(new RSAParameters
            {
                DP = rsaParameters.DP.ToByteArray(),
                DQ = rsaParameters.DQ.ToByteArray(),
                Exponent = rsaParameters.Exponent.ToByteArray(),
                InverseQ = rsaParameters.QInv.ToByteArray(),
                Modulus = rsaParameters.Modulus.ToByteArray(),
                P = rsaParameters.P.ToByteArray(),
                Q = rsaParameters.Q.ToByteArray(),
            });
    }

on the "ImportParameters" call, I get "Bad Data". Am I doing something wrong?

McKay
  • 12,334
  • 7
  • 53
  • 76

2 Answers2

2

I can't remember exactly but I believe pem files can not be used. You'll need something like bouncy castle.

I don't remember much but it loads PEM files. Occasionally it will not like it but its somewhat rare. I don't know if it can be used but I do know i successfully used private/public keys with it. I have no idea how to convert it to something that works with .NET ssl library.

However I suggest you convert it to pem to something that is more compatible with .NET implementation if you are using .net implementation rather then bouncy castle. I used bouncycastle and it worked for my project which didnt need to interface with another library.

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.OpenSsl;
using System.IO;
using System.Security.Cryptography;

//elsewhere

        using (var reader = File.OpenText(fileName))
        {
            var pemReader = new PemReader(reader);
            var bouncyRsaParameters = (RsaPrivateCrtKeyParameters)pemReader.ReadObject();
            var rsaParameters = DotNetUtilities.ToRSAParameters(bouncyRsaParameters);
            this.PrivateKey = new RSACryptoServiceProvider();
            this.PrivateKey.ImportParameters(rsaParameters);
        }
McKay
  • 12,334
  • 7
  • 53
  • 76
  • If pen files cannot be used, does that mean the certificate type is not supported? Or is it just the file format, and I can change it manually? – McKay Dec 07 '12 at 02:32
  • Is bouncy castle compatible with x509certificate? – McKay Dec 07 '12 at 02:33
  • @McKay: I have no idea. I know pem is a base64 encoding of x509 with a line at the top and bottom of it. But... your talking about the .net class. I dont think it is but if you only need to verify something and dont need to use MS .NET stuff then you might be able to use it. I'm not familar with the mastercard API. Also if their api has a C# kit/lib isnt there some sort of example? I just know I can do what you asked in the title, use a private key in C# with pem file using bouncy castle. Maybe you should try p12 file. Maybe MS supports it –  Dec 07 '12 at 02:56
  • @McKay: You'd probably have better luck using p12, it may be compatible or you can use openssl to change the format. I know i tried using .NET built in stuff with pem and it didnt fly –  Dec 07 '12 at 03:15
  • MasterCard doesn't have a .net API. I couldn't get the base64 decoded bytes loaded as an x509 cert, and I couldn't get the p12 file imported either. What should I do with the p12 file in openssl to get it to import into x509certificate? – McKay Dec 07 '12 at 03:17
  • hmm msdn says "ASN.1 DER is the only certificate format supported by this class." http://msdn.microsoft.com/en-us/library/ykwkw5f9.aspx says. Try converting pem to der? http://www.sslshopper.com/article-most-common-openssl-commands.html `openssl x509 -outform der -in certificate.pem -out certificate.der` But i really dont know if this is correct. I always thought pfx/p12 had built in support by MS. `openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt`. These commands are on that page. Try the der first though –  Dec 07 '12 at 06:31
  • I couldn't get openssl to convert it to a usable format for me in .net – McKay Dec 07 '12 at 21:44
-2

You could try to use a relative path instead of an absolute one?

Just put the file in the root of your project and try to use only the filename, without the path.

WowtaH
  • 1,488
  • 2
  • 11
  • 19