package de.tu_dresden.diplom.richter_mirko_mat2628335;

import org.apache.log4j.Logger;

import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import sun.misc.BASE64Encoder;

import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.FileInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.security.interfaces.RSAPrivateKey;

/*
 * generate key, write in PEM, read back in DER
 * found at https://lists.xcf.berkeley.edu/lists/advanced-java/2002-October/019136.html
 */

public class KeyGenerator {

   private static final Logger logger = Logger.getLogger(KeyGenerator.class);

   public static void main(String[] args) throws Exception {
      PrintWriter o;
      DataInputStream i;
      File f;

      KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
      KeyPair kp = kg.generateKeyPair();
      Key pub = kp.getPublic();
      Key pri = kp.getPrivate();
      byte[] pub_e = pub.getEncoded();
      byte[] pri_e = pri.getEncoded();

      o = new PrintWriter(new FileOutputStream("pub.pem"));
      o.println("-----BEGIN PUBLIC KEY-----");
      o.println(new BASE64Encoder().encode(pub_e));
      o.println("-----END PUBLIC KEY-----");
      o.close();
      o = new PrintWriter(new FileOutputStream("pri.pem"));
      o.println("-----BEGIN PRIVATE KEY-----");
      o.println(new BASE64Encoder().encode(pri_e));
      o.println("-----END PRIVATE KEY-----");
      o.close();

      KeyFactory kf = KeyFactory.getInstance("RSA");
      Key pub1 = kf.generatePublic(new X509EncodedKeySpec(pub_e));
      System.out.println("pub1: " + pub1);
      Key pri1 = kf.generatePrivate(new PKCS8EncodedKeySpec(pri_e));
      System.out.println("pri1: " + pri1);
      System.out.println("privateExponent: " + ((RSAPrivateKey) pri1).getPrivateExponent());

      Process p;
      p = Runtime.getRuntime().exec("openssl rsa -in pub.pem -inform PEM -pubin -outform DER -out pub.der");
      p.waitFor();
      p = Runtime.getRuntime().exec("openssl pkcs8 -nocrypt -in pri.pem -inform PEM -topk8 -outform DER -out pri.der");
      p.waitFor();

      byte[] b;
      f = new File("pub.der");
      b = new byte[(int) f.length()];
      i = new DataInputStream(new FileInputStream(f));
      i.readFully(b);
      i.close();
      Key pub2 = kf.generatePublic(new X509EncodedKeySpec(b));
      System.out.println("pub2: " + pub2);
      f = new File("pri.der");
      b = new byte[(int) f.length()];
      i = new DataInputStream(new FileInputStream(f));
      i.readFully(b);
      i.close();
      Key pri2 = kf.generatePrivate(new PKCS8EncodedKeySpec(b));
      System.out.println("pri2: " + pri2);
      System.out.println("privateExponent: " + ((RSAPrivateKey) pri2).getPrivateExponent());
   }

}
