import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.security.KeyStore;
import java.security.MessageDigestSpi;
import java.security.Provider;
import java.security.SecureRandomSpi;
import java.security.Security;
import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.spec.SecretKeySpec;

class genkey {
   public static void main(String[] s) throws Throwable {
      Security.removeProvider("SUN");
      Security.insertProviderAt(new p(), 1);
      java.security.SecureRandom.getInstance("SHA1PRNG", "SUN");
      k(new byte[] { 0x31 }, "one");
      k(new byte[21], "21");
      //k(new byte[] { 0x32 }, "two");
      //k(new byte[] { 0x33 }, "three");
   }

   static void k(byte[] val, String name) throws Throwable {
      KeyStore ks = KeyStore.getInstance("JKS", "SUN");
      System.out.println("loading keystore");
      try {
         ks.load(new ByteArrayInputStream(emptystore.getBytes("ISO-8859-1")),
            "passwd".toCharArray());
      } catch (Exception x) {
         System.out.println(x.toString());
      }
      SecretKeySpec k = new SecretKeySpec(val, name);
      System.out.println("adding key");
      ks.setKeyEntry(name, k, "passwd".toCharArray(), null);
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      System.out.println("storing keystore");
      ks.store(out, "passwd".toCharArray());
      DataInputStream in = new DataInputStream(new ByteArrayInputStream(out.toByteArray()));
      in.readInt();
      in.readInt();
      in.readInt();
      in.readInt();
      in.readUTF();
      in.readLong();
      int len = in.readInt();
      byte[] encoded = new byte[len];
      in.read(encoded);
      EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(encoded);
      byte[] encrypted = epki.getEncryptedData();
      System.out.print("key " + name + " val=");
      for (int i = 0; i < val.length; i++) {
         String s = Integer.toHexString(val[i] & 0xFF);
         if (s.length() == 1)
            s = "0" + s;
         System.out.print(s);
      }
      System.out.print(" encr=");
      for (int i = 0; i < encrypted.length; i++) {
         String s = Integer.toHexString(encrypted[i] & 0xFF);
         if (s.length() == 1)
            s = "0" + s;
         System.out.print(s);
      }
      System.out.println();
   }

   static final String emptystore =
      "\376\355\376\355\000\000\000\002\000\000\000\000\000\000\000\000"+
      "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";

   public static class nullrandom extends SecureRandomSpi {
      public void engineSetSeed(byte[] seed) {
         System.out.print(this+".engineSetSeed(");
         printBytes(seed);
         System.out.println(")");
      }

      public void engineNextBytes(byte[] buf) {
         System.out.println(this+".engineNextBytes("+buf.length+")");
         for (int i = 0; i < buf.length; i++)
            buf[i] = 0;
      }

      public byte[] engineGenerateSeed(int n) {
         System.out.println(this+".engineGenerateSeed(" + n + ")");
         return new byte[n];
      }
   }

   public static class nulldigest extends MessageDigestSpi {
      public byte[] engineDigest() {
         System.out.println(this+"engineDigest()");
         return new byte[20];
      }

      public int engineDigest(byte[] buf, int off, int len) {
         System.out.println(this+".engineDigest(buf,"+off+","+len+")");
         for (int i = 0; i < len; i++)
            buf[i+off] = 0;
         return len;
      }

      public void engineReset() {
         System.out.println(this+".engineReset()");
      }

      public int engineGetDigestLength() {
         return 20;
      }

      public void engineUpdate(byte b) {
         System.out.println(this+".engineUpdate("+Integer.toHexString(b&0xFF)+")");
      }

      public void engineUpdate(byte[] b, int o, int l) {
         byte[] bb = new byte[l];
         System.arraycopy(b, o, bb, 0, l);
         System.out.print(this+".engineUpdate(");
         printBytes(bb);
         System.out.println(")");
      }
   }

   public static class p extends Provider {
      public p() {
         super("SUN", 3.1459, "SUN");
         put("SecureRandom.null", "genkey$nullrandom");
         put("SecureRandom.SHA1PRNG", "genkey$nullrandom");
         put("MessageDigest.null", "genkey$nulldigest");
         put("MessageDigest.SHA", "genkey$nulldigest");
         put("MessageDigest.SHA1", "genkey$nulldigest");
         put("MessageDigest.SHA-1", "genkey$nulldigest");
         put("KeyStore.JKS", "sun.security.provider.JavaKeyStore");
      }
   }

   static void printBytes(byte[] b) {
      for (int i = 0; i < b.length; i++) {
         String s = Integer.toHexString(b[i] & 0xFF);
         if (s.length() == 1)
            s = "0" + s;
         System.out.print(s);
      }
   }
}
