hi ivyteam,
i've tried with the third party library is *bouncycastle* and *java.mails* , it's seem to work and i post implementation here
Function to encrypt message:
public MimeMessage encrypt(MimeMessage clearMessage, Session session) {
MimeMessage encryptedMessage = null;
try {
MailcapCommandMap mailcap = (MailcapCommandMap) CommandMap
.getDefaultCommandMap();
mailcap.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature");
mailcap.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");
mailcap.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature");
mailcap.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");
mailcap.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");
CommandMap.setDefaultCommandMap(mailcap);
/* Add BC */
Security.addProvider(new BouncyCastleProvider());
/* Open the keystore */
KeyStore keystore = KeyStore.getInstance("PKCS12", "BC");
keystore.load(new FileInputStream(pathP12File),
p12FilePassword.toCharArray());
// get key alias
Enumeration e = keystore.aliases();
String keyAlias = null;
//
while (e.hasMoreElements()) {
String alias = (String) e.nextElement();
if (keystore.isKeyEntry(alias)) {
keyAlias = alias;
}
}
if (keyAlias == null) {
Ivy.log().error("can't find a private key!");
return null;
}
// end getting key
Certificate[] chain = keystore.getCertificateChain(keyAlias);
/* Create the encrypter */
SMIMEEnvelopedGenerator encrypter = new SMIMEEnvelopedGenerator();
encrypter
.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(
(X509Certificate) chain[0]).setProvider("BC"));
/* Encrypt the message */
MimeBodyPart encryptedPart = encrypter.generate(clearMessage,
new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC)
.setProvider("BC").build());
/*
* Create a new MimeMessage that contains the encrypted and signed
* content
*/
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
encryptedPart.writeTo(out);
} catch (IOException e1) {
Ivy.log().error("EncryptMEssage: " + e1.getMessage(), e1);
}
encryptedMessage = new MimeMessage(session,
new ByteArrayInputStream(out.toByteArray()));
/* Set all original MIME headers in the encrypted message */
Enumeration headers = clearMessage.getAllHeaderLines();
while (headers.hasMoreElements()) {
String headerLine = (String) headers.nextElement();
if (!Strings.toLowerCase(headerLine).startsWith("content-")) {
encryptedMessage.addHeaderLine(headerLine);
}
}
} catch (SMIMEException | MessagingException | CMSException
| IllegalArgumentException | KeyStoreException
| NoSuchAlgorithmException | CertificateException | IOException
| NoSuchProviderException ex) {
Ivy.log().error("encrypt method:" + ex.getMessage());
}
return encryptedMessage;
}
And Sendmail method:
SignMessageService signMessageService = new SignMessageService();
EncryptMessageService encryptMessageService = new EncryptMessageService();
MimeMessage signedMessage = signMessageService.sign(clearMessage,
session);
MimeMessage encryptedMessage = encryptMessageService.encrypt(
signedMessage, session);
Ivy.log().info("send mail");
Transport.send(encryptedMessage);
Ivy.log().info("DONE");
You can get the full sourcecode from this [link][1] [Here][2] (follow the ReadMe.txt to import project) . In that project i I implement demo flow with using normal process as well using Signal (experiment)
But i get one exception when encrypt mail with ivy
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type application/pkcs7-mime; name="smime.p7m"; smime-type=enveloped-data
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:896)
at javax.activation.DataHandler.writeTo(DataHandler.java:317)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1627)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:961)
at SMimeSecurity.EncryptMessageService.encrypt(EncryptMessageService.java:112)
at SMimeSecurity.MailSendingService.sendEmail(MailSendingService.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at ch.ivyteam.ivy.scripting.internal.types.IvyJavaMethod.invokeImpl(IvyJavaMethod.java:73)
at ch.ivyteam.ivy.scripting.types.impl.IvyMethod.invoke(IvyMethod.java:83)
at ch.ivyteam.ivy.scripting.internal.language.IvyScriptEnginePerformer.visitControlInstructionInvoke(IvyScriptEnginePerformer.java:639)
at ch.ivyteam.ivy.scripting.internal.language.ControlInstructionInvoke.acceptControlInstructionVisitor(ControlInstructionInvoke.java:98)
at ch.ivyteam.ivy.scripting.internal.language.ControlInstruction.acceptInstructionVisitor(ControlInstruction.java:55)
at ch.ivyteam.ivy.scripting.internal.language.IvyScriptEnginePerformer.execute(IvyScriptEnginePerformer.java:170)
at ch.ivyteam.ivy.scripting.internal.language.IvyScriptEnginePerformer.execute(IvyScriptEnginePerformer.java:126)
at ch.ivyteam.ivy.scripting.internal.language.IvyScriptEngine.executeInternal(IvyScriptEngine.java:310)
at ch.ivyteam.ivy.scripting.internal.language.IvyScriptEngine.execute(IvyScriptEngine.java:279)
at ch.ivyteam.ivy.bpm.exec.restricted.scripting.IvyScriptExecutor$1.call(IvyScriptExecutor.java:222)
at ch.ivyteam.ivy.security.internal.SecurityContext.executeAs(SecurityContext.java:1563)
at ch.ivyteam.ivy.bpm.exec.restricted.scripting.IvyScriptExecutor.executeSecurely(IvyScriptExecutor.java:239)
at ch.ivyteam.ivy.bpm.exec.restricted.scripting.IvyScriptExecutor.executeInstruction(IvyScriptExecutor.java:226)
at ch.ivyteam.ivy.bpm.exec.restricted.scripting.IvyScriptExecutor.execute(IvyScriptExecutor.java:194)
at ch.ivyteam.ivy.bpm.exec.internal.activity.script.ScriptExecutor.execute(ScriptExecutor.java:31)
at ch.ivyteam.ivy.bpm.exec.internal.activity.script.ScriptExecutor.execute(ScriptExecutor.java:1)
at ch.ivyteam.ivy.bpm.engine.internal.model.bpmn.SimpleActivityExecutorAdapter.execute(SimpleActivityExecutorAdapter.java:36)
at ch.ivyteam.ivy.bpm.engine.internal.model.ProcessElement.lambda$0(ProcessElement.java:215)
at ch.ivyteam.ivy.bpm.engine.internal.model.ProcessElement.executeInElementContext(ProcessElement.java:286)
at ch.ivyteam.ivy.bpm.engine.internal.model.ProcessElement.execute(ProcessElement.java:215)
at ch.ivyteam.ivy.bpm.engine.internal.core.ProcessElementExecution.execute(ProcessElementExecution.java:37)
at ch.ivyteam.ivy.bpm.engine.internal.core.RequestProcessor.handleExecution(RequestProcessor.java:140)
at ch.ivyteam.ivy.bpm.engine.internal.core.RequestProcessor.processRequest(RequestProcessor.java:130)
at ch.ivyteam.ivy.bpm.engine.internal.core.RequestProcessor.handleRequest(RequestProcessor.java:95)
at ch.ivyteam.ivy.bpm.engine.internal.core.RequestProcessor.handleRequest(RequestProcessor.java:77)
at ch.ivyteam.ivy.bpm.engine.internal.BpmEngine.handleNormalRequest(BpmEngine.java:190)
at ch.ivyteam.ivy.bpm.engine.internal.BpmEngine.handleRequestWithinContext(BpmEngine.java:140)
at ch.ivyteam.ivy.request.impl.ContextAwareRequestHandler.handleRequest(ContextAwareRequestHandler.java:32)
at ch.ivyteam.ivy.system.task.internal.SystemTaskJob.executeProcess(SystemTaskJob.java:127)
at ch.ivyteam.ivy.system.task.internal.SystemTaskJob.executeAsSystem(SystemTaskJob.java:92)
at ch.ivyteam.ivy.system.task.internal.SystemTaskJob$1.call(SystemTaskJob.java:56)
at ch.ivyteam.ivy.security.internal.SecurityManager.executeAsSystem(SecurityManager.java:1467)
at ch.ivyteam.ivy.system.task.internal.SystemTaskJob.execute(SystemTaskJob.java:52)
at ch.ivyteam.ivy.job.internal.JobManager$1.call(JobManager.java:381)
at ch.ivyteam.ivy.job.internal.JobManager$1.call(JobManager.java:1)
at ch.ivyteam.util.callable.ExecutionContextContainer$ContainerExecutionContext.call(ExecutionContextContainer.java:92)
at ch.ivyteam.ivy.security.internal.SecurityManager.executeInContext_aroundBody0(SecurityManager.java:1519)
at ch.ivyteam.ivy.security.internal.SecurityManager.executeInContext_aroundBody1$advice(SecurityManager.java:41)
at ch.ivyteam.ivy.security.internal.SecurityManager.executeInContext(SecurityManager.java:1)
at ch.ivyteam.util.callable.ExecutionContextContainer$ContainerExecutionContext.call(ExecutionContextContainer.java:88)
at ch.ivyteam.util.callable.ExecutionContextContainer.executeInContext(ExecutionContextContainer.java:27)
at ch.ivyteam.ivy.job.internal.JobManager.execute(JobManager.java:375)
at ch.ivyteam.ivy.job.internal.Job.run(Job.java:56)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Somehow Ivy can not load class for relevant DCH of *bouncycastle* library, even i already added its jars to project then make order on top, including: *bcmail-jdk15on-155.jar, bcpkix-jdk15on-155.jar, bcprov-jdk15on-155.jar*
For temporary solution, i have to put those three libs of *bouncycastle* (you can find it on Webcontent/WEB-INF/lib of above project) to *AxonIvyDesigner6.4.0.52683\jre\lib\ext* then it will work for both case (normal process & signal).
If i just put those libs on *AxonIvyDesigner6.4.0.52683\webapps\ivy\WEB-INF\lib* it will throw the same exception when i test with signal, normal process it work fine
Does anyone of you recommend me some hints ?
Thanks in advance
=========Update 23.11.2016:
After fixing this exeption. [Here][2] is final version that we can use to send encrypted email in ivy:
[1]: https://drive.google.com/file/d/0B6qldkZvvHgHQjNvS3NwRjdJZDQ/view?usp=sharing
[2]: https://drive.google.com/file/d/0B6qldkZvvHgHb3M4RDNwZFE5YkU/view?usp=sharing