How do I sign a PDF document using a LUNA HSM? - java

I use a java with Itext for make a digital sign PDF document using a LUNA HSM.
My objective is sign a document with PKCS11 and assemble the certificates chain from the HSM. I dont want to install certificates into the server.
I try to use a sample program called C4_01_SignWithPKCS11HSM.java from the iText.
I take this from:
http://developers.itextpdf.com/examples/security/digital-signatures-white-paper/digital-signatures-chapter-4
When I compiled program, it show me the follow warning:
[luna#sumCentosHsm pdf]$ javac -Xlint signPdf.java signPdf.java:93:
warning: [deprecation] OcspClientBouncyCastle() in
OcspClientBouncyCastle has been deprecated
OcspClient ocspClient = new OcspClientBouncyCastle();
Also, how to build the configuration file and parameters.
I would like to know if someone had the same problem
Thank you.

import java.security.*;
import java.security.KeyStore.*;
import java.security.cert.X509Certificate;
import java.security.cert.Certificate;
import com.safenetinc.luna.*;
import java.io.*;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.security.*;
public class SignPdfUsingLuna{
private static String keyAlias = null;
private static String slotPin = null;
private static int slotId;
private static String inputFile = null;
private static String outputFile = null;
private static KeyStore ks = null;
private static PrivateKeyEntry prKE = null;
private static void usage(){
System.out.println("Command usage :-");
System.out.println("java SignPdfUsingLuna <SlotNumber> <SlotPassword> <KeyAlias> <InputFile>");
}
public static void main(String args[]){
try{
slotId = Integer.parseInt(args[0]);
slotPin = args[1];
keyAlias = args[2];
inputFile = args[3];
ks = KeyStore.getInstance("Luna");
ks.load(new ByteArrayInputStream(("slot:"+slotId).getBytes()),slotPin.toCharArray());
ProtectionParameter param = new PasswordProtection("abcd".toCharArray());
prKE = (PrivateKeyEntry)ks.getEntry(keyAlias,param);
X509Certificate cert = (X509Certificate)ks.getCertificate(keyAlias);
Certificate[] certchain = (Certificate[]) ks.getCertificateChain(keyAlias);
PdfReader readPdf = new PdfReader(inputFile);
FileOutputStream outFile = new FileOutputStream("Signed"+inputFile);
PdfStamper stamp = PdfStamper.createSignature(readPdf, outFile, '\0');
PdfSignatureAppearance psa = stamp.getSignatureAppearance();
psa.setReason("Signed by :- Sam Paul");
psa.setLocation("India");
Image img = Image.getInstance("Logo.jpg");
psa.setImage(img);
psa.setVisibleSignature(new Rectangle(100, 100, 300, 200), 1, "Signature");
ExternalDigest dgst = new BouncyCastleDigest();
Provider prod = ks.getProvider();
PrivateKey pk = prKE.getPrivateKey();
ExternalSignature sign = new PrivateKeySignature(pk,DigestAlgorithms.SHA256,prod.getName());
MakeSignature.signDetached(psa, dgst, sign, certchain, null, null, null, 0, MakeSignature.CryptoStandard.CMS);
stamp.close();
}catch(ArrayIndexOutOfBoundsException aio){
usage();
}catch(NumberFormatException nfe){
System.out.println("Please enter a valid slot number");
usage();
}catch(Exception e){
e.printStackTrace();
}
}
Hope this helps.
Sam.

Perhaps you have a special circumstance where you want to use HSM keys to sign documents. Most of the time, document signing is done with 'person-entity' PKI certificates. In this scenario, your local Certificate Authority (Windows Server), has been configured to store the CA's private key on the SafeNet HSM. Then the local CA would issue personal PKI certificates to users of that domain (Bob Smith). Then a user, Bob, could use his certificate that is local to his machine to sign documents. This would provide integrity and nonrepudiation, and the certificate would signed by that individual.
In your implementation, any signed document would simply display the subject name of the HSM certificate, which in most implementations would be a domain's CA name, etc.

Related

Save pfx certificate to file with java code (ejbca)

i use EJBCA to generate a certificate from a CommonName. In java code i have generated private key and public key and then the csr for generate the certificate.
Now i save the certificate in PEM format (.cer), but i need also private key so i want save with .pfx or p12 extension. How can i do?
This is my actual code for generate certificate:
KeyPair keys;
try {
keys = KeyTools.genKeys("1024", AlgorithmConstants.KEYALGORITHM_RSA);
//SAVE PRIVKEY
//PrivateKey privKey = keys.getPrivate();
//byte[] privateKeyBytes = privKey.getEncoded();
PKCS10CertificationRequest pkcs10 = new PKCS10CertificationRequest("SHA256WithRSA",
CertTools.stringToBcX509Name("CN=NOUSED"), keys.getPublic(), null, keys.getPrivate());
//Print Privatekey
//System.out.println(keys.getPrivate().toString());
CertificateResponse certenv = ws.certificateRequest(user1,
new String(Base64.encode(pkcs10.getEncoded())),
CertificateHelper.CERT_REQ_TYPE_PKCS10,
null,
CertificateHelper.RESPONSETYPE_CERTIFICATE);
//Certificate certenv = ejbcaraws.pkcs10Req("WSTESTUSER1","foo123",new
//String(Base64.encode(pkcs10.getEncoded())),null);
return certenv.getCertificate ();
}catch (Exception e) {}
and with this i save the certificate:
File file = new File(path+"/"+ x509Cert.getSubjectDN().toString().replace("CN=", "") +".cer");
FileOutputStream os = new FileOutputStream(file);
//os.write("-----BEGIN CERTIFICATE-----\n".getBytes("US-ASCII"));
//os.write(Base64.encode(x509Cert.getEncoded(), true));
//os.write("-----END CERTIFICATE-----".getBytes("US-ASCII"));
//os.close();
PEMWriter pemWriter = new PEMWriter(new PrintWriter(os));
pemWriter.writeObject(x509Cert);
pemWriter.flush();
pemWriter.close();
I never use EJBCA, however if you have the certificate and the private key and you want to create a PKCS12 you can use setKeyEntry(String alias,byte[] key,Certificate[] chain) method from java.security.KeyStore to add the entry, and then store(OutputStream stream, char[] password) method to save the PKCS12 on a file (look at API for more details). Your code could be something like:
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
public class SamplePKCS12 {
public static void main(String args[]) throws Exception {
String alias = // the alias for your key...
PrivateKey key = // your private key
Certificate[] chain = // an array with your EE certificate to your CA issuer
// create keystore
KeyStore keystore = KeyStore.getInstance("PKCS12");
// add your key and cert
keystore.setKeyEntry(alias, key.getEncoded(), chain);
// save the keystore to file
keystore.store(new FileOutputStream("/tmp/keystore.p12"), "yourPin".toCharArray());
}
}
Note I suppose that you have your certificate and your private key as you said in your question. To work with PKCS12 you need SunJSSE provider (which is normally loaded by default), or alternatively you can use BouncyCastle provider.
Hope this helps,

Java code to generate private key and self signed certificate [duplicate]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 8 years ago.
Improve this question
I'm looking for a java library or code to generate certificates, public and private keys
on the fly without to use third party programs (such as openssl).
I think something that is doeing keytool+openssl but from Java code.
Consider a java servlet based web application secured with ssl and client authentification.
I want the servlet container generate client certificates (eg. pkcs12 format) on request only with Java code.
You can generate Certificate in java dynamically, by using a pair or keys. (Public Key, Private Keys). Get These keys as BigInteger format and checking the following code to generate certificate.
RSAPrivateKeySpec serPrivateSpec = new RSAPrivateKeySpec(
new BigInteger(val of pub key), new BigInteger(val of pri key));
fact = KeyFactory.getInstance("RSA");
PrivateKey serverPrivateKey = fact.generatePrivate(serPrivateSpec);
RSAPublicKeySpec serPublicSpec = new RSAPublicKeySpec(
new BigInteger(agentCL.getSerPubMod()), new BigInteger(agentCL.getSerPubExp()));
PublicKey serverPublicKey = fact.generatePublic(serPublicSpec);
keyStore = KeyStore.getInstance(IMXAgentCL.STORE_TYPE);
keyStore.load(null, SOMEPWD.toCharArray());
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
X509Certificate[] serverChain = new X509Certificate[1];
X509V3CertificateGenerator serverCertGen = new X509V3CertificateGenerator();
X500Principal serverSubjectName = new X500Principal("CN=OrganizationName");
serverCertGen.setSerialNumber(new BigInteger("123456789"));
// X509Certificate caCert=null;
serverCertGen.setIssuerDN(somename);
serverCertGen.setNotBefore(new Date());
serverCertGen.setNotAfter(new Date());
serverCertGen.setSubjectDN(somename);
serverCertGen.setPublicKey(serverPublicKey);
serverCertGen.setSignatureAlgorithm("MD5WithRSA");
// certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,new
// AuthorityKeyIdentifierStructure(caCert));
serverCertGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
new SubjectKeyIdentifierStructure(serverPublicKey));
serverChain[0] = serverCertGen.generateX509Certificate(serverPrivateKey, "BC"); // note: private key of CA
keyStore.setEntry("xyz",
new KeyStore.PrivateKeyEntry(serverPrivateKey, serverChain),
new KeyStore.PasswordProtection("".toCharArray()));
Hope this will help you.
Legacy Warning Begin:
This code only sets the CommonName/CN/Subject.
The correct place now is the SubjectAltName.
From Chrome Deprecates Subject CN Matching:
Chrome 58 will require that certificates specify the hostname(s) to which they apply in the SubjectAltName field; values in the Subject field will be ignored."
Legacy Warning End
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Date;
import sun.security.x509.CertAndKeyGen;
import sun.security.x509.X500Name;
public class UseKeyTool {
private static final int keysize = 1024;
private static final String commonName = "www.test.de";
private static final String organizationalUnit = "IT";
private static final String organization = "test";
private static final String city = "test";
private static final String state = "test";
private static final String country = "DE";
private static final long validity = 1096; // 3 years
private static final String alias = "tomcat";
private static final char[] keyPass = "changeit".toCharArray();
// copied most ideas from sun.security.tools.KeyTool.java
#SuppressWarnings("restriction")
public static void main(String[] args) throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, null);
CertAndKeyGen keypair = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
X500Name x500Name = new X500Name(commonName, organizationalUnit, organization, city, state, country);
keypair.generate(keysize);
PrivateKey privKey = keypair.getPrivateKey();
X509Certificate[] chain = new X509Certificate[1];
chain[0] = keypair.getSelfCertificate(x500Name, new Date(), (long) validity * 24 * 60 * 60);
keyStore.setKeyEntry(alias, privKey, keyPass, chain);
keyStore.store(new FileOutputStream(".keystore"), keyPass);
}
}

Sign data using PKCS #7 in JAVA

I want to sign a text file (may be a .exe file or something else in the future)
using PKCS#7 and verify the signature using Java.
What do I need to know?
Where will I find an API (.jar and documentation)?
What are the steps I need to follow in order to sign data and verify the data?
Please provide me code snippet if possible.
I reckon you need the following 2 Bouncy Castle jars to generate the PKCS7 digital signature:
bcprov-jdk15on-147.jar (for JDK 1.5 - JDK 1.7)
bcmail-jdk15on-147.jar (for JDK 1.5 - JDK 1.7)
You can download the Bouncy Castle jars from here.
You need to setup your keystore with the public & private key pair.
You need only the private key to generate the digital signature & the public key to verify it.
Here's how you'd pkcs7 sign content (Exception handling omitted for brevity) :
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.encoders.Base64;
public final class PKCS7Signer {
private static final String PATH_TO_KEYSTORE = "/path/to/keyStore";
private static final String KEY_ALIAS_IN_KEYSTORE = "My_Private_Key";
private static final String KEYSTORE_PASSWORD = "MyPassword";
private static final String SIGNATUREALGO = "SHA1withRSA";
public PKCS7Signer() {
}
KeyStore loadKeyStore() throws Exception {
KeyStore keystore = KeyStore.getInstance("JKS");
InputStream is = new FileInputStream(PATH_TO_KEYSTORE);
keystore.load(is, KEYSTORE_PASSWORD.toCharArray());
return keystore;
}
CMSSignedDataGenerator setUpProvider(final KeyStore keystore) throws Exception {
Security.addProvider(new BouncyCastleProvider());
Certificate[] certchain = (Certificate[]) keystore.getCertificateChain(KEY_ALIAS_IN_KEYSTORE);
final List<Certificate> certlist = new ArrayList<Certificate>();
for (int i = 0, length = certchain == null ? 0 : certchain.length; i < length; i++) {
certlist.add(certchain[i]);
}
Store certstore = new JcaCertStore(certlist);
Certificate cert = keystore.getCertificate(KEY_ALIAS_IN_KEYSTORE);
ContentSigner signer = new JcaContentSignerBuilder(SIGNATUREALGO).setProvider("BC").
build((PrivateKey) (keystore.getKey(KEY_ALIAS_IN_KEYSTORE, KEYSTORE_PASSWORD.toCharArray())));
CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").
build()).build(signer, (X509Certificate) cert));
generator.addCertificates(certstore);
return generator;
}
byte[] signPkcs7(final byte[] content, final CMSSignedDataGenerator generator) throws Exception {
CMSTypedData cmsdata = new CMSProcessableByteArray(content);
CMSSignedData signeddata = generator.generate(cmsdata, true);
return signeddata.getEncoded();
}
public static void main(String[] args) throws Exception {
PKCS7Signer signer = new PKCS7Signer();
KeyStore keyStore = signer.loadKeyStore();
CMSSignedDataGenerator signatureGenerator = signer.setUpProvider(keyStore);
String content = "some bytes to be signed";
byte[] signedBytes = signer.signPkcs7(content.getBytes("UTF-8"), signatureGenerator);
System.out.println("Signed Encoded Bytes: " + new String(Base64.encode(signedBytes)));
}
}
PKCS#7 is known as CMS now (Cryptographic Message Syntax), and you will need the Bouncy Castle PKIX libraries to create one. It has ample documentation and a well established mailing list.
I won't supply code snippet, it is against house rules. Try yourself first.

EC2 Windows - Get Administrator Password

Currently, the only way I know to retrieve the administrator password from a newly created EC2 windows instance is through the AWS management console. This is fine, but I need to know how to accomplish this via the Java API - I can't seem to find anything on the subject. Also, once obtained, how do I modify the password using the same API?
The EC2 API has a call "GetPasswordData" which you can use to retrieve an encrypted block of data containing the Administrator password. To decrypt it, you need 2 things:
First, the private key. This is the private half of the keypair you used to instantiate the instance. A complication is that normally Amazon uses keys in PEM format ("-----BEGIN"...) but the Java Crypto API wants keys in DER format. You can do the conversion yourself - strip off the -----BEGIN and -----END lines, take the block of text in the middle and base64-decode it.
Second, the encryption parameters. The data is encrypted with RSA, with PKCS1 padding – so the magic invocation to give to JCE is: Cipher.getInstance("RSA/NONE/PKCS1Padding")
Here's a full example (that relies on BouncyCastle, but could be modified to use a different crypto engine)
package uk.co.frontiertown;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.GetPasswordDataRequest;
import com.amazonaws.services.ec2.model.GetPasswordDataResult;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import javax.crypto.Cipher;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
public class GetEc2WindowsAdministratorPassword {
private static final String ACCESS_KEY = "xxxxxxxxxxxxxxxxxxxx";
private static final String SECRET_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
private static final String PRIVATE_KEY_MATERIAL = "-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIEowIBAAKCAQEAjdD54kJ88GxkeRc96EQPL4h8c/7V2Q2QY5VUiJ+EblEdcVnADRa12qkohT4I\n" +
// several more lines of key data
"srz+xXTvbjIJ6RL/FDqF8lvWEvb8uSC7GeCMHTznkicwUs0WiFax2AcK3xjgtgQXMgoP\n" +
"-----END RSA PRIVATE KEY-----\n";
public static void main(String[] args) throws GeneralSecurityException, InterruptedException {
Security.addProvider(new BouncyCastleProvider());
String password = getPassword(ACCESS_KEY, SECRET_KEY, "i-XXXXXXXX", PRIVATE_KEY_MATERIAL);
System.out.println(password);
}
private static String getPassword(String accessKey, String secretKey, String instanceId, String privateKeyMaterial) throws GeneralSecurityException, InterruptedException {
// Convert the private key in PEM format to DER format, which JCE can understand
privateKeyMaterial = privateKeyMaterial.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
privateKeyMaterial = privateKeyMaterial.replace("-----END RSA PRIVATE KEY-----", "");
byte[] der = Base64.decode(privateKeyMaterial);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(der);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
// Get the encrypted password data from EC2
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
AmazonEC2Client client = new AmazonEC2Client(awsCredentials);
GetPasswordDataRequest getPasswordDataRequest = new GetPasswordDataRequest().withInstanceId(instanceId);
GetPasswordDataResult getPasswordDataResult = client.getPasswordData(getPasswordDataRequest);
String passwordData = getPasswordDataResult.getPasswordData();
while (passwordData == null || passwordData.isEmpty()) {
System.out.println("No password data - probably not generated yet - waiting and retrying");
Thread.sleep(10000);
getPasswordDataResult = client.getPasswordData(getPasswordDataRequest);
passwordData = getPasswordDataResult.getPasswordData();
}
// Decrypt the password
Cipher cipher = Cipher.getInstance("RSA/NONE/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] cipherText = Base64.decode(passwordData);
byte[] plainText = cipher.doFinal(cipherText);
String password = new String(plainText, Charset.forName("ASCII"));
return password;
}
}
ObDisclosure: I originally answered this on a blog posting at http://www.frontiertown.co.uk/2012/03/java-administrator-password-windows-ec2-instance/
You can create an instance, set the password and then turn it back into an image. Effectively setting a default password for each instance you create. Wouldn't this be simpler?
Looks like you are looking for the following parts of the API: GetPasswordDataRequest and GetPasswordDataResult
You can also create a Image with default user name and Password setup on that Image.And then launch all instances with that image id..so that you dont need to create and retrieve password evry time..just launch your instance rdp that launched instance with definde credntials in Image. I am doing same.And its perfectly working for me.

Java: Invalid keystore format, when generated through code

This has been asked a couple of times, but none provide coded test cases. Here I give an example of the problem:
programmatic generation of a Keystore (works)
creation of certificate within that store (works)
saving keystore to disk (works)
listing keystore with keytool (works)
loading the keystore programmatically (fails with IOException: InvalidKeystoreFormat)
What I dont get is that in both save and load, I use KeyStore.getInstance("JKS"), but its failing. Any suggestions welcome!
Runtime output:
Creating private keystore at 'private.keystore'.
Created keystore, now created signer cert
Created signer cert, saving cert
Reloading keystore:
Failed to load the keystore after creation: Invalid keystore format
Test case source:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import sun.security.x509.X500Name;
public class KeystoreCreator
{
private String fPrivateKeyStore;
private String fPrivateKeyStorePassword;
private String fPrivateKeyStoreKeyPassword;
private String fPublicKeyCipherPassword;
private String fPrivateKeyAlias;
/**
* #param args
* #throws Exception
*/
public static void main(String[] args) throws Exception
{
KeystoreCreator creator = new KeystoreCreator();
creator.setPrivateKeyStore("private.keystore");
creator.setPrivateKeyStorePassword("beer123");
creator.setPrivateKeyAlias("myalias");
creator.setPrivateKeyStoreKeyPassword("beer123");
creator.setPublicKeyCipherPassword("beer123");
creator.initKeyStores();
}
public KeystoreCreator()
{
}
public void setPrivateKeyStore(String name)
{
fPrivateKeyStore=name;
}
public void setPrivateKeyStorePassword(String pass)
{
fPrivateKeyStorePassword=pass;
}
public void setPrivateKeyStoreKeyPassword(String pass)
{
fPrivateKeyStoreKeyPassword=pass;
}
public void setPublicKeyCipherPassword(String pass)
{
fPublicKeyCipherPassword=pass;
}
public void setPrivateKeyAlias(String alias)
{
fPrivateKeyAlias=alias;
}
public void initKeyStores() throws Exception
{
OutputStream out = null;
File f=new File(fPrivateKeyStore);
if (f.exists())
{
f.delete();
if (f.exists())
{
throw new IOException("Want to remove the keystore but can't, still reported as present after removal");
}
}
try
{
System.out.println("Creating private keystore at '" + fPrivateKeyStore + "'.");
out = new FileOutputStream(fPrivateKeyStore);
KeyStore privateKeyStore = KeyStore.getInstance("JKS");
privateKeyStore.load(null, fPrivateKeyStorePassword.toCharArray());
System.out.println("Created keystore, now created signer cert");
X500Name x500name=getCA();
Certificate cert = createCertificate(fPrivateKeyAlias, fPrivateKeyStoreKeyPassword, x500name, privateKeyStore);
System.out.println("Created signer cert, saving cert");
privateKeyStore.store(out, fPublicKeyCipherPassword.toCharArray());
out.flush();
out.close();
//try to load it.
KeyStore reloadedKeyStore = KeyStore.getInstance("JKS");
try
{
InputStream reloadedIs=getClass().getClassLoader().getResourceAsStream(fPrivateKeyStore);
if (reloadedIs!=null)
{
System.out.println("Reloading keystore:");
reloadedKeyStore.load(reloadedIs, fPrivateKeyStorePassword.toCharArray());
}
}
catch (Exception e)
{
System.err.println("Failed to load the keystore after creation: "+e.getLocalizedMessage());
}
}
catch (Exception e)
{
System.err.println("Failed to save the keystore: "+e.getLocalizedMessage());
}
}
private X500Name getCA() throws IOException
{
return new sun.security.x509.X500Name("a","b", "c","d","e", "GB");
}
public Certificate createCertificate( String alias, String keyPassword,
sun.security.x509.X500Name x500Name, KeyStore keyStore ) throws NoSuchAlgorithmException,
InvalidKeyException, CertificateException, SignatureException, NoSuchProviderException,
KeyStoreException {
sun.security.x509.CertAndKeyGen keypair = new sun.security.x509.CertAndKeyGen( "RSA", "MD5WithRSA" );
keypair.generate( 1024 );
PrivateKey privKey = keypair.getPrivateKey();
X509Certificate[] chain = new X509Certificate[1];
chain[0] = keypair.getSelfCertificate( x500Name, 7000 * 24 * 60 * 60 );
keyStore.setKeyEntry( alias, privKey, keyPassword.toCharArray(), chain );
Certificate cert = keyStore.getCertificate( alias );
return cert;
}
}
You create the private key store in the current working directory, by writing to a file: new FileOutputStream(fPrivateKeyStore);
Later, you read from the class path by using getClass().getClassLoader().getResourceAsStream(fPrivateKeyStore);
I think you're reading the wrong files. And there is already another one with the name private.keystore from previous tests. To verify, you may want to print out the absolute file path of both files, e.g. new File(fPrivateKeyStore).getAbsolutePath() and compare it to getClass().getClassLoader().getResource(fPrivateKeyStore).toFileURL();
I may be missing something, but why not just re-load the private key store using FileInputStream?
InputStream reloadedIs = new FileInputStream(fPrivateKeyStore);
(I'm not certain this fixes the problem, I just noticed it while scanning your code)

Categories

Resources