How to import an existing X.509 certificate and private key in Java keystore to use in SSL?

前端 未结 15 861
说谎
说谎 2020-11-22 08:05

I have this in an ActiveMQ config:


        

        
相关标签:
15条回答
  • 2020-11-22 08:32

    Yes, it's indeed a sad fact that keytool has no functionality to import a private key.

    For the record, at the end I went with the solution described here

    0 讨论(0)
  • 2020-11-22 08:38

    Using Let's Encrypt certificates

    Assuming you've created your certificates and private keys with Let's Encrypt in /etc/letsencrypt/live/you.com:

    1. Create a PKCS #12 file

    openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out pkcs.p12 \
            -name letsencrypt
    

    This combines your SSL certificate fullchain.pem and your private key privkey.pem into a single file, pkcs.p12.

    You'll be prompted for a password for pkcs.p12.

    The export option specifies that a PKCS #12 file will be created rather than parsed (from the manual).

    2. Create the Java keystore

    keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 \
            -srcstoretype PKCS12 -alias letsencrypt
    

    If keystore.jks doesn't exist, it will be created containing the pkcs.12 file created above. Otherwise, you'll import pkcs.12 into the existing keystore.


    These instructions are derived from the post "Create a Java Keystore (.JKS) from Let's Encrypt Certificates" on this blog.

    Here's more on the different kind of files in /etc/letsencrypt/live/you.com/.

    0 讨论(0)
  • 2020-11-22 08:38

    What I was trying to achieve was using already provided private key and certificate to sign message that was going someplace that needed to make sure that the message was coming from me (private keys sign while public keys encrypt).

    So if you already have a .key file and a .crt file?

    Try this:

    Step1: Convert the key and cert to .p12 file

    openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -name alias -out yourconvertedfile.p12
    

    Step 2: Import the key and create a .jsk file with a single command

    keytool -importkeystore -deststorepass changeit -destkeystore keystore.jks -srckeystore umeme.p12 -srcstoretype PKCS12
    

    Step 3: In your java:

    char[] keyPassword = "changeit".toCharArray();
    
    KeyStore keyStore = KeyStore.getInstance("JKS");
    InputStream keyStoreData = new FileInputStream("keystore.jks");
    
    keyStore.load(keyStoreData, keyPassword);
    KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(keyPassword);
    KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry("alias", entryPassword);
    
    System.out.println(privateKeyEntry.toString());
    

    If you need to sign some string using this key do the following:

    Step 1: Convert the text you want to encrypt

    byte[] data = "test".getBytes("UTF8");
    

    Step 2: Get base64 encoded private key

    keyStore.load(keyStoreData, keyPassword);
    
    //get cert, pubkey and private key from the store by alias
    Certificate cert = keyStore.getCertificate("localhost");
    PublicKey publicKey = cert.getPublicKey();
    KeyPair keyPair = new KeyPair(publicKey, (PrivateKey) key);
    
    //sign with this alg
    Signature sig = Signature.getInstance("SHA1WithRSA");
    sig.initSign(keyPair.getPrivate());
    sig.update(data);
    byte[] signatureBytes = sig.sign();
    System.out.println("Signature:" + Base64.getEncoder().encodeToString(signatureBytes));
    
    sig.initVerify(keyPair.getPublic());
    sig.update(data);
    
    System.out.println(sig.verify(signatureBytes));
    

    References:

    1. How to import an existing x509 certificate and private key in Java keystore to use in SSL?
    2. http://tutorials.jenkov.com/java-cryptography/keystore.html
    3. http://www.java2s.com/Code/Java/Security/RetrievingaKeyPairfromaKeyStore.htm
    4. How to sign string with private key

    Final program

    public static void main(String[] args) throws Exception {
    
        byte[] data = "test".getBytes("UTF8");
    
        // load keystore
        char[] keyPassword = "changeit".toCharArray();
    
        KeyStore keyStore = KeyStore.getInstance("JKS");
        //System.getProperty("user.dir") + "" < for a file in particular path 
        InputStream keyStoreData = new FileInputStream("keystore.jks");
        keyStore.load(keyStoreData, keyPassword);
    
        Key key = keyStore.getKey("localhost", keyPassword);
    
        Certificate cert = keyStore.getCertificate("localhost");
    
        PublicKey publicKey = cert.getPublicKey();
    
        KeyPair keyPair = new KeyPair(publicKey, (PrivateKey) key);
    
        Signature sig = Signature.getInstance("SHA1WithRSA");
    
        sig.initSign(keyPair.getPrivate());
        sig.update(data);
        byte[] signatureBytes = sig.sign();
        System.out.println("Signature:" + Base64.getEncoder().encodeToString(signatureBytes));
    
        sig.initVerify(keyPair.getPublic());
        sig.update(data);
    
        System.out.println(sig.verify(signatureBytes));
    }
    
    0 讨论(0)
提交回复
热议问题