selective-php / xmldsig

Sign XML Documents with Digital Signatures
MIT License
73 stars 34 forks source link

Unable to verify signature value #27

Closed kumarakmuz closed 4 months ago

kumarakmuz commented 9 months ago

Hi, We are working on UPI integration where we need to sign xml message before API call. We are using this library to sign xml. The signature is verified at our level but not getting verified at API level. They are verifying signature using java code. Can anyone help us. Below is the java code shared by API development team :

package olivecrypto.upi.xml;

import java.io.FileInputStream;
import java.io.StringReader;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class VerifySignature {
    PublicKey publicKey;

    public VerifySignature(String cer) throws Exception {
        CertificateFactory certFact = CertificateFactory.getInstance("X509");
        Certificate cert = certFact.generateCertificate(new FileInputStream(cer));
        publicKey = cert.getPublicKey();
    }
    public boolean isXmlDigitalSignatureValid(String signedXml) throws Exception {
        boolean validFlag = false;
        System.out.println("signedXml" + signedXml);
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        Document doc = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(signedXml)));
        System.out.println("doc" + doc);
        NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
        if (nl.getLength() == 0) {
            throw new Exception("No XML Digital Signature Found, document is discarded");
        }
        DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(0));
        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
        XMLSignature signature = fac.unmarshalXMLSignature(valContext);
        validFlag = signature.validate(valContext);
        return validFlag;
    }
}
odan commented 9 months ago

Hi @kumarakmuz

I was able to successfully validate a signed (by this PHP package) XML file using Java.

Algo: SHA512

image

Make sure to use the correct certificate file. It works with a PEM for the public key but not with a P12 file in Java. Also use SHA512 and not SHA1 to sign the XML files, because SHA1 is "forbidden" for security reason in the Java ecosystem.

Can you try that?

odan commented 9 months ago

We are using sha256 is it ok

Yes, this is OK.

Our PHP code

Note, that this PHP package must be used with the composer autoloader in order to work correctly.

Try the following example:

<?php

require_once __DIR__ . '/vendor/autoload.php';

use Selective\XmlDSig\Algorithm;
use Selective\XmlDSig\CryptoSigner;
use Selective\XmlDSig\PrivateKeyStore;
use Selective\XmlDSig\XmlSigner;

// The xml contents you want to sign
$xmlContents = '<?xml version="1.0"?><root></root>';

$privateKeyStore = new PrivateKeyStore();

$algo = Algorithm::METHOD_SHA256;

$privateKeyFile = 'path/to/file.p12';
$password = 'secret';

$privateKeyStore->loadFromPkcs12(file_get_contents($privateKeyFile), $password);

$algorithm = new Algorithm($algo, $algo);
$cryptoSigner = new CryptoSigner($privateKeyStore, $algorithm);
$xmlSigner = new XmlSigner($cryptoSigner);

$signedXml = $xmlSigner->signXml($xmlContents);

file_put_contents('signed.xml', $signedXml);

Then give that signed XML file your API development team for validation.

API team using our .cer file to verify signature.

Without code example it's hard to help here. In Java I have successfully used a PEM file for the validation with the the public key. Maybe try this.

odan commented 9 months ago

You have installed an older version 2.4. The latest version of this package is 3.1. Check your composer.json file and upgrade to ^3 or reinstall the new package version with

composer require selective/xmldsig "^3"
kumarakmuz commented 9 months ago

ok and other things will remain same ?

odan commented 9 months ago

Unfortunately, I do not offer free Java code consulting, but I can send you my working Java code for a small fee if you are interested.

kumarakmuz commented 9 months ago

Unfortunately, I do not offer free Java code consulting, but I can send you my working Java code for a small fee if you are interested.

ok, No issue we can pay. Kindly plan to connect

odan commented 9 months ago

@kumarakmuz You can contact me here: https://twitter.com/dopitz

kumarakmuz commented 9 months ago

Kindly share your skype id so that we can connect

odan commented 9 months ago

Ok, here you can find my Skye ID: https://odan.github.io/about.html#contact