JoaoDinisBate Posted July 1, 2025 at 12:34 PM Report #634997 Posted July 1, 2025 at 12:34 PM Boas, Estou a usar uma aplicação original das financas, em java, para a comunicação com a at. Esta aplicação usava um ficheiro saPubKey.jks e funcionava. Agora deixou de funcionar e o problema é que não sei como encaixar na aplicação e o que fazer com este certificado que nos mandaram (chave cifra publica at 2027.cer). Será que alguém me pode ajudar? Insiro abaixo o java SOAPClientMessageHeaderHandler que penso será onde tem de ser usado. Obrigado, JoãoDinis package pt.at.factemipf.core.webservices.proxy; import sun.misc.BASE64Encoder; import javax.xml.namespace.QName; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPFactory; import javax.xml.soap.SOAPHeader; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.security.Key; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimeZone; import java.util.logging.Logger; public class SOAPClientMessageHeaderHandler implements SOAPHandler<SOAPMessageContext> { public enum CERTIFICATE { PROD("P", "sapubkey.prod", "Producao"), TESTES("T", "sapubkey.testes", "Testes"); private final String key, keyAlias, descricao; private CERTIFICATE(String key, String keyAlias, String desc) { System.out.println("36SoapMsgHandler"); this.key = key; this.keyAlias = keyAlias; this.descricao = desc; } public String getKeyAlias() { return keyAlias; } public String getDescricao() { return descricao; } public static CERTIFICATE get(String mode) { for (CERTIFICATE certificate : CERTIFICATE.values()) { if (certificate.key.equals(mode)) return certificate; } throw new IllegalArgumentException("certificado inexistente nao validado."); } } private static final String AUTH_NS = "http://schemas.xmlsoap.org/ws/2002/12/secext"; private static final String AUTH_PREFIX = "wss"; private static final String KS_PATH = "saPubKey.jks"; private static final String KS_PWD = "saKeyPubPass"; //private static final String KEY_ALIAS = "sapubkey.testes"; private Logger logger; private String userName; private String password; private CERTIFICATE ambienteCert; public SOAPClientMessageHeaderHandler(Logger logger, String userName, String password, CERTIFICATE ambienteCert) { System.out.println("73SoapMsgHandler"); this.logger = logger; this.userName = userName; this.password = password; this.ambienteCert = ambienteCert; } public boolean handleFault(SOAPMessageContext smc) { return true; } public void close(MessageContext mc) { } /** * adiciona header para autenticacao */ public boolean handleMessage(SOAPMessageContext smc) { boolean direction = (Boolean) smc.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY); if (direction) { try { // ---------------------- // ---- AUTENTICACAO ---- // ---------------------- // Generate simetric key used for this request. Nonce! final byte[] simetricKey = generateAESKey(); // logger.info("Chave sim�trica gerada"); // Encrypt with the simetric key and B64 encode the password final byte[] encryptedPassword = WSAutenticaTestCypherUtil.cypherCredential(simetricKey, password); final String b64EncryptedPassword = new BASE64Encoder().encodeBuffer(encryptedPassword); // logger.info("Password field encrypted and encoded: " + b64EncryptedPassword); // Encrypt with the simetric key and B64 encode the timestamp final byte[] encryptedTimestamp = WSAutenticaTestCypherUtil.cypherCredential(simetricKey, getTimestamp()); final String b64EncryptedTimestamp = new BASE64Encoder().encodeBuffer(encryptedTimestamp); // logger.info("timestamp encrypted and encoded: " + b64EncryptedTimestamp); // Encrypt with the SA public key and B64 encode the request simetric key (nonce) final Key publicKey = WSAutenticaTestCypherUtil.getPublicKeyFromKeystore(KS_PATH, KS_PWD, ambienteCert.getKeyAlias()); final byte[] encriptedSimetricKey = WSAutenticaTestCypherUtil.cypherRequestKey((PublicKey) publicKey, simetricKey); final String b64EncryptedSimetricKey = new BASE64Encoder().encodeBuffer(encriptedSimetricKey); // logger.info("Request simetric key encrypted and encoded:\n" + b64EncryptedSimetricKey); // ---------------------- SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope(); SOAPFactory soapFactory = SOAPFactory.newInstance(); // WSSecurity <Security> header SOAPElement wsSecHeaderElm = soapFactory.createElement( "Security", AUTH_PREFIX, AUTH_NS); SOAPElement userNameTokenElm = soapFactory.createElement("UsernameToken", AUTH_PREFIX, AUTH_NS); // Username SOAPElement userNameElm = soapFactory.createElement("Username", AUTH_PREFIX, AUTH_NS); userNameElm.addTextNode(userName); // Password SOAPElement passwdElm = soapFactory.createElement("Password", AUTH_PREFIX, AUTH_NS); passwdElm.addTextNode(b64EncryptedPassword); //Nonce SOAPElement nonceElm = soapFactory.createElement("Nonce", AUTH_PREFIX, AUTH_NS); nonceElm.addTextNode(b64EncryptedSimetricKey); //Created SOAPElement createdElm = soapFactory.createElement("Created", AUTH_PREFIX, AUTH_NS); createdElm.addTextNode(b64EncryptedTimestamp); userNameTokenElm.addChildElement(userNameElm); userNameTokenElm.addChildElement(passwdElm); userNameTokenElm.addChildElement(nonceElm); userNameTokenElm.addChildElement(createdElm); // add child elements to the root element wsSecHeaderElm.addChildElement(userNameTokenElm); // create SOAPHeader instance for SOAP envelope //SOAPHeader sh = envelope.addHeader(); SOAPHeader sh = envelope.getHeader(); // add SOAP element for header to SOAP header object sh.addChildElement(wsSecHeaderElm); } catch (Exception ex) { StringWriter sw = new StringWriter(); ex.printStackTrace(new PrintWriter(sw)); String stacktrace = sw.toString(); logger.severe("Could not intercept and add WS Security Header\n\n" + stacktrace); } } return true; } private byte[] buildPasswordDigest(byte[] simetricKey, String timestamp, String password) throws UnsupportedEncodingException, NoSuchAlgorithmException { byte[] bytesNonce = simetricKey; byte[] bytesCreated = timestamp.getBytes("UTF-8"); byte[] bytesPassword = password.getBytes("UTF-8"); byte[] digestInput = new byte[bytesNonce.length + bytesCreated.length + bytesPassword.length]; System.arraycopy(bytesNonce, 0, digestInput, 0, bytesNonce.length); System.arraycopy(bytesCreated, 0, digestInput, bytesNonce.length, bytesCreated.length); System.arraycopy(bytesPassword, 0, digestInput, bytesNonce.length + bytesCreated.length, bytesPassword.length); MessageDigest md = MessageDigest.getInstance("SHA-1"); return md.digest(digestInput); } public java.util.Set<QName> getHeaders() { return null; } // --------------- // Utility Methods // --------------- private static byte[] generateAESKey() throws NoSuchAlgorithmException { return WSAutenticaTestCypherUtil.generateRequestKey(); } private static final SimpleDateFormat TIMESTAMP_FORMATER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'"); static { TIMESTAMP_FORMATER.setTimeZone(TimeZone.getTimeZone("UTC")); } private static String getTimestamp() throws ParseException { Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC")); return TIMESTAMP_FORMATER.format(c.getTime()); } }
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now