Witam
Borykam się już od pewnego czasu z implementacją komunikacji z portalem ePuap w Java, a dokładniej chodzi mi o zaimplementowanie całej ich koperty SOAP do komunikacji. Szukając w internecie okazało się że nie ma tego wiele. Bardzo pomocna była strona http://www.extern.pl/artykuly/ws-security_epuap/. Na początku zabrnąłem niestety w ślepą uliczkę (przynajmniej tak mi się wydaje) bo do podpisu używałem biblioteki WSS4J, niestety jak się okazuje Xades to chyba troszeczkę coś innego. Przy WSS4J używałem takiego kodu
WSSConfig.init();
String soapXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:user=\"http://userinfo.zp.epuap.gov.pl\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" +
"<SOAP-ENV:Body xmlns:ns=\"http://ejb.draco.comarch.com\">" +
"<ns:getUserInfo>" +
"<ns:tgsId></ns:tgsId>" +
"<ns:appId></ns:appId>" +
"</ns:getUserInfo>" +
"</SOAP-ENV:Body>" +
"</SOAP-ENV:Envelope>";
Document doc = SOAPUtil.toSOAPPart(soapXML);
Properties clientProperties = new Properties();
clientProperties.put("org.apache.wss4j.crypto.provider", "org.apache.wss4j.common.crypto.Merlin");
clientProperties.put("org.apache.wss4j.crypto.merlin.keystore.type", "jks");
clientProperties.put("org.apache.wss4j.crypto.merlin.keystore.password", "haslo");
clientProperties.put("org.apache.wss4j.crypto.merlin.keystore.alias", "alias");
clientProperties.put("org.apache.wss4j.crypto.merlin.keystore.file", "plik.jks");
Crypto crypto = new Merlin(clientProperties, this.getClass().getClassLoader(), null);
WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(doc);
WSSecTimestamp timestamp = new WSSecTimestamp();
timestamp.setTimeToLive(3 * 3600);
doc = timestamp.build(doc, secHeader);
WSSecSignature builder = new WSSecSignature();
builder.setUserInfo("uzytkownik", "haslo");
builder.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);
List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
WSEncryptionPart encP = new WSEncryptionPart("Timestamp", WSConstants.WSU_NS,"");
WSEncryptionPart bodyPart = new WSEncryptionPart(WSConstants.ELEM_BODY, WSConstants.URI_SOAP11_ENV, "");
parts.add(bodyPart);
parts.add(encP);
builder.setParts(parts);
Document signedDoc = builder.build(doc, crypto, secHeader);
W wyniku czego dostawałem taką kopertę:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:user="http://userinfo.zp.epuap.gov.pl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" SOAP-ENV:mustUnderstand="1">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" Id="e6bac805-2ee5-4d82-8e8e-ee4c0a37e705" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">MIICSjCCAbOgAwIBAgIJAIXSDNq9Dr0hMA0GCSqGSIb3DQEBBQUAMG0xCzAJBgNVBAYTAlBMMR4wHAYDVQQKExVDUEkgQ0EgZm9yIGVwdWFwIFRFU1QxHjAcBgNVBAsTFUNQSSBDQSBmb3IgZXB1YXAgVEVTVDEeMBwGA1UEAxMVQ1BJIENBIGZvciBlcHVhcCBURVNUMB4XDTE0MDgxNTAwMDAwMFoXDTE2MDgxNDIzNTk1OVowRTELMAkGA1UEBhMCUEwxDDAKBgNVBAoTA0NQSTETMBEGA1UECxMKZGFtaWFuU29mdDETMBEGA1UEAxMKZGFtaWFuU29mdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzXr0F9mUTQ5Ow4XqwEpCEsGZKBG+OrSmqFzFpC+gC23L96gnFYVGl5Cv5vT8fMnRlb9m7ebsH7bVFL1UsRbg4xyRi8Rf/kefSGOZmtmQG3X1BsfLsYfhXBhYC8qvjJfnm8pVaHZ1joxcUapzwTQp2Se/EFTAodJV24JL8T8XdXcCAwEAAaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQEFBQADgYEAF2+pSbCJzxg0Zd75fO0zNviPvZJU6FD2aq6YQGKGghMSfBXH6M3oX6AdHWD9nXrvGCqB6aNBdeww1RbF7qOugUYxmZ6fqxVRwADrSP81Uz8rLBQVovieCjlXdeWvXt4CGyeu1AcdXYMnsdTtvXHHAdAoqMTP+klPAM0MrsN+GRA=</wsse:BinarySecurityToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-444db4cb-7f98-469a-acc5-f15470eaf298">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="SOAP-ENC SOAP-ENV user xsd xsi" />
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#id-de9cadef-6ab1-4f68-9106-b7c87ed85a95">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="SOAP-ENC user xsd xsi" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>QGFHPvQm0xoKx6UfJioDhycuvzg=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#TS-15747850-9adf-4990-a5ee-8c23bb50ba87">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="wsse SOAP-ENC SOAP-ENV user xsd xsi" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>24WiH+AtrGk4tcUVi/mj5mTEPxM=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>ZRRjF9ejiNp8v89CgEIpPJTAn87RGL5f6/49XvdN1IfRrjbiEmYidbi0GH9Dafuh5Y1OnG5qzSg3BdCLRX3iAgciomGw7EpEg6m9SSzKZC3iwCMtLaEGdzkKHYqMkdJrb6h0PYBSYJ9JUNbYbBewt1/ksSXkChWehGMyLRspeR8=</ds:SignatureValue>
<ds:KeyInfo Id="KI-218aa69e-2dd2-41ee-bcaa-482a8cefd64b">
<wsse:SecurityTokenReference wsu:Id="STR-d9f5821a-36ec-4e5c-9887-2158e68ee1ff">
<wsse:Reference URI="#e6bac805-2ee5-4d82-8e8e-ee4c0a37e705" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp wsu:Id="TS-15747850-9adf-4990-a5ee-8c23bb50ba87">
<wsu:Created>2015-01-22T11:47:58.057Z</wsu:Created>
<wsu:Expires>2015-01-22T14:47:58.057Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body xmlns:ns="http://ejb.draco.comarch.com" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-de9cadef-6ab1-4f68-9106-b7c87ed85a95">
<ns:getUserInfo>
<ns:tgsId></ns:tgsId>
<ns:appId></ns:appId>
</ns:getUserInfo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Niestety ePuap odrzucał moje zapytanie z odpowiedzią WSDoAllReceiver: security processing failed. Uruchomiłem sobie oczywiście kod w PHP z wymienionej wcześniej strony i jak to bywa on działa a obie koperty wyglądają tak samo (tzn. różnią się wartości DigestValue oraz SignatureValue i stąd wynika zapewne różnica w stosunku do Xades). Zacząłem próbować z biblioteką Xades4J na podstawie kodu z wątku Podpis Xades na pliku XML ale jak na razie bez pozytywnych rezultatów tzn. to co wygenerowałem zupełnie nie przypomina pokazanej wcześniej koperty nie mówiąc już o wartości sygnatury. Kod:
String alias = "";
char haslo[] = "haslo".toCharArray();
// zaladowanie pliki p12
KeyStore store = KeyStore.getInstance("PKCS12");
store.load(new FileInputStream("plik.p12"), haslo);
// wyciagnij klucz prywatny
Key privKey = store.getKey(alias, haslo);
final PrivateKey privateKey = (PrivateKey) privKey;
// wyciagnij certyfikat
final X509Certificate cert = (X509Certificate) store.getCertificate(alias);
// provider dla xades
KeyingDataProvider keyingDataProv = new KeyingDataProvider() {
public List<X509Certificate> getSigningCertificateChain() throws SigningCertChainException, UnexpectedJCAException {
return (List<X509Certificate>) (Object) Arrays.asList(cert);
}
public PrivateKey getSigningKey(X509Certificate signingCert) throws SigningKeyException, UnexpectedJCAException {
return privateKey;
}
};
AlgorithmsProviderEx ap = new DefaultAlgorithmsProviderEx() {
@Override
public String getDigestAlgorithmForDataObjsReferences() {
return "http://www.w3.org/2000/09/xmldsig#sha1";
}
@Override
public Algorithm getSignatureAlgorithm(String keyAlgorithmName)
throws UnsupportedAlgorithmException {
return new GenericAlgorithm(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
}
@Override
public String getDigestAlgorithmForReferenceProperties() {
return "http://www.w3.org/2000/09/xmldsig#sha1";
}
};
// plik xml do podpisania
String inputFile = "";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
org.w3c.dom.Document inDoc = db.parse(new FileInputStream(inputFile));
// profil podpisu xades
XadesSigningProfile profile = new XadesBesSigningProfile(keyingDataProv).withAlgorithmsProviderEx(ap);
// zmienna podpisujaca
XadesSigner signer = profile.newSigner();
// dodatkowe dane do podpisu
SignedDataObjects dataObjs = new SignedDataObjects();
DataObjectReference obj = new DataObjectReference("");
obj.withTransform(new DataObjectTransform("http://www.w3.org/2001/10/xml-exc-c14n#"));
dataObjs.withSignedDataObject(obj);
// podpisanie
signer.sign(dataObjs, inDoc.getDocumentElement());
// Zapis podpisanego pliku
String outputFile = "";
OutputStream os = new FileOutputStream(outputFile);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(inDoc), new StreamResult(os));
Wynik:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:user="http://userinfo.zp.epuap.gov.pl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body xmlns:ns="http://ejb.draco.comarch.com" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" Id="abcd">
<ns:getUserInfo>
<ns:tgsId></ns:tgsId>
<ns:appId></ns:appId>
</ns:getUserInfo>
</SOAP-ENV:Body>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="xmldsig-089c463a-9afe-480d-9e39-4e7fe1eb00e7">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference Id="xmldsig-089c463a-9afe-480d-9e39-4e7fe1eb00e7-ref0" URI="">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>TI95y7S79osPz9WCiRXwptz2vmE=</ds:DigestValue>
</ds:Reference>
<ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xmldsig-089c463a-9afe-480d-9e39-4e7fe1eb00e7-signedprops">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>2Rl17TWjQZ71k2e9vtMX1uUFxN0=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue Id="xmldsig-089c463a-9afe-480d-9e39-4e7fe1eb00e7-sigvalue">YpuextXY+k3GG+BPtlkJ97U99udTZe5z6ushOlihHcyt9LG2DobBc44C0YgyBxKVmzAe8coMzm+5
DMrFhBLVHBEx45Mka4o6jOpQoxvUQD6OM5nU8xbt1m7dZ7+3VzlilmiJVQL1kdA5R0HFbI9DrRlD
C89Y0+h0idS+vh/5gAo=</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIICSjCCAbOgAwIBAgIJAIXSDNq9Dr0hMA0GCSqGSIb3DQEBBQUAMG0xCzAJBgNVBAYTAlBMMR4w
HAYDVQQKExVDUEkgQ0EgZm9yIGVwdWFwIFRFU1QxHjAcBgNVBAsTFUNQSSBDQSBmb3IgZXB1YXAg
VEVTVDEeMBwGA1UEAxMVQ1BJIENBIGZvciBlcHVhcCBURVNUMB4XDTE0MDgxNTAwMDAwMFoXDTE2
MDgxNDIzNTk1OVowRTELMAkGA1UEBhMCUEwxDDAKBgNVBAoTA0NQSTETMBEGA1UECxMKZGFtaWFu
U29mdDETMBEGA1UEAxMKZGFtaWFuU29mdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzXr0
F9mUTQ5Ow4XqwEpCEsGZKBG+OrSmqFzFpC+gC23L96gnFYVGl5Cv5vT8fMnRlb9m7ebsH7bVFL1U
sRbg4xyRi8Rf/kefSGOZmtmQG3X1BsfLsYfhXBhYC8qvjJfnm8pVaHZ1joxcUapzwTQp2Se/EFTA
odJV24JL8T8XdXcCAwEAAaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCB4AwDQYJKoZIhvcNAQEF
BQADgYEAF2+pSbCJzxg0Zd75fO0zNviPvZJU6FD2aq6YQGKGghMSfBXH6M3oX6AdHWD9nXrvGCqB
6aNBdeww1RbF7qOugUYxmZ6fqxVRwADrSP81Uz8rLBQVovieCjlXdeWvXt4CGyeu1AcdXYMnsdTt
vXHHAdAoqMTP+klPAM0MrsN+GRA=</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
<ds:Object>
<xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" Target="#xmldsig-089c463a-9afe-480d-9e39-4e7fe1eb00e7">
<xades:SignedProperties Id="xmldsig-089c463a-9afe-480d-9e39-4e7fe1eb00e7-signedprops">
<xades:SignedSignatureProperties>
<xades:SigningTime>2015-01-22T13:00:08.569+01:00</xades:SigningTime>
<xades:SigningCertificate>
<xades:Cert>
<xades:CertDigest>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>okFqGkp1+kY2NdB8m8cQTLROKq0=</ds:DigestValue>
</xades:CertDigest>
<xades:IssuerSerial>
<ds:X509IssuerName>CN=CPI CA for epuap TEST,OU=CPI CA for epuap TEST,O=CPI CA for epuap TEST,C=PL</ds:X509IssuerName>
<ds:X509SerialNumber>9642783885767916833</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>
</xades:SigningCertificate>
</xades:SignedSignatureProperties>
</xades:SignedProperties>
</xades:QualifyingProperties>
</ds:Object>
</ds:Signature>
</SOAP-ENV:Envelope>
Robię coś nie tak ale nie wiem niestety gdzie. Może ktoś przechodził już to wszystko i mógłby pomóc. Byłbym niezmiernie wdzięczny bo już powoli tracę nadzieje.