package cn.report.pdf.sign.base;

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 org.apache.commons.codec.binary.Base64;


/*Keystore是一个密码保护的文件，存放私钥和证书。可以通过JDK自带的keytool工具生成。
 * 但是keytool工具，并没有提供方便的方法，从keystore文件中到处私钥和证书。
 * 所以可以通过JDK提供的java.security.KeyStore 类来编码完成相关工作。
 * JKS文件是使用keytool生成的keystore文件，
 */
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;  
	}  
	//BASE64Encoder/BASE64Decoder类在sun.misc包下，是sun公司的内部方法，后期有删除的潜在可能，建议使用apache commons.codec下的Base64替代。
	//import Decoder.BASE64Encoder;export()
	//没有调试
	public void export() throws Exception{  
		KeyStore keystore=KeyStore.getInstance(keyStoreType);  
		keystore.load(new FileInputStream(keystoreFile),password);  
		KeyPair keyPair=getPrivateKey(keystore,alias,password);  
		PrivateKey privateKey=keyPair.getPrivate();  
		//BASE64Encoder encoder=new BASE64Encoder(); 
		//String encoded=encoder.encode(privateKey.getEncoded());
		
		byte[] encoded = privateKey.getEncoded();
	    Base64 base64=new Base64();
	    encoded = base64.encode(encoded);
		
		FileWriter fw=new FileWriter(exportedFile);  
		fw.write("—–BEGIN PRIVATE KEY—–\n");  
		//fw.write(encoded);//Decoder.BASE64Encoder  
		fw.write(bytes2Int(encoded));
		fw.write("\n");  
		fw.write("—–END PRIVATE KEY—–");  
		fw.close();  
	}  
	public static int bytes2Int(byte[] bytes )
	  {
	      //如果不与0xff进行按位与操作，转换结果将出错，有兴趣的同学可以试一下。
	      int int1=bytes[0]&0xff;
	      int int2=(bytes[1]&0xff)<<8;
	      int int3=(bytes[2]&0xff)<<16;
	      int int4=(bytes[3]&0xff)<<24;
	 
	     return int1|int2|int3|int4;
	 }
	public static byte[] int2Bytes(int integer)
	  {
	      byte[] bytes=new byte[4];
	      bytes[3]=(byte) ((byte) integer>>24);
	      bytes[2]=(byte) ((byte) integer>>16);
	      bytes[1]=(byte) ((byte) integer>>8);
	      bytes[0]=(byte) integer;
	  
	      return bytes;
	 }
	public static void main(String args[]) throws Exception{  
		ExportPrivateKey export=new ExportPrivateKey();  
		export.keystoreFile=new File("D:/test/keystore.jks");//keystore.jks  
		export.keyStoreType="JKS";  
		export.password="changeit".toCharArray();  
		export.alias="tom_server";  
		export.exportedFile=new File("luke");  
		export.export();  
	}  
	
	

}  