This project is read-only.

Help with IPAWS 3 and Digital Signatures on .NET

We have found that people are having problems with digital signatures IPAWS 3. We sure had problems too. We cover how to use our proxy code in the README file, but thought putting some questions and answers we have fielded in a wiki for others to use.

Since these are excerpts from emails this is in somewhat of a "thread" format...

More information on signing with an IPAWS certification can be found here... IPAWS Proxy Library Help

Q&A 1


1) Are you able to successfully use the WSDL provided at https://tdl.integration.fema.gov/IPAWS_CAPService/IPAWS?WSDL and not have anything lost in translation so the signature will still work? Do you use the “Any” field to pass the signature?

2) I’m using Linq2XML to parse the CAP file but I have all the PreserveWhitespace stuff in there. Do you think that may be causing a problem?

3) What encoding are you using?

4) Gary had mentioned that he uses a method called “SetAlert()” but it’s not in the wsdl and I can’t find it documented anywhere. Have you been able to get the postCAP that IS documented working through the wsdl (work’s fine for me, except for the signature)?

1. I had to make a few tweaks to the reference class that was generated from the WSDL (in Oct).
a. Had to remove Default language from language string
b. Had to add the appropriate namespaces to getRequestResponse parameterListItem, getRequestInput parameters, getMessageInput parameters
c. Had to the XML root and namespace attribute to the alert class
2. I am not sure. We created a custom set of classes to serialize and deserialize the EDXL/CAP data. It is something I could look at, if you would like.
3. We are using UTF8.
4. Yes. It took quite a bit to figure out, but here is the gist of what we found.
We needed to include a class for a RSA256 security descriptor (can be found athttp://clrsecurity.codeplex.com/ ). It had to be registered before trying to sign with it. We then serialized the CAP object to a memory stream without any namespaces, loaded that ms into an XML Doc, and used the SIgnedXML class to sign it using the private key of certificated provided by FEMA. Because of some issues with the certificate, we needed to create our own friendly name for the certificate. Finally, we had to export the IPAWS certificate to a PEM format (I got it in pfx format) and then import the PEM to a p12 format while associating the certificate to the “Microsoft Enhanced RSA and AES Cryptographic Provider”. I used OpenSSL for this. This process lost the friendly name of the certificate as provided by FEMA, hence we needed to recreate the friendly name in code.

Q&A 2

1) I think I have all the wsdl proxy class stuff created correctly but it would be nice to see what your reference class looks like. You are correct. It did not work “out of the box”.
2) I use the Security.Cryptography.RSAPKCS1SHA256SignatureDescription and a memory stream to generate my Digest Value but I do not think I’m doing it right. Could you provide a code sample that demonstrates how you create the whole capsig:Signature xml structure (not asking for much am I)? I thought that the sha256 signature stuff did not “bubble up” to the SignedXML class so I created all that stuff from scratch. I probably messed something up somewhere.
3) When I include the Codeplex clrsecurity “Security.dll” in my project instead of the Microsoft.Security reference, my SOAP envelope stops working with an error message along the lines of “The server binding endpoint is not communicating with http”???. Any thoughts on that?
4) I received a .pfx (which is better than just a .jks, which is what my predecessor received) and have been using that ever since so I haven’t even researched that whole process yet. I guess I’ll get there when I get there. I’ll download OpenSSL.

1. I will send along our reference class. It only has auto-generated comments, but it should still be of some use.
2. I will send along the code that we use to serialize and sign the XML. Obviously, your serialization will be different, but it might help with what is not working on your end.
3. We did not include the whole security dll in our project. I only included the relevant class for the RSA256 descriptor. If you use the whole class, there was an extra one-time step that you needed to do to register the dll properly with Windows. I didn’t want anyone using our lib to have to deal with that.
4. I will send along the OpenSSL commands that I used.

Q&A 3

I went through openSLL and I’m using the .p12 certs (created by the command lines that you sent me) Installed them (lost the friendly name as you said I would)

I’m able to successfully call the following method and step through the class you gave me in my project

CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription),"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

And then step through the code you provided…

BUT when I call signedXml.ComputeSignature(); I get an error “Invalid Algorithm Specified”

Hmmm…what OS are you using? It might make a difference. That error is because the RSA256 algorithm is not being recognized. Let me go through my notes and see what I can find. You may have to unregister the CLR dll and remove it from your project. Did you look at the app.config that I sent? Are you using similar settings?

We had to…
1. Add the RSA security descriptor class
2. Add the algorithm
3. Specify the cert use the enhanced crypto provider
4. Use memory stream instead of string writer/reader

Q&A 4

I loaded the p12 cert as follows:

this.cert256 = new System.Security.Cryptography.X509Certificates.X509Certificate2(sCertDir256 + sCertName, sCertPW);

I do not set any properties after that but I do call al the code that you sent for the signXML class including:

signedXml.SigningKey = this.cert256.PrivateKey;
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoData = new KeyInfoX509Data();
keyInfoData.AddSubjectName(GetFriendlyName());
keyInfoData.AddCertificate(this.cert256);
keyInfo.AddClause(keyInfoData);
signedXml.KeyInfo = keyInfo;

If you did the openSSL commands, you did #3. Everything looks right. I didn’t do anything with the private key other than assigning it to the signing key. There are issues with XP not working. Vista should work. We are using Win7, so I know that works.

Q&A 5

C:\OpenSSL\bin>openssl pkcs12 -in C:\Certs\DMOPEN100014.pfx -out C:\Certs\DMOPEN100014.pem ûnodes
Usage: pkcs12 options
where options are
-export output PKCS12 file
-chain add certificate chain
-inkey file private key if not infile
-certfile f add all certs in f
-CApath arg - PEM format directory of CA's
-CAfile arg - PEM format file of CA's
-name "name" use name as friendly name
-caname "nm" use nm as CA friendly name (can be used more than once).
-in infile input filename

but FEMA provided me with a .pem file so I just skipped that step and used the second command to create the p12 file which worked just fine (I hope).

C:\OpenSSL\bin>openssl pkcs12 -export -in c:\certs\DMOPEN_100014.pem -i
nkey c:\certs\DMOPEN_100014.pem -CSP "Microsoft Enhanced RSA and AES Cryptograph
ic Provider" -out C:\certs\DMOPEN_100014.p12
Loading 'screen' into random state - done
Enter pass phrase for c:\certs\DMOPEN_100014.pem:
Enter Export Password:
Verifying - Enter Export Password:

C:\OpenSSL\bin>

The .p12 file is created…….. (then I register using the windows cert wizard)

Still searching for answers but the key seems to be that the cert256.PrivateKey.SignatureAlgorithm = sha1 when viewed in the Visual Studio debugger, which would mean that the following command is not working as expected:

openssl pkcs12 -export -in c:\certs\DMOPEN100014.pem -inkey c:\certs\DMOPEN100014.pem -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider" -out C:\certs\DMOPEN_100014.p12

However, The details of the cert Signature Algorithm when I look at it using internet explorer are sha256.

Here is a link to the OpenSSL commands for pkc12…

http://www.openssl.org/docs/apps/pkcs12.html#

Q&A 6

Last edited Mar 15, 2013 at 7:30 PM by bwilkinsnh, version 2

Comments

No comments yet.