How to generate a Certificate Chain to be sent as an argument to KeyStore.PrivateKeyEntry?
I am a beginner in Java Programming. My code encrypts data extracted from a text file and stores it in another file using RSA algorithm. I want to make my Private Key password protected by using the KeyStore class (http://download.oracle.com/javase/1,5.0/docs/api/java/security/KeyStore.html) and it's nested class - KeyStore.PrivateKeyEntry (http://download.oracle.com/javase/1,5.0/docs/api/java/security/KeyStore.PrivateKeyEntry.html).
The constructor of KeyStore.PrivateKeyEntry requires a Certificate[] array and I am not sure about how to generate this Certificate[] array.
I am attaching my code so far along with the question:
This is the Encryption code.
public class Fileencrypt {
public static void main(String args[]) throws IOException, InvalidKeyException, java.security.InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, KeyStoreException, CertificateException, CertificateEncodingException, IllegalStateException, NoSuchProviderException, SignatureException, UnrecoverableKeyException{
try{
byte[] plainData;
byte[] encryptedData = null;
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
PublicKey publicKey = kp.getPublic();
PrivateKey privateKey = kp.getPrivate();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
try {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream("C:\\Output\\Publickey.txt");
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();
// Store Private Key.
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
fos = new FileOutputStream("C:\\Output\\Privatekey.txt");
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
File f = new File("C:\\Output\\text.txt");
FileInputStream in = new FileInputStream(f);
plainData = new byte[(int)f.length()];
in.read(plainData);
try {
encryptedData = cipher.doFinal(plainData);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
System.out.println(encryptedData);
FileOutputStream target = new FileOutputStream(new File("C:\\Output\\encrypted.txt"));
target.write(encryptedData);
target.close();
}
catch(IOException e){e.printStackTrace();}
catch(Inval开发者_开发百科idKeyException ei){ei.printStackTrace();
}
}
}
This is the Decryption code.
public class Filedecrypt {
public static void main(String args[]) throws IOException,
InvalidKeyException, java.security.InvalidKeyException,
NoSuchAlgorithmException, NoSuchPaddingException,
BadPaddingException {
try {
byte[] plainData = null;
byte[] encryptedData;
File f1 = new File("C:\\Output\\Privatekey.txt");
FileInputStream in1 = new FileInputStream(f1);
byte[] bytekey = new byte[(int) f1.length()];
in1.read(bytekey);
KeyFactory keyFac = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytekey);
PrivateKey key = keyFac.generatePrivate(keySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
File f = new File("C:\\Output\\encrypted.txt");
FileInputStream in = new FileInputStream(f);
encryptedData = new byte[(int) f.length()];
in.read(encryptedData);
try {
plainData = cipher.doFinal(encryptedData);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
FileOutputStream target = new FileOutputStream(
new File(
"C:\\Output\\text1.txt"));
target.write(plainData);
target.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InvalidKeyException ei) {
ei.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
If you want to save private key with certificate you can use something like this:
/**
* Create new Certificate Authority.
* @param keyAlgorithm key algorithm
* @param keyLength key length
* @param storePassword store password
* @param keyPassword private key password
* @param alias alias in key store
* @param signatureAlgorithm signature algorithm
* @param issuer issuer
* @param validFrom certificate validity first date
* @param validTo certificate validity last date
* @return KeyStore with the certificate and private key
* @throws GeneralSecurityException
*/
public static KeyStore createCertificateAuthority(String keyAlgorithm, int keyLength, char[] storePassword, char[] keyPassword, String alias,
String signatureAlgorithm, String issuer, Date validFrom, Date validTo)
throws GeneralSecurityException {
String subject = issuer;
String subjectAltName = null;
String subjectIPAddress = null;//"127.0.0.1";
KeyPair keyPair = SecurityUtils.generateKeyPair(keyAlgorithm, keyLength);
X509Certificate x509Certificate = CertificateUtils.generateV3Certificate(
new X500Principal(issuer), new X500Principal(subject),
false, false, subjectAltName, subjectIPAddress,
keyPair.getPublic(), keyPair.getPrivate(), validFrom, validTo, signatureAlgorithm);
x509Certificate.checkValidity(new Date());
x509Certificate.verify(keyPair.getPublic());
X509Certificate[] chain = new X509Certificate[1];
chain[0] = x509Certificate;
KeyStore keyStoreSigningKey = SecurityUtils.createKeyStore(storePassword);
keyStoreSigningKey.setKeyEntry(alias, keyPair.getPrivate(), keyPassword, chain);
return keyStoreSigningKey;
}
/**
* Generate RCA 1024bit private and public keys pair
*
* @param algorithm the standard string name of the algorithm. i.e. "RSA"
* @param keySize algorithm-specific metric, such as modulus length, specified in number of bits. i.e. 1024,2048,4096 for RSA
* @return
* @throws NoSuchAlgorithmException
*/
public static KeyPair generateKeyPair(String algorithm, int keySize) throws NoSuchAlgorithmException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(algorithm);
kpg.initialize(keySize);
return kpg.generateKeyPair();
}
/**
* Create new key store
*
* @param storePassword
* @return
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws CertificateException
*/
public static KeyStore createKeyStore(char[] storePassword) throws KeyStoreException, NoSuchAlgorithmException, CertificateException {
// Instantiate KeyStore
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
// Load keystore
try {
keyStore.load(null, storePassword);
} catch (IOException e) { //theoretically should never happen
throw new KeyStoreException(e);
}
return keyStore;
}
or another similar method I have:
/**
* Creates a new key pair and self-signed certificate.
* example params: keyAlgName = "RSA", sigAlgName = "SHA1WithRSA", keysize = 2048
* Example: x500Name=new X500Name(commonName, organizationalUnit, organization, city, state, country);
* @param keyStore
* @param alias
* @param keyPass
* @param keyAlgName
* @param sigAlgName
* @param keysize
* @param principal
* @param startDate
* @param validityDays
* @return KeyStore object
* @throws Exception
*/
public static KeyStore generateKeyPair(KeyStore keyStore, String alias, char[] keyPass,
String keyAlgName, String sigAlgName, int keysize,
X500Principal principal, Date startDate, int validityDays)
throws Exception {
KeyStore keyStore2 = keyStore;
if (keyStore2 == null) {
keyStore2 = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore2.load(null, null);
}
if (keyStore2.containsAlias(alias)) {
MessageFormat form = new MessageFormat("Key pair not generated, alias <alias> already exists");
Object[] source = {alias};
throw new Exception(form.format(source));
}
X509Certificate[] chain = new X509Certificate[1];
//CertAndKeyGen keyPair = new CertAndKeyGen(keyAlgName, sigAlgName);
//keyPair.generate(keysize);
//X500Name x500Name=new X500Name(commonName, organizationalUnit, organization, city, state, country);
//chain[0] = keyPair.getSelfCertificate(x500Name, startDate, (long)validityDays*24*3600);
KeyPair keyPair = SecurityUtils.generateKeyPair(keyAlgName, keysize);
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(startDate);
cal.add(Calendar.DATE, validityDays);
Date endDate = cal.getTime();
chain[0] = generateV3Certificate(principal, principal, false, true, null, null, keyPair.getPublic(), keyPair.getPrivate(), startDate, endDate, sigAlgName);
keyStore2.setKeyEntry(alias, keyPair.getPrivate(), keyPass, chain);
return keyStore2;
}
/**
* Generate V3 Certificate.
* @param issuer issuer
* @param subject subject
* @param useForServerAuth use for server auth flag
* @param useForClientAuth use for client auth flag
* @param subjectAltName subject alt name
* @param subjectIPAssress subject IP address
* @param publicKey public key
* @param privateKey private key
* @param from certificate validity first date
* @param to certificate validity last date
* @param signatureAlgorithm signature algorithm
* @return X509Certificate object
* @throws GeneralSecurityException GeneralSecurityException
*/
public static X509Certificate generateV3Certificate(X500Principal issuer, X500Principal subject,
boolean useForServerAuth, boolean useForClientAuth,
String subjectAltName, String subjectIPAssress, PublicKey publicKey, PrivateKey privateKey,
Date from, Date to, String signatureAlgorithm) throws GeneralSecurityException {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
certGen.setSerialNumber(new BigInteger(UUID.randomUUID().toString().replaceAll("-", ""), 16));
certGen.setSubjectDN(subject);
certGen.setIssuerDN(issuer);
certGen.setNotBefore(from);
certGen.setNotAfter(to);
certGen.setPublicKey(publicKey);
certGen.setSignatureAlgorithm(signatureAlgorithm);
certGen.addExtension(X509Extensions.BasicConstraints, true, issuer.equals(subject) ? new BasicConstraints(1) : new BasicConstraints(false));
if (!issuer.equals(subject)) {
certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature
| KeyUsage.keyEncipherment | (useForServerAuth ? KeyUsage.keyCertSign | KeyUsage.cRLSign : 0)));
}
if (useForServerAuth) {
certGen.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeId.id_kp_serverAuth));
}
if (useForClientAuth) {
certGen.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth));
}
if (subjectAltName != null) {
certGen.addExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(
new GeneralName(GeneralName.rfc822Name, subjectAltName)));
}
if (subjectIPAssress != null) {
certGen.addExtension(X509Extensions.SubjectAlternativeName, true, new GeneralNames(
new GeneralName(GeneralName.iPAddress, subjectIPAssress)));
}
return certGen.generate(privateKey);
}
精彩评论