Obtaining public key from certificate - java

I'm trying to obtain the public key of a Certificate using the method:
FileInputStream fin = new FileInputStream("PathToCertificate");
CertificateFactory f = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
PublicKey pk = certificate.getPublicKey();
but I receive the following error:
Exception in thread "main" java.lang.ClassCastException: sun.security.x509.X509CertImpl cannot be cast to codec.x509.X509Certificate
at sergas_testcertificates.Main.main(Main.java:54)
Does anyone know what this error is about?
Thanks in advance

You have the wrong class imported for X509Certificate.
You are likely looking for java.security.cert.X509Certificate not codec.x509.X509Certificate.

X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
PublicKey pk = certificate.getPublicKey();
since you are only pulling the public key, you can use the certificate class. The factory class will decide what type of a certificate to return.
Certificate certificate = f.generateCertificate(fin);
PublicKey pk = certificate.getPublicKey();
If you need to cast this for antoher reason, check your imports and change it, X509Certificate should be coming from javax.security.cert

Related

PEMParser bouncy castle read certificate and private key from PEM

I have created a PEMParser object to which I pass a PEM string containing chain certificate, encrypted private key etc. Which is the way to retrieve the decrypted private key and the certificate X509? I have tried with :
pemParser.readObject()
I am able to get a x509CertificateHolder (how to get the certificate from it?) and at the second call an encrypted privatekey info.
Thanks in advance.
assuming that your pem file has two entries first is cert and second is key.
another assumption is that key is of type pkcs8 and it is password protected.
first call to pemParser.readObject() is done with assumption that first entry in pem file is of x509 certificate
second call to pemParser.readObject() is done with assumption that second entry in pem file is of pkcs8 password protected key
variable certificate will contain the x509 certificate and variable finalKey will contain the private key
private void getCertAndKeyFromPemFile(String fileName, String keyPassword) throws Exception {
Security.addProvider(new BouncyCastleProvider());
PEMParser pemParser = new PEMParser(new FileReader(fileName));
JcaX509CertificateConverter x509Converter = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider());
X509Certificate certificate =x509Converter.getCertificate((X509CertificateHolder) pemParser.readObject());
PKCS8EncryptedPrivateKeyInfo privateKeyInfo = (PKCS8EncryptedPrivateKeyInfo) pemParser.readObject();
InputDecryptorProvider decryptorProvider = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(keyPassword.toCharArray());
PrivateKey finalKey = new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo.decryptPrivateKeyInfo(decryptorProvider));
}

Digital Signature for Acrobat

Trying to get an authenticated digital signature onto a PDF in Acrobat, by using iText. The way we want to grab someone digital signature is through there cert, which in our case we would be getting the user cert through their CAC's. Having issue with the ks.load() where I am getting an error: "Invalid key store format". Wonder if it is even possible without using any cmd? Would prefer a solution that involves Java.
String KEYSTORE = ReadConfig.get("WebRoot")+"mods/Reports/sources/t_cert.jks";
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(KEYSTORE), null);
String alias = (String) ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, null);
Certificate[] chain = ks.getCertificateChain(alias);

Verifying POI Digital signature

I have recently implemented digital signing and validation of office documents using the apache POI library. I am now looking to add verification to this so I can prove that the document was signed by a trusted user. I have tried the following code but with no success I think as the call to "getSigningCertificateChain" is empty but im not sure how to get this to load properly so the signature will be there? this is my current code:
pkg = OPCPackage.open(Dir, PackageAccess.READ);
sic = new SignatureConfig();
sic.setOpcPackage(pkg);
SignatureInfo si = new SignatureInfo();
si.setSignatureConfig(sic);
isValid = si.verifySignature();
X509Certificate x509a = (X509Certificate) sic.getSigningCertificateChain().get(0);
FileInputStream fin = new FileInputStream("C:\myCer.cer");
CertificateFactory f = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
PublicKey pk = certificate.getPublicKey();
x509a.verify(pk);
anyone had any luck with implementing this.
You have to select the certificate from the chain based on the issuer Common Name = {myCer.cer} Common Name, then try to verify it
PublicKey pk = selectedIssuedCertificate.getPublicKey();
x509a.verify(pk);
I hope this could help

Reading certificate error

I am getting the following exception when running my application in a different server. The code works in two different tomcat servers, but on a specific one it doesn't work.
java.lang.NoClassDefFoundError:
org/bouncycastle/asn1/pkcs/PrivateKeyInfo
org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi.engineGeneratePrivate(Unknown
Source) java.security.KeyFactory.generatePrivate(KeyFactory.java:372)
The part of the code when I am getting the error is the following on this line
> pk = kf.generatePrivate(ks);
PrivateKey pk = null;
X509Certificate cert = null;
Security.addProvider(new BouncyCastleProvider());
try{
byte [] key = Base64.decodeBase64(llave.getBytes());
byte [] cer = Base64.decodeBase64(certificado.getBytes());
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(key);
pk = kf.generatePrivate(ks);
pk.getEncoded();
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(cer);
cert = (X509Certificate)certFactory.generateCertificate(in);
DateTime fechaDesde = new DateTime(cert.getNotBefore());
DateTime fechaHasta = new DateTime(cert.getNotAfter());
Does somebody knows why this happens?
java.lang.NoClassDefFoundError This exception is thrown when JVM is unable to find a particular class at runtime which was available during compile time.
This link will help you

Providing Key Usage to X509Certificate generated with Java BouncyCastle

Here is my piece of code to for generating X509Certificate with BouncyCastle API
private static X509Certificate createCertificate(String dn, String issuer,
PublicKey publicKey, PrivateKey privateKey) throws Exception {
X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
certGenerator.setSerialNumber(BigInteger.valueOf(Math.abs(new Random()
.nextLong())));
certGenerator.setIssuerDN(new X509Name(dn));
certGenerator.setSubjectDN(new X509Name(dn));
certGenerator.setIssuerDN(new X509Name(issuer)); // Set issuer!
certGenerator.setNotBefore(Calendar.getInstance().getTime());
certGenerator.setNotAfter(Calendar.getInstance().getTime());
certGenerator.setPublicKey(publicKey);
certGenerator.setSignatureAlgorithm("SHA1WithRSAEncryption");
**certGenerator..... ??? what for key usage ?**
X509Certificate certificate = (X509Certificate) certGenerator.generate(
privateKey, "BC");
return certificate;
}
Full code you can see here
My question is there is no way to set the key usage for the generated Digital Certificate.
I am trying to set the usage as Encryption.. There is no such method/way in X509V3CertificateGenerator class.
How to go about it.
Thanks for any hints.

Categories

Resources