[java] Load RSA public key from file

I've generated a private key with:

openssl genrsa [-out file] –des3

After this I've generated a public key with:

openssl rsa –pubout -in private.key [-out file]

I want to sign some messages with my private key, and verify some other messages with my public key, using code like this:

public String sign(String message) throws SignatureException{
    try {
        Signature sign = Signature.getInstance("SHA1withRSA");
        sign.initSign(privateKey);
        sign.update(message.getBytes("UTF-8"));
        return new String(Base64.encodeBase64(sign.sign()),"UTF-8");
    } catch (Exception ex) {
        throw new SignatureException(ex);
    }
}

public boolean verify(String message, String signature) throws SignatureException{
    try {
        Signature sign = Signature.getInstance("SHA1withRSA");
        sign.initVerify(publicKey);
        sign.update(message.getBytes("UTF-8"));
        return sign.verify(Base64.decodeBase64(signature.getBytes("UTF-8")));
    } catch (Exception ex) {
        throw new SignatureException(ex);
    }
}

I found a solution to convert my private key to PKCS8 format and load it. It works with some code like this:

public PrivateKey getPrivateKey(String filename) throws Exception {

    File f = new File(filename);
    FileInputStream fis = new FileInputStream(f);
    DataInputStream dis = new DataInputStream(fis);
    byte[] keyBytes = new byte[(int) f.length()];
    dis.readFully(keyBytes);
    dis.close();
    PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory kf =
            KeyFactory.getInstance("RSA");
    return kf.generatePrivate(spec);
}

And finally my question is: How do I load my RSA Public Key from a file?

I think maybe I need to convert my public key file to x509 format, and use X509EncodedKeySpec. But how can I do this?

This question is related to java openssl rsa

The answer is


This program is doing almost everything with Public and private keys. The der format can be obtained but saving raw data ( without encoding base64). I hope this helps programmers.

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import sun.security.pkcs.PKCS8Key;
import sun.security.pkcs10.PKCS10;
import sun.security.x509.X500Name;

import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;



/**
 * @author Desphilboy
 * DorOd bar shomA barobach
 *
 */
public class csrgenerator {

    private static PublicKey publickey= null;
    private static PrivateKey privateKey=null;
    //private static PKCS8Key privateKey=null;
    private static KeyPairGenerator kpg= null;
    private static ByteArrayOutputStream bs =null;
    private static csrgenerator thisinstance;
    private KeyPair keypair;
    private static PKCS10 pkcs10;
    private String signaturealgorithm= "MD5WithRSA";

    public String getSignaturealgorithm() {
        return signaturealgorithm;
    }



    public void setSignaturealgorithm(String signaturealgorithm) {
        this.signaturealgorithm = signaturealgorithm;
    }



    private csrgenerator() {
        try {
           kpg = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            System.out.print("No such algorithm RSA in constructor csrgenerator\n");
        }
        kpg.initialize(2048);
        keypair = kpg.generateKeyPair();
        publickey = keypair.getPublic();
        privateKey = keypair.getPrivate();
    }



    /** Generates a new key pair 
    *
    * @param int bits 
    *   this is the number of bits in modulus must be 512, 1024, 2048  or so on 
    */
    public KeyPair generateRSAkys(int bits)
    {
          kpg.initialize(bits);
            keypair = kpg.generateKeyPair();
            publickey = keypair.getPublic();
            privateKey = keypair.getPrivate();
            KeyPair dup= keypair;
     return dup;
    }

     public static csrgenerator getInstance() {
            if (thisinstance == null)
                thisinstance = new csrgenerator();
            return thisinstance;
        }


     /**
      *  Returns a CSR as string  
      * @param cn  Common Name
      * @param OU  Organizational Unit 
      * @param Org  Organization
      * @param LocName Location name
      * @param Statename  State/Territory/Province/Region
      * @param Country    Country
      * @return     returns  csr as string.
      * @throws Exception
      */
     public String getCSR(String commonname, String organizationunit, String organization,String localname, String statename, String country ) throws Exception {
            byte[] csr = generatePKCS10(commonname, organizationunit, organization, localname, statename, country,signaturealgorithm);
            return new String(csr);
        }

     /** This function generates a new Certificate 
      * Signing Request. 
     *
     * @param CN
     *            Common Name, is X.509 speak for the name that distinguishes
     *            the Certificate best, and ties it to your Organization
     * @param OU
     *            Organizational unit
     * @param O
     *            Organization NAME
     * @param L
     *            Location
     * @param S
     *            State
     * @param C
     *            Country
     * @return    byte stream of generated request
     * @throws Exception
     */
    private static byte[] generatePKCS10(String CN, String OU, String O,String L, String S, String C,String sigAlg) throws Exception {
        // generate PKCS10 certificate request

        pkcs10 = new PKCS10(publickey);
       Signature   signature = Signature.getInstance(sigAlg);
        signature.initSign(privateKey);
        // common, orgUnit, org, locality, state, country
        //X500Name(String commonName, String organizationUnit,String organizationName,Local,State, String country)
        X500Name x500Name = new X500Name(CN, OU, O, L, S, C);
        pkcs10.encodeAndSign(x500Name,signature);
        bs = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(bs);
        pkcs10.print(ps);
        byte[] c = bs.toByteArray();
        try {
            if (ps != null)
                ps.close();
            if (bs != null)
                bs.close();
        } catch (Throwable th) {
        }
        return c;
    }

    public  PublicKey getPublicKey() {
        return publickey;
    }




    /**
     * @return
     */
    public PrivateKey getPrivateKey() {
        return privateKey;
    }

    /**
     * saves private key to a file
     * @param filename
     */
    public  void SavePrivateKey(String filename)
    {
        PKCS8EncodedKeySpec pemcontents=null;
        pemcontents= new PKCS8EncodedKeySpec( privateKey.getEncoded());
        PKCS8Key pemprivatekey= new  PKCS8Key( );
        try {
            pemprivatekey.decode(pemcontents.getEncoded());
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        File file=new File(filename);
        try {

            file.createNewFile();
            FileOutputStream fos=new FileOutputStream(file);
            fos.write(pemprivatekey.getEncoded());
            fos.flush();
            fos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }



    /**
     * Saves Certificate Signing Request to a file;
     * @param filename  is a String containing full path to the file which will be created containing the CSR.
     */
    public void SaveCSR(String filename)
    {
        FileOutputStream fos=null;
        PrintStream ps=null;
        File file;
        try {

            file = new File(filename);
            file.createNewFile();
            fos = new FileOutputStream(file);
            ps= new PrintStream(fos);
        }catch (IOException e)
        {
            System.out.print("\n could not open the file "+ filename);
        }

        try {
            try {
                pkcs10.print(ps);
            } catch (SignatureException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            ps.flush();
            ps.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.print("\n cannot write to the file "+ filename);
            e.printStackTrace();

        }

        }


    /**
     * Saves both public key and private  key to file names specified
     * @param fnpub  file name of public key
     * @param fnpri  file name of private key
     * @throws IOException
     */
    public static void SaveKeyPair(String fnpub,String fnpri) throws IOException { 

// Store Public Key.
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publickey.getEncoded());
FileOutputStream fos = new FileOutputStream(fnpub);
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();

// Store Private Key.
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
fos = new FileOutputStream(fnpri);
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
}


    /**
     * Reads a Private Key from a pem base64 encoded file.
     * @param filename name of the file to read.
     * @param algorithm Algorithm is usually "RSA"
     * @return returns the privatekey which is read from the file;
     * @throws Exception
     */
    public  PrivateKey getPemPrivateKey(String filename, String algorithm) throws Exception {
          File f = new File(filename);
          FileInputStream fis = new FileInputStream(f);
          DataInputStream dis = new DataInputStream(fis);
          byte[] keyBytes = new byte[(int) f.length()];
          dis.readFully(keyBytes);
          dis.close();

          String temp = new String(keyBytes);
          String privKeyPEM = temp.replace("-----BEGIN PRIVATE KEY-----", "");
          privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", "");
          //System.out.println("Private key\n"+privKeyPEM);

          BASE64Decoder b64=new BASE64Decoder();
          byte[] decoded = b64.decodeBuffer(privKeyPEM);

          PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
          KeyFactory kf = KeyFactory.getInstance(algorithm);
          return kf.generatePrivate(spec);
          }



    /**
     * Saves the private key to a pem file.
     * @param filename  name of the file to write the key into 
     * @param key the Private key to save.
     * @return  String representation of the pkcs8 object.
     * @throws Exception
     */
    public  String  SavePemPrivateKey(String filename) throws Exception {
        PrivateKey key=this.privateKey;
          File f = new File(filename);
          FileOutputStream fos = new FileOutputStream(f);
          DataOutputStream dos = new DataOutputStream(fos);


          byte[] keyBytes = key.getEncoded();
          PKCS8Key pkcs8= new PKCS8Key();
          pkcs8.decode(keyBytes);
          byte[] b=pkcs8.encode();

          BASE64Encoder b64=new BASE64Encoder();
          String  encoded = b64.encodeBuffer(b);

          encoded= "-----BEGIN PRIVATE KEY-----\r\n" + encoded + "-----END PRIVATE KEY-----";

         dos.writeBytes(encoded);
         dos.flush();
         dos.close();

          //System.out.println("Private key\n"+privKeyPEM);
        return pkcs8.toString();

          }


    /**
     * Saves a public key to a base64 encoded pem file
     * @param filename  name of the file 
     * @param key public key to be saved 
     * @return string representation of the pkcs8 object.
     * @throws Exception
     */
    public  String  SavePemPublicKey(String filename) throws Exception {
        PublicKey key=this.publickey;  
        File f = new File(filename);
          FileOutputStream fos = new FileOutputStream(f);
          DataOutputStream dos = new DataOutputStream(fos);


          byte[] keyBytes = key.getEncoded();
          BASE64Encoder b64=new BASE64Encoder();
          String  encoded = b64.encodeBuffer(keyBytes);

          encoded= "-----BEGIN PUBLIC KEY-----\r\n" + encoded + "-----END PUBLIC KEY-----";

         dos.writeBytes(encoded);
         dos.flush();
         dos.close();

          //System.out.println("Private key\n"+privKeyPEM);
      return  encoded.toString();

          }





       /**
     * reads a public key from a file
     * @param filename name of the file to read
     * @param algorithm is usually RSA
     * @return the read public key
     * @throws Exception
     */
    public  PublicKey getPemPublicKey(String filename, String algorithm) throws Exception {
          File f = new File(filename);
          FileInputStream fis = new FileInputStream(f);
          DataInputStream dis = new DataInputStream(fis);
          byte[] keyBytes = new byte[(int) f.length()];
          dis.readFully(keyBytes);
          dis.close();

          String temp = new String(keyBytes);
          String publicKeyPEM = temp.replace("-----BEGIN PUBLIC KEY-----\n", "");
          publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");


          BASE64Decoder b64=new BASE64Decoder();
          byte[] decoded = b64.decodeBuffer(publicKeyPEM);

          X509EncodedKeySpec spec =
                new X509EncodedKeySpec(decoded);
          KeyFactory kf = KeyFactory.getInstance(algorithm);
          return kf.generatePublic(spec);
          }




    public static void main(String[] args) throws Exception {
        csrgenerator gcsr = csrgenerator.getInstance();
        gcsr.setSignaturealgorithm("SHA512WithRSA");
        System.out.println("Public Key:\n"+gcsr.getPublicKey().toString());

        System.out.println("Private Key:\nAlgorithm: "+gcsr.getPrivateKey().getAlgorithm().toString());
        System.out.println("Format:"+gcsr.getPrivateKey().getFormat().toString());
        System.out.println("To String :"+gcsr.getPrivateKey().toString());
        System.out.println("GetEncoded :"+gcsr.getPrivateKey().getEncoded().toString());
        BASE64Encoder encoder= new BASE64Encoder();
        String s=encoder.encodeBuffer(gcsr.getPrivateKey().getEncoded());
        System.out.println("Base64:"+s+"\n");

        String csr = gcsr.getCSR( "[email protected]","baxshi az xodam", "Xodam","PointCook","VIC" ,"AU");
        System.out.println("CSR Request Generated!!");
        System.out.println(csr);
        gcsr.SaveCSR("c:\\testdir\\javacsr.csr");
        String p=gcsr.SavePemPrivateKey("c:\\testdir\\java_private.pem");
        System.out.print(p);
        p=gcsr.SavePemPublicKey("c:\\testdir\\java_public.pem");
        privateKey= gcsr.getPemPrivateKey("c:\\testdir\\java_private.pem", "RSA");
        BASE64Encoder encoder1= new BASE64Encoder();
        String s1=encoder1.encodeBuffer(gcsr.getPrivateKey().getEncoded());
        System.out.println("Private Key in Base64:"+s1+"\n");
        System.out.print(p);


    }

    }

Below code works absolutely fine to me and working. This code will read RSA private and public key though java code. You can refer to http://snipplr.com/view/18368/

   import java.io.DataInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.security.KeyFactory;
    import java.security.NoSuchAlgorithmException;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;

    public class Demo {

        public static final String PRIVATE_KEY="/home/user/private.der";
        public static final String PUBLIC_KEY="/home/user/public.der";

        public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
            //get the private key
            File file = new File(PRIVATE_KEY);
            FileInputStream fis = new FileInputStream(file);
            DataInputStream dis = new DataInputStream(fis);

            byte[] keyBytes = new byte[(int) file.length()];
            dis.readFully(keyBytes);
            dis.close();

            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory kf = KeyFactory.getInstance("RSA");
            RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(spec);
            System.out.println("Exponent :" + privKey.getPrivateExponent());
            System.out.println("Modulus" + privKey.getModulus());

            //get the public key
            File file1 = new File(PUBLIC_KEY);
            FileInputStream fis1 = new FileInputStream(file1);
            DataInputStream dis1 = new DataInputStream(fis1);
            byte[] keyBytes1 = new byte[(int) file1.length()];
            dis1.readFully(keyBytes1);
            dis1.close();

            X509EncodedKeySpec spec1 = new X509EncodedKeySpec(keyBytes1);
            KeyFactory kf1 = KeyFactory.getInstance("RSA");
            RSAPublicKey pubKey = (RSAPublicKey) kf1.generatePublic(spec1);

            System.out.println("Exponent :" + pubKey.getPublicExponent());
            System.out.println("Modulus" + pubKey.getModulus());
        }
    }

Once you have your key stored in a PEM file, you can read it back easily using PemObject and PemReader classes provided by BouncyCastle, as shown in this this tutorial.

Create a PemFile class that encapsulates file handling:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

public class PemFile {

    private PemObject pemObject;

    public PemFile(String filename) throws FileNotFoundException, IOException {
        PemReader pemReader = new PemReader(new InputStreamReader(
                new FileInputStream(filename)));
        try {
            this.pemObject = pemReader.readPemObject();
        } finally {
            pemReader.close();
        }
    }

    public PemObject getPemObject() {
        return pemObject;
    }
}

Then instantiate private and public keys as usual:

import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class Main {

    protected final static Logger LOGGER = Logger.getLogger(Main.class);

    public final static String RESOURCES_DIR = "src/main/resources/rsa-sample/";

    public static void main(String[] args) throws FileNotFoundException,
            IOException, NoSuchAlgorithmException, NoSuchProviderException {
        Security.addProvider(new BouncyCastleProvider());
        LOGGER.info("BouncyCastle provider added.");

        KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
        try {
            PrivateKey priv = generatePrivateKey(factory, RESOURCES_DIR
                    + "id_rsa");
            LOGGER.info(String.format("Instantiated private key: %s", priv));

            PublicKey pub = generatePublicKey(factory, RESOURCES_DIR
                    + "id_rsa.pub");
            LOGGER.info(String.format("Instantiated public key: %s", pub));
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
    }

    private static PrivateKey generatePrivateKey(KeyFactory factory,
            String filename) throws InvalidKeySpecException,
            FileNotFoundException, IOException {
        PemFile pemFile = new PemFile(filename);
        byte[] content = pemFile.getPemObject().getContent();
        PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
        return factory.generatePrivate(privKeySpec);
    }

    private static PublicKey generatePublicKey(KeyFactory factory,
            String filename) throws InvalidKeySpecException,
            FileNotFoundException, IOException {
        PemFile pemFile = new PemFile(filename);
        byte[] content = pemFile.getPemObject().getContent();
        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);
        return factory.generatePublic(pubKeySpec);
    }
}

Hope this helps.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to openssl

dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib How to install OpenSSL in windows 10? SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 How to fix: fatal error: openssl/opensslv.h: No such file or directory in RedHat 7 Homebrew refusing to link OpenSSL Solving sslv3 alert handshake failure when trying to use a client certificate How to install latest version of openssl Mac OS X El Capitan How to resolve the "EVP_DecryptFInal_ex: bad decrypt" during file decryption SSL error SSL3_GET_SERVER_CERTIFICATE:certificate verify failed Can't get private key with openssl (no start line:pem_lib.c:703:Expecting: ANY PRIVATE KEY)

Examples related to rsa

RSA encryption and decryption in Python Differences between "BEGIN RSA PRIVATE KEY" and "BEGIN PRIVATE KEY" C# RSA encryption/decryption with transmission RSA Public Key format Load RSA public key from file Calculate RSA key fingerprint Use RSA private key to generate public key? Encrypt and Decrypt text with RSA in PHP How do I access my SSH public key? How to Load RSA Private Key From File