From 9f2bef75b354f36cca86e3945e4762cde77223ab Mon Sep 17 00:00:00 2001 From: rogerio.costa Date: Sat, 30 Apr 2016 15:09:36 -0300 Subject: [PATCH] #4583 - Assinar documento digital --- cit-ecm-api/src/main/java/br/com/centralit/api/service/AssinaturaUtilService.java | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cit-ecm-api/src/main/java/br/com/centralit/api/service/impl/AssinaturaServiceImpl.java | 71 ++++++++++++++++++++++++++++++++++++++++++----------------------------- cit-ecm-api/src/main/java/br/com/centralit/api/service/impl/AssinaturaUtilServiceImpl.java | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cit-ecm-api/src/main/resources/keys/private_key.der | Bin 0 -> 1217 bytes cit-ecm-api/src/main/resources/keys/private_key.pem | 27 +++++++++++++++++++++++++++ cit-ecm-api/src/main/resources/keys/public_key.der | Bin 0 -> 294 bytes 6 files changed, 349 insertions(+), 29 deletions(-) create mode 100644 cit-ecm-api/src/main/java/br/com/centralit/api/service/AssinaturaUtilService.java create mode 100644 cit-ecm-api/src/main/java/br/com/centralit/api/service/impl/AssinaturaUtilServiceImpl.java create mode 100644 cit-ecm-api/src/main/resources/keys/private_key.der create mode 100644 cit-ecm-api/src/main/resources/keys/private_key.pem create mode 100644 cit-ecm-api/src/main/resources/keys/public_key.der diff --git a/cit-ecm-api/src/main/java/br/com/centralit/api/service/AssinaturaUtilService.java b/cit-ecm-api/src/main/java/br/com/centralit/api/service/AssinaturaUtilService.java new file mode 100644 index 0000000..310eb9b --- /dev/null +++ b/cit-ecm-api/src/main/java/br/com/centralit/api/service/AssinaturaUtilService.java @@ -0,0 +1,56 @@ +package br.com.centralit.api.service; + +/** + *

+ * + *

+ * + *

+ * Company: Central IT - Governança Corporativa - + *

+ * + *

+ * Title: + *

+ * + *

+ * Description: + *

+ * + *

+ * Iniciativa(s): NUMERO_INICIATIVA + *

+ * + *

+ * Regra(s) de negócio: NUMERO_REGRA_DE_NEGOCIO + *

+ * + * @since 30/04/2016 - 13:47:33 + * + * @version 1.0.0 + * + * @author rogerio.costa + * + */ +public interface AssinaturaUtilService { + + /** + *

+ * Iniciativa(s): NUMERO_INICIATIVA + *

+ * + *

+ * Regra(s) de negócio: NUMERO_REGRA_DE_NEGOCIO + *

+ * + * Método responsável por assinar o documento + * + * @author rogerio.costa + * + * @param mensagem + * @return byte[] + * @throws Exception + */ + byte[] geraAssinatura(byte[] conteudo) throws Exception; + +} diff --git a/cit-ecm-api/src/main/java/br/com/centralit/api/service/impl/AssinaturaServiceImpl.java b/cit-ecm-api/src/main/java/br/com/centralit/api/service/impl/AssinaturaServiceImpl.java index 542ca2f..2da795d 100644 --- a/cit-ecm-api/src/main/java/br/com/centralit/api/service/impl/AssinaturaServiceImpl.java +++ b/cit-ecm-api/src/main/java/br/com/centralit/api/service/impl/AssinaturaServiceImpl.java @@ -24,76 +24,84 @@ import br.com.centralit.framework.service.arquitetura.GenericServiceImpl; import br.com.centralit.framework.util.UtilObjeto; import br.com.centralit.framework.util.UtilString; - /** - *

Title:

- *

Description:

+ *

+ * Title: + *

+ *

+ * Description: + *

* * @since 22/04/2016 - 11:50:56 * @author rogerio.cassimiro - * + * */ @Service("assinaturaService") public class AssinaturaServiceImpl extends GenericServiceImpl implements AssinaturaService { @Autowired private AssinaturaDao assinaturaDao; - + @Autowired private DocumentoGedService documentoGedService; - + @Autowired private UsuarioService usuarioService; - + @Autowired private DominioService dominioService; - + @Autowired private FuncaoService funcaoService; - + @Autowired private PessoaService pessoaService; - + @Autowired private HistoricoAlteracaoProcessoService historicoAlteracaoProcessoService; - + @Autowired private TarjaAssinaturaService tarjaAssinaturaService; - + @Value("${metodo.autenticacao.ldap}") private String ldap; - + @Autowired - public AssinaturaServiceImpl( AssinaturaDao assinaturaDao) { + public AssinaturaServiceImpl( AssinaturaDao assinaturaDao ) { + this.dao = assinaturaDao; } - + /** * Salva assinatura do documento e gera histórico */ @Override public Assinatura saveAssinaturaInterna(Assinatura assinatura) { + Usuario usuario = (Usuario) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); validarSenha(assinatura.getPassword(), usuario); montarTransients(assinatura, usuario); historicoAlteracaoProcessoService.gerarHistoricoAssinatura(assinatura); - tarjaAssinaturaService.gerarAssinaturaInternaUsuario(assinatura,assinatura.getDocumentoGed().getFormaCriacao().getCodigo()); + tarjaAssinaturaService.gerarAssinaturaInternaUsuario(assinatura, assinatura.getDocumentoGed().getFormaCriacao().getCodigo()); alterarEstadoDocumento(assinatura.getDocumentoGed()); return super.save(assinatura); } /** * Método responsável por alterar estado do documento se a forma for online + * * @author rogerio.cassimiro * @param documentoGed */ private void alterarEstadoDocumento(DocumentoGed documentoGed) { - if(documentoGed.getFormaCriacao().getCodigo().equals(1L) && !documentoGed.getEstado().getCodigo().equals(2L)) - documentoGed.setEstado(dominioService.findByChaveAndCodigo("estadoDocumentoGed", 2L)); + + if (documentoGed.getFormaCriacao().getCodigo().equals(1L) && !documentoGed.getEstado().getCodigo().equals(2L)) + documentoGed.setEstado(dominioService.findByChaveAndCodigo("estadoDocumentoGed", 2L)); } /** * Método responsável por montar transients da assinatura + * * @author rogerio.cassimiro * @param assinatura * @param usuario @@ -106,45 +114,50 @@ public class AssinaturaServiceImpl extends GenericServiceImpl assinatura.setTipoAssinatura(dominioService.findByChaveAndCodigo(Dominio.TIPO_ASSINATURA, Dominio.TIPO_ASSINATURA_INTERNA)); assinatura.setFuncao(funcaoService.getReference(assinatura.getFuncao().getId())); } - + /** * Método responsável por validar senha para assinar o documento + * * @author rogerio.cassimiro * @param password * @param usuario */ private void validarSenha(String password, Usuario usuario) { - - if(!UtilString.isNullOrEmpty(ldap) && ldap.equals("false")) { - if(UtilString.isNullOrEmpty(password)) + if (!UtilString.isNullOrEmpty(ldap) && ldap.equals("false")) { + + if (UtilString.isNullOrEmpty(password)) throw new BusinessException("ECM.VALIDACAO.SENHA_ASSINATURA", CodigoErro.REGRA_NEGOCIO.getValue(), ""); - - if(!UtilObjeto.isReferencia(this.usuarioService.loadUserByUsernamePasswordMobile(usuario.getUsername(), password))) + + if (!UtilObjeto.isReferencia(this.usuarioService.loadUserByUsernamePasswordMobile(usuario.getUsername(), password))) throw new BusinessException("ECM.VALIDACAO.SENHA_ASSINATURA_INVALIDA", CodigoErro.REGRA_NEGOCIO.getValue(), ""); - + } else { - //TODO LDAP validação + // TODO LDAP validação } } - + /** * Método responsável por validar se o usuário já teve assinatura anterior para o documento informado + * * @author rogerio.cassimiro * @return {@link Boolean} */ @Override public Boolean validarAssinaturaPorUsuario(Long idDocumento) { - return this.assinaturaDao.validarAssinaturaPorUsuario(idDocumento, ((Usuario) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId()); + + return this.assinaturaDao.validarAssinaturaPorUsuario(idDocumento, ( (Usuario) SecurityContextHolder.getContext().getAuthentication().getPrincipal() ).getId()); } @Override public Assinatura getReference(Long id) { + Assinatura assinatura = (Assinatura) this.assinaturaDao.getReference(id); assinatura.getConteudoTarja().setConteudo(tarjaAssinaturaService.decrypted(assinatura.getConteudoTarja().getConteudoCriptografado())); - if(UtilObjeto.isReferencia(assinatura.getDocumentoGed().getConteudoTarja())){ + if (UtilObjeto.isReferencia(assinatura.getDocumentoGed().getConteudoTarja())) { assinatura.getDocumentoGed().getConteudoTarja().setConteudo(tarjaAssinaturaService.decrypted(assinatura.getDocumentoGed().getConteudoTarja().getConteudoCriptografado())); } return assinatura; } + } diff --git a/cit-ecm-api/src/main/java/br/com/centralit/api/service/impl/AssinaturaUtilServiceImpl.java b/cit-ecm-api/src/main/java/br/com/centralit/api/service/impl/AssinaturaUtilServiceImpl.java new file mode 100644 index 0000000..8dd30e6 --- /dev/null +++ b/cit-ecm-api/src/main/java/br/com/centralit/api/service/impl/AssinaturaUtilServiceImpl.java @@ -0,0 +1,224 @@ +package br.com.centralit.api.service.impl; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import br.com.centralit.api.service.AssinaturaUtilService; + +/** + *

+ * + *

+ * + *

+ * Company: Central IT - Governança Corporativa - + *

+ * + *

+ * Title: AssinaturaUtilServiceImpl + *

+ * + *

+ * Description: Classe responsável por assinar e validar autenticidade do documento. + *

+ * + *

+ * Iniciativa(s): NUMERO_INICIATIVA + *

+ * + *

+ * Regra(s) de negócio: NUMERO_REGRA_DE_NEGOCIO + *

+ * + * @since 30/04/2016 - 13:47:59 + * + * @version 1.0.0 + * + * @author rogerio.costa + * + */ +@Service("assinaturaUtilService") +public class AssinaturaUtilServiceImpl implements AssinaturaUtilService { + + /** Atributo publicKeyFile. */ + @Value("${ecm.signature.publicKeyFile}") + private File publicKeyFile; + + /** Atributo privateKeyFile. */ + @Value("${ecm.signature.privateKeyFile}") + private File privateKeyFile; + + /** + *

+ * Iniciativa(s): NUMERO_INICIATIVA + *

+ * + *

+ * Regra(s) de negócio: NUMERO_REGRA_DE_NEGOCIO + *

+ * + * Método responsável por assinar o documento + * + * @author rogerio.costa + * + * @param mensagem + * @return byte[] + * @throws InvalidKeyException + * @throws Exception + */ + public byte[] geraAssinatura(byte[] conteudo) throws Exception { + + Signature sig = Signature.getInstance("SHA1withRSA"); + + // Inicializando Obj Signature com a Chave Privada + sig.initSign(this.getPrivateKey()); + + // Gerar assinatura + sig.update(this.gerarHash(conteudo)); + + byte[] assinatura = sig.sign(); + + return assinatura; + } + + /** + *

+ * Iniciativa(s): NUMERO_INICIATIVA + *

+ * + *

+ * Regra(s) de negócio: NUMERO_REGRA_DE_NEGOCIO + *

+ * + * Método responsável por + * + * @author rogerio.costa + * + * @param conteudo + * @param assinatura + * @throws Exception + */ + public Boolean validarAutenticidade(byte[] conteudo, byte[] assinatura) throws Exception { + + Signature clientSig = Signature.getInstance("SHA1withRSA"); + + clientSig.initVerify(getPublicKey()); + + clientSig.update(this.gerarHash(conteudo)); + + return clientSig.verify(assinatura); + + } + + /** + *

+ * Iniciativa(s): NUMERO_INICIATIVA + *

+ * + *

+ * Regra(s) de negócio: NUMERO_REGRA_DE_NEGOCIO + *

+ * + * Método responsável por obter a chave privada + * + * @author rogerio.costa + * + * @return PrivateKey + * + * @throws Exception + */ + public PrivateKey getPrivateKey() throws Exception { + + FileInputStream fis = new FileInputStream(this.privateKeyFile); + + DataInputStream dataInputStream = new DataInputStream(fis); + + byte[] keyBytes = new byte[(int) this.privateKeyFile.length()]; + + dataInputStream.readFully(keyBytes); + + dataInputStream.close(); + + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); + + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + + return keyFactory.generatePrivate(spec); + + } + + /** + *

+ * Iniciativa(s): NUMERO_INICIATIVA + *

+ * + *

+ * Regra(s) de negócio: NUMERO_REGRA_DE_NEGOCIO + *

+ * + * Método responsável por obter a chace pública + * + * @author rogerio.costa + * + * @return + * @throws Exception + */ + public PublicKey getPublicKey() throws Exception { + + FileInputStream fis = new FileInputStream(this.publicKeyFile); + + DataInputStream dataInputStream = new DataInputStream(fis); + + byte[] keyBytes = new byte[(int) this.publicKeyFile.length()]; + + dataInputStream.readFully(keyBytes); + + dataInputStream.close(); + + X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); + + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + + return keyFactory.generatePublic(spec); + } + + /** + *

+ * Iniciativa(s): NUMERO_INICIATIVA + *

+ * + *

+ * Regra(s) de negócio: NUMERO_REGRA_DE_NEGOCIO + *

+ * + * Método responsável por gerar o hash do documento + * + * @author rogerio.costa + * + * @param doc + * @return + * @throws NoSuchAlgorithmException + */ + public byte[] gerarHash(byte[] doc) throws NoSuchAlgorithmException { + + MessageDigest md = MessageDigest.getInstance("MD5"); + + md.update(doc); + + return md.digest(); + } + +} diff --git a/cit-ecm-api/src/main/resources/keys/private_key.der b/cit-ecm-api/src/main/resources/keys/private_key.der new file mode 100644 index 0000000..9545e63 Binary files /dev/null and b/cit-ecm-api/src/main/resources/keys/private_key.der differ diff --git a/cit-ecm-api/src/main/resources/keys/private_key.pem b/cit-ecm-api/src/main/resources/keys/private_key.pem new file mode 100644 index 0000000..bdba1c5 --- /dev/null +++ b/cit-ecm-api/src/main/resources/keys/private_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAuz6F91j0K2cogHAWhvTON6TKqHwxn97zA4U2TrjuczwQxAnz +Z/EzxbNKwxpMktuoVMTRYrqRAPWEK4mEMC4yQnH0O5NmwVtqf1/URd3CuNwszWRC +EXY1H1e4K26aLFQHaudBkVxkAPdzozX1guJWrG7y6pKn2RNt17h0DLJGvf21RFKl +7M06UewXartSF0VtxiOXA5RktmNh/E7zwaY/y7CBEoiYR/Vhg+xv1a9x1TwslbR5 +/KpVDiarLXJ4ssU0Zx/dT7l9wdx8wNox2SpkrC6jHyum8v++3vV1qMIbQ91nkyaD +qQ4QRhGxd35iqSIolbkP3eq63zX8kHw/RxwP6wIDAQABAoIBAHkIDxw1GY88nQd4 +bHdLokiBcqW5sXH/cOGjp9j23NsLxmKRdA6J8Mcn/3lhdIGxDnvMxPOmWLhf+tER +kKp8Eey1MAOaYd82Mf6neNS4ZXeMikExPyt+VxQtZVRdp7Zjkm/dj5pgOBwP12V2 +KX4yw4euJ8LMjUZZsrSv/AOA8Q045tVpcN7u53gMJ6PmmSA1CGYM0UXBZ7tuLzIj +YiSwSL6ANtAYjbRy5ZZlYDAWUg7c+XG1+i85AsCiblJUQFvGje1eqPzgK+qAB/TO +AfJLYCZewOL8ZA3cY8zPZHl1qA48Pj6pJxYx+FwutILO7ufxzJBnI1BT4yt1QYAT +4ckes/ECgYEA89PuCxHAC32AgTBSwxRKedOQQuqv55idNluEbKn13wnHni5gBl2u +d4z1qzUVjLaWUzLiybijmdsW0sjsCDOd3QlBFdg3R2x5qJbI2FLv2PDNuQCohqRr +N0pwscBpJCgboI+nADdxTu3RJZplIro6jbrhneV0HkWA1T7KTkY/XtUCgYEAxJd3 +YqPXte/SertCUs4Nq8L45+jF2mGaWpHAlDfDcQVYcnA7ALdgwRS9H/2v0ZTC1Iwf +GhkmIbGGnJKt5aYpqeR1stzMBL1HvZgaCQQAu/59BQl2VSWRlSVUWhMk8uD91NKm +Hl63DTvUrxkieSsswnj371U7BGbMLBXMkYDgk78CgYBMnoIk9FT2x19EOV0odA3b +LoIcpQbVrf1pAWUhiF780WPq7wO5vGKAqsjgHfRBnXarekgNv3mZdWE8p2qUQTQQ +K0JKjQEB7rJkKc2/PICmGTVsNyq99JjEbR3wnVfsxrW3xKxjwwhWFyErwdKaEQ8p +TlprdZkBkjGj0PFdm3F6aQKBgQCgrFaztMspdI+nJYMoYCZGOnzqNZH3UQwxd6xY +t1ax+bd3GIjwpe+a/tMv4UwgU6AEzVziHKnQoeIt96fO6MZmh0U24USRnw2SRE0L +D012WKFfS4N+Rc09g5v0Xm81XnO2zE9exPSBCWRjk3xcYdAcRXgGELfCei3m3g4q +4ZUqywKBgCk/PdKa3xNQRYX5V29Jlgn+NiJgcgKPmW56QFT55H6AOaJM4h0Q6P5F +UVV6se5HRIne+5rf2Lh1nyldW4qp9Ujeo7Ku8uqivgqXxTsb/BdNvhSU9xR8G/0w +8HgFEMKqZ1njJhLUTa4547bSwf3VAwmoWcsaEl/b5dyGN/f4lBxP +-----END RSA PRIVATE KEY----- diff --git a/cit-ecm-api/src/main/resources/keys/public_key.der b/cit-ecm-api/src/main/resources/keys/public_key.der new file mode 100644 index 0000000..b09ff34 Binary files /dev/null and b/cit-ecm-api/src/main/resources/keys/public_key.der differ -- libgit2 0.21.2