Avatar billede fredand Forsker
08. december 2004 - 20:55 Der er 1 løsning

How to send a mail with Java that uses S/Mime (2)?

Hello!

I have a assignment where I shall create a small app that sends a email signed and encrypted with S/MIME. But I do not manage to create the keys and certificates. I guess my code is correct, it is build with samples from:
http://www.wedgetail.com/jcsi/examples/JCSI-S-MIME-Example.html

To run it you need the jar files:
jcsi_base.jar
jcsi_jce.jar
jcsi_provider.jar
jcsi_smime.jar
...from that site

I'm pretty sure that I mess this up when I try to create the keys and certificates.

Below is my steps for creating the keys and certificates, I guess something is wrong there. After everything is my code, that uses this. So by follow theses steps you should be able to try this.


1 //Create keystore with sender_keypair
keytool -genkey -keyalg "RSA" -alias sender_keypair -keystore smime_keystore -keypass password -dname "cn=Fredrik_Andersson_Sender" -storepass password -storetype pkcs12

2 //Create a certificate request for the sender_keypair
keytool -certreq -alias sender_keypair -file sender_keypair_certrequest.csr -keypass password -storetype pkcs12 -keystore smime_keystore -storepass password

3 //Create the certificate from ca by upload this request at wwww.thawte.com
trials > free trail certificate ...

-----BEGIN NEW CERTIFICATE REQUEST-----
MIIBYTCBywIBADAjMSEwHwYDVQQDDBhGcmVkcmlrX0FuZGVyc3Nvbl9TZW5kZXIwgZ4wDQYJKoZI
hvcNAQEBBQADgYwAMIGIAoGAV2SKsV3Q+V6ykSVx63PpeHz0RoVXOv42HAHjDfO1yjMn7DS/oHkN
Xtte+1un0idCTL6zpQ0EKXAQNbLQOSptbUjKCJLblkBMfkRphBJja38GVfevSCxOE20pbnXGqyRI
F7ugPzNXxvN5lV2mQqWBgO90CJIdhOiHg+04WsvuUnMCAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GB
AET/U+0h1U+sbCwmsx1dyYXlr/N4i/e7sbHBHvCAj1FgnxQ/F7W9X43bGBWlpG6rca0Vs6lyF9C2
P4swxhiRMJxLUdz0coPrhtFzjUD8rWOYgBGaTKJCCVbMqOS4D40le6DzAoZsyRzxg7NT17t+QWFn
jiyNC+uLM2jz2j9DAoyI
-----END NEW CERTIFICATE REQUEST-----

For response I get the certificate, is that what they call the ca.certificate?

4 //Create the sender-certificate
keytool -export -keystore smime_keystore -storepass password -alias sender_keypair -file SenderCertificate.cer -storetype pkcs12

5 //Create the receiver_keypair (I will just test local so I store it in the same keystore)
keytool -genkey -keyalg "RSA" -alias receiver_keypair -keystore smime_keystore -keypass password -dname "cn=Fredrik_Andersson_Receiver" -storepass password -storetype pkcs12

6 //Create the receiver-certificate
keytool -export -keystore smime_keystore -storepass password -alias receiver_keypair -file ReceiverCertificate.cer -storetype pkcs12


And the questions....
1) Does this looks like the correct way of doing this or do I have to import the thing I got from thawte into my keystore? Cause when I tried that it said some IOexception like "DerInputStream.getLength(): lengthTag=109, too big"

2) Do I need to connect the sender-certificate with the ca-certificate in some way? Or is that what happens in point 3?


3) When i run my code below I get the following exception, but the exception never looks like it refers to my code. So what do you think is the error?

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
        at java.lang.CharacterDataLatin1.getType(CharacterDataLatin1.java:62)
        at java.lang.CharacterDataLatin1.isLetter(CharacterDataLatin1.java:91)
        at java.lang.Character.isLetter(Character.java:3427)
        at java.lang.Character.isLetter(Character.java:3391)
        at java.net.URL.isValidProtocol(URL.java:613)
        at java.net.URL.<init>(URL.java:529)
        at java.net.URL.<init>(URL.java:464)
        at java.net.URL.<init>(URL.java:413)
        at java.net.JarURLConnection.parseSpecs(JarURLConnection.java:160)
        at java.net.JarURLConnection.<init>(JarURLConnection.java:143)
        at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:61)
        at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
        at java.net.URL.openConnection(URL.java:943)
        at com.sun.crypto.provider.SunJCE_d.run(DashoA6275)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.crypto.provider.SunJCE_c.a(DashoA6275)
        at com.sun.crypto.provider.SunJCE_c.a(DashoA6275)
        at com.sun.crypto.provider.SunJCE_c.a(DashoA6275)
        at com.sun.crypto.provider.SunJCE.c(DashoA6275)
        at com.sun.crypto.provider.SunJCE.b(DashoA6275)
        at com.sun.crypto.provider.SunJCE.a(DashoA6275)
        at com.sun.crypto.provider.RSACipher.<init>(DashoA6275)
        at sun.reflect.GeneratedConstructorAccessor14.newInstance(Unknown Source
)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingC
onstructorAccessorImpl.java:27)
...bla bla bla


Any comments or ideas are most welcome and valueable!

Best reagards
Fredrik


Below is the code
--------------------------------------------------
package smime_encryption_and_signing;

import java.net.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.net.ssl.*;
import java.io.*;
import java.security.*;

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import java.security.cert.*;
import com.dstc.security.smime.*;

public class SendMailSMIMEApplication extends JFrame implements ActionListener
{
    JLabel mailserverjLabel = new JLabel("Mail-server");
    JLabel fromjLabel = new JLabel("From");
    JLabel tojLabel = new JLabel("To");
    JLabel subjectjLabel = new JLabel("Subject");
    JLabel messagejLabel = new JLabel("Message");

    JTextField mailserverjTextField = new JTextField("mail1.telia.com");
    JTextField fromjTextField = new JTextField("fredand44@hotmail.com");
    JTextField tojTextField = new JTextField("fredand44@hotmail.com");
    JTextField subjectjTextField = new JTextField("A subject");

    JTextArea messagejTextArea = new JTextArea("A message!");
    JScrollPane jScrollPane = new JScrollPane(messagejTextArea);

    JButton jButton = new JButton("Send");

    public SendMailSMIMEApplication()
    {
        setSize(400, 400);

        getContentPane().setLayout(null);

        setBackground(new Color(200, 200, 200));

        mailserverjLabel.setBounds(5, 5, 100, 25);
        fromjLabel.setBounds(5, 35, 100, 25);
        tojLabel.setBounds(5, 65, 100, 25);
        subjectjLabel.setBounds(5, 95, 100, 25);
        messagejLabel.setBounds(5, 125, 100, 25);
        jButton.setBounds(5, 155, 100, 25);

        mailserverjTextField.setBounds(110, 5, 280, 25);
        fromjTextField.setBounds(110, 35, 280, 25);
        tojTextField.setBounds(110, 65, 280, 25);
        subjectjTextField.setBounds(110, 95, 280, 25);
        jScrollPane.setBounds(110, 125, 280, 240);


        jButton.addActionListener(this);

        getContentPane().add(mailserverjLabel);
        getContentPane().add(fromjLabel);
        getContentPane().add(tojLabel);
        getContentPane().add(subjectjLabel);
        getContentPane().add(messagejLabel);
        getContentPane().add(jButton);

        getContentPane().add(mailserverjTextField);
        getContentPane().add(fromjTextField);
        getContentPane().add(tojTextField);
        getContentPane().add(subjectjTextField);
        getContentPane().add(jScrollPane);
    }

    public void actionPerformed(ActionEvent e)
    {
        String error = sendMail();
        if(!error.equals("No errors"))
        {
            messagejTextArea.setText(error);
        }
    }

    public String sendMail()
    {
        try
        {
            Security.insertProviderAt(new com.dstc.security.provider.DSTC(), 2);
            Security.addProvider(new com.dstc.security.keymanage.keystore.DSTC());

            Properties properties = new Properties();
            properties.put("mail.smtp.host", mailserverjTextField.getText());
            Session mailSession = Session.getDefaultInstance(properties, null);
            //session = Session.getDefaultInstance(System.getProperties(), null);

            // certs
            X509Certificate recipientCertificate = getCertificate("smime_encryption_and_signing/ReceiverCertificate.cer");
            X509Certificate senderCertificate = getCertificate("smime_encryption_and_signing/SenderCertificate.cer");
            X509Certificate caCertificate = getCertificate("smime_encryption_and_signing/thawte_certificate.cer");

            PrivateKey senderKey = getPrivateKey("smime_encryption_and_signing/smime_keystore", "sender_keypair", "password".toCharArray());

            InternetAddress fromAddress = new InternetAddress(fromjTextField.getText());

            MimeMessage mimeMessage = new MimeMessage(mailSession);
            mimeMessage.setFrom(fromAddress);

            InternetAddress internetAddress = new InternetAddress(tojTextField.getText());
            mimeMessage.setRecipient(Message.RecipientType.TO, internetAddress);

            mimeMessage.setSentDate(new java.util.Date());
            mimeMessage.setSubject(subjectjTextField.getText());
            mimeMessage.setText(messagejTextArea.getText());

            X509Certificate[] senderCertificates = {senderCertificate, caCertificate};
            mimeMessage = signMimeMessage(mimeMessage, senderKey, senderCertificates);

            X509Certificate[] recipientCertificates = { recipientCertificate };
            mimeMessage = encryptMimeMessage(mimeMessage, recipientCertificates);

            Transport.send(mimeMessage);

            System.out.println("Message sent");

            return "No errors";
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    public X509Certificate getCertificate(String certificateFile)
    {
        try
        {
            FileInputStream fileInputStream = new FileInputStream(certificateFile);
            DataInputStream dataInputStream = new DataInputStream(fileInputStream);
            byte[] certificateData = new byte[fileInputStream.available()];
            dataInputStream.readFully(certificateData);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(certificateData);
            CertificateFactory fact = CertificateFactory.getInstance("X509");
            X509Certificate certificate = (X509Certificate) fact.generateCertificate(byteArrayInputStream);
            return certificate;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

    public PrivateKey getPrivateKey(String keystoreFile, String alias, char[] password)
    {
        try
        {
            FileInputStream fileInputStream = new FileInputStream(keystoreFile);

            KeyStore keyStore = KeyStore.getInstance("pkcs12");

            keyStore.load(fileInputStream, password);

            return (PrivateKey) keyStore.getKey(alias, password);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

    public MimeMessage signMimeMessage(MimeMessage mimeMessage, PrivateKey privateKey, X509Certificate[] certificates)
    {
        try
        {
            SMIMESignature smimeSignature = new SMIMESignature();

            smimeSignature.initSign("SHA-1", privateKey, certificates, false);

            smimeSignature.setMessage(mimeMessage);

            return smimeSignature.sign();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    public MimeMessage encryptMimeMessage(MimeMessage mimeMessage, X509Certificate[] certificates)
    {
        try
        {
            SMIMECipher smimeCipher = new SMIMECipher();

            smimeCipher.initEncrypt(new SecureRandom(), "DESede", certificates);

            smimeCipher.setMessage(mimeMessage);

            return smimeCipher.encrypt();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args)
    {
        SendMailSMIMEApplication sendMailSMIMEApplication = new SendMailSMIMEApplication();
        sendMailSMIMEApplication.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        sendMailSMIMEApplication.setVisible(true);
    }
}
Avatar billede fredand Forsker
09. december 2004 - 23:03 #1
Hello!

The code seamed to be ok. But I had to download an newer version of the jarfiles from wedgtail because i'm runnin Java 1.5

Best regards
Fredrik
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester