Results 1 to 3 of 3

Thread: Exporting private key from keystore for use with Postfix/Apache

  1. #1
    riogd is offline Senior Member
    Join Date
    Apr 2006
    Posts
    50
    Rep Power
    9

    Default Exporting private key from keystore for use with Postfix/Apache

    As cited elsewhere it is a rather big hassle to setup commercial ssl certificates within Zimbra for Tomcat, Postfix etc... This is definitely an area that could use some improvement!

    A rather large problem we encountered is that when generating the CSR to get our certificate, the keystore (jks keystore) does not output the .key or provide any facility for obtaining the .key.
    So in the end we ended up with a .pem/.crt with no way of using it with Postfix/Apache, both of which need a .key + .pem/.crt pair.
    The primary reason for this forum post is that the wiki doesn't allow file uploads other than images and I wanted to make sure there was a version of the java program necessary to do this somewhere within the wiki or forums, to reference to, in the event that the original site/location is moved or removed and it consequently becomes difficult to find.

    The following instructions are from this page, which originally got them from here.
    Here is a summary of the steps needed to export a private key from a jks keystore
    Download ExportPrivateKey.zip from the attachments of this post or the original location.
    Invoke:
    Code:
    java -jar ExportPrivateKey.zip {keystore_path} JKS {keystore_password} {alias} {target_file}
    This would export the key to PKCS #8 PEM format. Now run openssl to convert it to the format apache modssl expects the file in
    Code:
    openssl pkcs8 -inform PEM -nocrypt -in exported-pkcs8.key -out exported.key
    The java code for exporting the private key in PKCS #8 format (already compiled and packaged within the .zip file, ready to run)
    Code:
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileWriter;
    import java.security.Key;
    import java.security.KeyPair;
    import java.security.KeyStore;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.UnrecoverableKeyException;
    import java.security.cert.Certificate;
    
    import sun.misc.BASE64Encoder;
    
    public class ExportPrivateKey {
            private File keystoreFile;
            private String keyStoreType;
            private char[] password;
            private String alias;
            private File exportedFile;
    
            public static KeyPair getPrivateKey(KeyStore keystore, String alias, char[] password) {
                    try {
                            Key key=keystore.getKey(alias,password);
                            if(key instanceof PrivateKey) {
                                    Certificate cert=keystore.getCertificate(alias);
                                    PublicKey publicKey=cert.getPublicKey();
                                    return new KeyPair(publicKey,(PrivateKey)key);
                            }
                    } catch (UnrecoverableKeyException e) {
            } catch (NoSuchAlgorithmException e) {
            } catch (KeyStoreException e) {
            }
            return null;
            }
    
            public void export() throws Exception{
                    KeyStore keystore=KeyStore.getInstance(keyStoreType);
                    BASE64Encoder encoder=new BASE64Encoder();
                    keystore.load(new FileInputStream(keystoreFile),password);
                    KeyPair keyPair=getPrivateKey(keystore,alias,password);
                    PrivateKey privateKey=keyPair.getPrivate();
                    String encoded=encoder.encode(privateKey.getEncoded());
                    FileWriter fw=new FileWriter(exportedFile);
                    fw.write(“—–BEGIN PRIVATE KEY—–\n“);
                    fw.write(encoded);
                    fw.write(“\n“);
                    fw.write(“—–END PRIVATE KEY—–”);
                    fw.close();
            }
    
            public static void main(String args[]) throws Exception{
                    ExportPrivateKey export=new ExportPrivateKey();
                    export.keystoreFile=new File(args[0]);
                    export.keyStoreType=args[1];
                    export.password=args[2].toCharArray();
                    export.alias=args[3];
                    export.exportedFile=new File(args[4]);
                    export.export();
            }
    }
    How we used it:
    Code:
    # Export the tomcat key (from the tomcat csr request) in pkcs8 format
    java -jar ExportPrivateKey.zip /opt/zimbra/tomcat/conf/keystore JKS zimbra tomcat /opt/zimbra/ssl/ssl/server/tomcat-pkcs8.key
    # Convert the pkcs8 formatted key to a non binary one
    openssl pkcs8 -inform PEM -nocrypt -in /opt/zimbra/ssl/ssl/server/tomcat-pkcs8.key -out /opt/zimbra/ssl/ssl/server/tomcat.key
    # Copy the tomcat.key and tomcat.pem to overwrite the default self signed smtpd ones
    cp /opt/zimbra/ssl/ssl/server/tomcat.key /opt/zimbra/conf/smtpd.key
    cp /opt/zimbra/ssl/ssl/server/tomcat.pem /opt/zimbra/conf/smtpd.crt
    # Restart Zimbra (or just Postfix if you choose)
    su zimbra
    zmcontrol stop
    zmcontrol start
    Now to test and see if it worked.
    For Postfix:
    Code:
    nc postfix.host.com 25                       (or telnet instead of nc if you don't have netcat but do have telnet)
    220 postfix.host.com ESMTP Postfix
    ehlo world                                   <-- type this line
    250-intraz.rio.com
    250-PIPELINING
    250-SIZE 10240000
    250-VRFY
    250-ETRN
    250-STARTTLS
    250 8BITMIME
    starttls                                     <-- type this line
    # If you get this:
    220 Ready to start TLS                       <-- SUCCESS !!!
    454 TLS not available due to local problem   <-- FAILURE :(
    For Apache (which needs slightly separate instructions for setting up the file pair, but the principles for extracting the key and such are the same):
    Open a browser, browse to the site, use your browser to verify the validity of the certificate.

    Disclaimer: I did not write the java code used for exporting the private key and the instructions on this page are only slightly edited and updated instructions found on the linked websites. This edited version of the instructions is what worked for us, there are no guarantees that it will work for you. If you have any problems running the java program to extract the key, please seek help from the person who wrote it. For anything Zimbra related however feel free to follow up in this post and someone will surely try to help.

    Cheers,

    RioGD

    Post Scriptum: To the Zimbra devs reading this... Wouldn't it be nice if Zimbra included the functionality to do all of this from within the interface so that people who require commercial certificates (most likely a large majority of your NE users) don't have to follow half baked howtos/tutorials, like the one I have just done , which are the source of much frustration ?
    Attached Files Attached Files

  2. #2
    jholder's Avatar
    jholder is offline Former Zimbran
    Join Date
    Oct 2005
    Location
    Thatcher, AZ
    Posts
    5,606
    Rep Power
    20

    Default

    Thanks for the Tip!
    I've filed a bug, and we'll get this into the wiki

    Bug 18021 - Support Export of Private Key via Admin UI

  3. #3
    riogd is offline Senior Member
    Join Date
    Apr 2006
    Posts
    50
    Rep Power
    9

    Default

    Thanks for the prompt response. Would it be possible to actually unify the whole ordeal within the Admin UI ? This would mean giving the ability to:
    • Generate a CSR for sending to the Certificate Authority.
    • Paste the PEM certificate sent back from the Certificate Authority.
    • Install the received PEM certificate into Tomcat's keystore for HTTPS access.
    • Install, by exporting and converting per the above instructions, the certificate & key pair for Postfix.


    The reason I would lead towards this is that the folks who are using commercial certificates are really met with a hassle to install them. And before you say "Save the hassle use the simple self signed ones" as some people in the forums have, it is important to note that all mobile users with Palm Treo's newer than the 650 will require a commercial certificate as there is no "easy way" to make them accept a self signed certificate. So basically Zimbra Mobile will not work properly on some phones without a commercial certificate.
    My reasoning is that it should be more simple than it currently is, to install a commercial certificate on a product geared towards business / enterprise use.
    Also unifying the whole thing in the UI using similar steps as outlined in this post will prevent ever exposing the private key via the UI. The only thing which will be exposed via the Admin UI is the CSR to generate the PEM certificate. Once generated and submitted through the Admin UI everything can take place internally.

    Thank you again for the prompt response and for submitting the bug request.

    Cheers,

    RioGD

    Post Scriptum: I had added this to the wiki here but would actually like for it to be redone by someone who has better wikifu than I do and perhaps placed in a better location etc...


LinkBacks (?)

  1. 11-16-2007, 01:53 AM
  2. 08-07-2007, 12:09 PM

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Initializing ldap...FAILED (256) on Mac OSX 10.4.4
    By kenzoida in forum Installation
    Replies: 19
    Last Post: 02-14-2007, 12:19 AM
  2. certs
    By rmvg in forum Administrators
    Replies: 11
    Last Post: 11-02-2005, 11:37 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •