Jump to content

Recommended Posts

Posted

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());
    }
}

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.