I am working on an older software for a company at the moment and in my work have been upgrading a number of libraries. The app connects to a web service hosted by the third party payment processor, and in doing so it must create a digital signature of the request so that they can identify the merchant.

The gentlemen I am working with at the company provided me a .p12 file and a password and stated it was provided to him by the payment processor and contains the pki necessary for the digital signature. This file is used by the production payment web service and the test web service.

It contained three certs, what appeared to be a root self-signed by the payment processor, what appeared to be an intermediary, and the merchant cert for validating signatures. It also contained an encrypted private key for creating the signature.

I got confused though because there were some things that were strange. The intermediary and root certs were only RSA 1024 and in turn contained SHA1 signatures, however the merchant cert was RSA 2048 and had a SHA-256 signature. I honestly didnt know you could actually sign SHA2 with an RSA 1024 public private key pair. I figured that maybe the other certs in the chain were just really old and hadnt been reissued yet, but no they were last created in 2018 and 2019.

I raised an alarm though with the company when I found out that the intermediary had expired yesterday of all days. I was concerned that if the chain was not valid then payments may not be posting. The guy at the company came back at me with a new .p12 file from the payment processor, and this one had all non-expired certs, however it was basically the same, 2048 signed with SHA-256, and two 1024 certs signed by SHA1.

l wanted to verify everything just to be sure so I tried using openssl verify but consistently got that the sigs were invalid. I got frustrated and used openssl asn1parse to pull out the tbs and the signature bytes into files. I also pulled the public keys with openssl x509 and then created SHA1 and SHA-256 hashes just to make absolute sure, and the only certs that actually came back as OK were the root cert that signed itself, and the intermediate that was signed by the root.

After a lot of frustration I finally realized that the merchant cert was actually signed by the root cert, which seems very odd to me. The intermediate cert wasnt actually an intermediate at all and was just... well I don't know what. I couldn't figure out the purpose of it, why was it even there? Just to make sure this wasnt an error on the part of the payment processor I double checked the older p12 file and it is the same thing. Merchant cert signed by a self signed cert, and the arbitrary expired psuedo-intermediary just along for the ride.

Is this a normal type of keystore to be given from a financial service company? Is this something specific to digital signatures that I am missing?

  • 1
    I don't know if it's common practice, but one thing that them giving the merchant cert (instead of you generating one) means is that whoever has handled that private key can forge requests (which is why if at all possible you normally want to generate one on an HSM). It's possible that the "intermediate" cert is supposed to be the cert for the servers that you're going to be talking to, but it's weird that the process implies (somewhat) that the chain isn't descended from a public root, and that they can't just point you to a dev website to the certificates... Commented Oct 14, 2021 at 4:11
  • 1
    I'd ask them if you can generate your own certificate and send them a CSR - certificate signing request - "as you don't want to use a key that's been generated by another party if possible" (they would have used a CSR to sign your merchant cert in the first place). Also, apparently 1024-bit RSA was supposed to have been fine... until 2010. 4096-bit (or a different algorithm) are recommended now. Commented Oct 14, 2021 at 4:16
  • I don't know if it's ordinary or anything, but it's worth considering: for a self-signed cert, it is completely irrelevant what signing algorithm is used. The signature is only used for two things: verifying the issuer of the cert to determine whether to trust it, and verifying the integrity of the cert to ensure it hasn't been tampered with. Both are rendered completely moot by having the cert be in a known trust store... and for self-signed, there isn't any other way to verify them anyhow. With that said, intermediate (and leaf) certs usually do need strong signatures.
    – CBHacking
    Commented Oct 14, 2021 at 5:15
  • @Clockwork-Muse Thanks for the explanation. It sounds like it is unusual and probably not secure. Not sure if this is an explanation, but this is an older style SOAP based web service (circa 2006) that they continue support for, however it seems like their dev site recommends not using it anymore in favor of their REST api. Maybe this type of pki is just a throwback that they never bothered to improve upon because they are deprecating it? Commented Oct 14, 2021 at 13:07
  • @maple_shaft - quite probably. SOAP has a whole section about signing/encrypting messages even if (or perhaps instead of) having encrypted channels (ie, HTTPS) - SOAP was big before HTTPS became as common as it is now (and before Let's Encrypt was a thing). If you can switch to their (presumably over HTTPS) JSON API, I'd do that - note that with at least one processor I've worked with, there was no certificate signing involved, just username/passwords or an auth token in a header. Commented Oct 14, 2021 at 17:55


You must log in to answer this question.

Browse other questions tagged .