In an effort to further refine my question this is the 3rd rewrite. Here is the scenario in a nutshell.
- Legacy ASP / VBscript website
- .NET / C# COM library which is used in the ASP site
I want to send the Request.ClientCertificate("Certificate") in it's raw form to my .NET COM library and decode it so I can validate fields against the client certificate in Active Directory.
- The documentation for Request.ClientCertificate("Certificate") says that i开发者_如何学运维t's a string of the binary data that represents the certificate in ASN.1 format. My .NET method that receives this has a string type for the parameter. I've tried using Encoding.UTF8.GetBytes, Encoding.Unicode.GetBytes and Encoding.ASCII.GetBytes to convert it to a byte[] that the X509Certificate2 constructor expects.
I have tried searching Google for every shred of information I can find on how to do something useful (ie. decode) the ASP Request.ClientCertificate in it's raw form but have come up empty. I've also saved this data to a file and attempted to decode this using CertUtil but it still fails to decode the data and just errors out.
As I continue to play around with this I decided to look at the size of the client certificate returned by ASP and ASP.NET and I found the size to not match. My certificate coming from ASP was 647 bytes and 1295 bytes in ASP.NET. I don't know why the size is skewed between both environments. Consequently I have no issues whatsoever decoding the client certificate returned by ASP.NET using the X509Certicate2 class.
I've also tried using the following p/invoked function:
[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern uint CertCreateCertificateContext(uint dwCertEncodingType,
byte[] pbCertEncoded, uint cbCertEncoded);
So in either case of using X509Certificate, X509Certificate2 and the function above I get a consistent result the certificate coming from ASP is not usable by these functions. The X509Certificate class just throws an exception when I try to construct it with the byte[] representing the certificate.
I've tried using the CAPICOM library to import the certificate but I get exactly the same exception that the X509Certificate2 class gives me.
Cannot find the requested object
So in summary what I want to do is, decode the ASP Request.ClientCertificate("Certificate") from a .NET / C# COM library utilizing the X509Certificate set of classes.
I suspect the problem has to do with marshaling of the certificate data when it is transmitted through the COM interface that you have created. Notice that the ASP certificate size (647) is almost exactly half of the .NET certificate size (1295). Are you perhaps inadvertently converting an array of 8 bit bytes on the ASP side to a 16 bit Unicode string? It would help to see the interface definition of the COM server that you have created to decode the certificate.
I finally figured out the issue and it is very simple. I had to base 64 encode the Request.ClientCertificate("Certificate") using the CAPICOM Utilities class on the ASP side. Once I did that, called my .NET COM method with an ASCII conversion to byte[] and the X509Certificate2 class had no trouble with decoding the certificate.
Looking at this page it seems it's possible to take the certificate and put it into base64 encoded X509. If you pass that string to the .NET side, you can create a byte array from it and then use the X509Certificate2 constructor to create an instance of the certificate.
You'd probably be better off though using the properties of the certificate class in ASP to extract the information you want and then pass that on.
精彩评论