Java: Get X509Certificate Issuers - java

Hi i have this certificate(X509Certificate) but i need to get all the issuers of it, for example:
the certification path of the certificate is
-CA NATIONAL ROOT - Costa Rica
--CA NATURAL PERSON POLITICS - Costa Rica
---CA SINPE - NATURAL PERSON
----MARIO XXXXX XXXXXX (SIGN) --->
---> This is what i have, but i need to access the top issuer till reach the root(CA NATIONAL ROOT - Costa Rica), because i need to compare the name of the first issuer and other data, with some parameters. How do i accomplish this or where should i start?

KeyStore ks = KeyStore.getInstance("pkcs12");
//FileInputStream fis = new FileInputStream("C://Users//youtube//Documents//workspace//PublicKey02//archivo//archivo.p12");
//ks.load(fis, "passwordp12file".toCharArray());
ks.load(new FileInputStream("archivo//llave_criptografica.p12"), "su-password".toCharArray());
/*Enumeration<String> e = ks.aliases();
while (e.hasMoreElements()) {
String param = e.nextElement();
System.out.println(param);
}*/
//System.out.println(ks.containsAlias("myKey"));
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("2cba9e2d-6ec2-435e-b1bc-5fd9fe5afcac", new KeyStore.PasswordProtection("su-password".toCharArray()));

Related

How can I set the value of TBScertificate::signiture during I generate a X509cert with java?

I'm going to generate a cert and set this value:
TBSCertificate::=SEQUENCE{
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,***<---this one***
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
extensions [3] EXPLICIT Extensions OPTIONAL
}
this is my code,right now I can only set SerialNumber,IssuerDN,NotBefore,NotAfter,SubjectDN,PublicKey,SignatureAlgorithm,:
public X509Certificate generateCert(String[] info, KeyPair keyPair_root,KeyPair keyPair_user) throws InvalidKeyException, NoSuchProviderException, SecurityException, SignatureException {
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
X509Certificate cert = null;
certGen.setSerialNumber(new BigInteger(info[8]));
certGen.setIssuerDN(new X509Name(
"CN=huahua, OU=hnu, O=university , C=china"));
certGen.setNotBefore(new Date(Long.parseLong(info[6])));
certGen.setNotAfter(new Date(Long.parseLong(info[7])));
certGen.setSubjectDN(new X509Name("C=" + info[0] + ",OU=" + info[1]
+ ",O=" + info[2] + ",C=" + info[3] + ",L=" + info[4] + ",ST="
+ info[3]));
certGen.setPublicKey(keyPair_user.getPublic());
certGen.setSignatureAlgorithm("SHA1WithRSA");
cert = certGen.generateX509Certificate(keyPair_root.getPrivate(), "BC");
return cert;
}
I will be appreciate it if any one could help me!I have find many solutions but none of them can help me.
TBSCertificate.signature is named poorly, it isn't a signature, just the signature algorithm identifier.
This value is presumably controlled by certGen.setSignatureAlgorithm(...), which you're already using.

Update/Delete Certificate chain: Cannot assign the key to the given alias

I want to update my previous self-signed certificate with new one eg: chains which is returned (signed CSR) from TEST CA. My default keystore is: Windows-MY
Step 1: I have created a private-public key pair, self-signed
certifcate and CSR(private key is stored in Windows-MY with
self-signed certificate).
Step 2: sent CSR to CA.
Step 3: CA returns a certificate chain for that public key.
Now I want to replace that self-signed certificate with the CA returned certificate. NB: I have the private key stored in my store.
Key privKey = keyStore.getKey(commonName, keyPass);
System.out.println("invalid private key :" + (privKey == null));
// keyStore.deleteEntry(commonName);
// keyStore.load(null, keyPass);
if (isPrivateKeyAvailable) {
System.out.println("name:" + commonName + " is updatded");
keyStore.setKeyEntry(commonName, privKey, keyPass, chains);
} else {
System.out.println("name:" + commonName + " does not exist");
}
But I am getting these errors:
java.lang.UnsupportedOperationException: Cannot assign the key to the
given alias. at
sun.security.mscapi.KeyStore.engineSetKeyEntry(KeyStore.java:415) at
sun.security.mscapi.KeyStore$MY.engineSetKeyEntry(KeyStore.java:55)
at java.security.KeyStore.setKeyEntry(Unknown Source) at
keygenerator.KeyInstaller.installCertificateInWindowsStore(KeyInstaller.java:284)
at keygenerator.KeyInstaller.doJob(KeyInstaller.java:167) at
keygenerator.KeyGeneration.installCertificate(KeyGeneration.java:171)
at keygenerator.KeyGeneration.main(KeyGeneration.java:68)
Windows keystore (named Windows-MY from Java) is not directly writable. You need to pack the private key and the certificate chain returned by CA into a PKCS#12 file (.p12) and import it using The Windows import tool.

Issue with Generating self-signed Certificate(X509), Private and Public key in Java Programatically

I am facing issues when i tried generating the certificate using BouncyCastle or Sun.Security.*
Requirements-
Android API support - For API 15 and API 8
I tried following ways to do it..
1) I tried using BouncyCastle jar with the following code
X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
v3CertGen.setSerialNumber(BigInteger.valueOf(new SecureRandom().nextInt()));
v3CertGen.setIssuerDN(new X509Principal("CN=" + domainName + ", OU=None, O=None L=None, C=None"));
v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30));
v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365*10)));
v3CertGen.setSubjectDN(new X509Principal("CN=" + domainName + ", OU=None, O=None L=None, C=None"));
//
v3CertGen.setPublicKey(KPair.getPublic());
v3CertGen.setSignatureAlgorithm("MD5WithRSAEncryption");
X509Certificate PKCertificate = v3CertGen.generateX509Certificate(KPair.getPrivate());
issues faced with this code:
CertificateGenerator is depricated
X509V3CertificateGenerator class is not identified
tried with different versions of bouncycastle jars (1.45, 1.46, 1.47 & 1.57)
tried using CertificateBuilder (code is below)
SubjectPublicKeyInfo this class is not identified when i used this code.
SubjectPublicKeyInfo publicKeyInfo =
SubjectPublicKeyInfo.getInstance(kp.getPublic().getEncoded());
X509v3CertificateBuilder myX509v3CertificateBuilder = new X509v3CertificateBuilder(new X500Name("c=sree"), BigInteger.valueOf(new Random().nextInt(1000000)), new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 *365 * 100)), new X500Name("c=sree"), publicKeyInfo);
ContentSigner signer = new JcaContentSignerBuilder("Sha256withRSA").build(myCAPrivateKey);
X509CertificateHolder certHolder = myX509v3CertificateBuilder.build(signer);
X509Certificate cert = (new JcaX509CertificateConverter().getCertificate(certHolder));
CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
Certificate certcert = cf.generateCertificate(new ByteArrayInputStream(cert.getEncoded()));
2) I tried with Sun.Security.* package with the below code
import java.security.cert.X509Certificate;
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.X500Name;
public class SelfSignedCertificateGeneration {
public static void main(String[] args){
try{
CertAndKeyGen keyGen=new CertAndKeyGen("RSA","SHA1WithRSA",null);
keyGen.generate(1024);
//Generate self signed certificate
X509Certificate[] chain=new X509Certificate[1];
chain[0]=keyGen.getSelfCertificate(new X500Name("CN=ROOT"), (long)365*24*3600);
System.out.println("Certificate : "+chain[0].toString());
}catch(Exception ex){
ex.printStackTrace();
}
}
}
Issues faced with this code:
CertAndKeyGen and few other class are not accessible
**
Is there any other way? please suggest me.
**
Old versions of android are shipped with a cut-down version of bouncycastle. So you can not trust that the functionality you need is complete. Try to include https://rtyley.github.io/spongycastle/, a repackage of Bouncy Castle for Android.
Specify dependencies in gradle
compile 'com.madgag.spongycastle:core:1.56.0.0'
compile 'com.madgag.spongycastle:prov:1.56.0.0'
compile 'com.madgag.spongycastle:pkix:1.56.0.0'
compile 'com.madgag.spongycastle:pg:1.56.0.0'
Package names have changed from org.bouncycastle.* to org.spongycastle.* and provider name from BC to SC
Here you have an example of using spongycastle to create a selfsigned certificate

Undefined CommonName in certificate

So far, I've been working with a certificate which I added to a SoapUI 5.2 project and which gave me access to a pre-production server. However, now that I'm ready to move to a production environment, I'm trying to check the new production certificate with SoapUI, but I'm getting the next error:
WARN:Using fallback method to load keystore/truststore due to: Invalid keystore format
ERROR:An error occurred [java.lang.NullPointerException], see error log for details
And the error log says:
ERROR:Could not load keystore/truststore
ERROR:java.lang.NullPointerException
java.lang.NullPointerException
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:176)
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:97)
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:88)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.fallbackLoad(KeyMaterialWssCrypto.java:206)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.load(KeyMaterialWssCrypto.java:168)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.getStatus(KeyMaterialWssCrypto.java:216)
at com.eviware.soapui.impl.wsdl.panels.project.WSSTabPanel$CryptoTableModel.getValueAt(WSSTabPanel.java:643)
at javax.swing.JTable.getValueAt(Unknown Source)
at javax.swing.JTable.prepareRenderer(Unknown Source)
...
The only difference I found between the pre-production and production certificates was that the latter did not have the CommonName field defined.
I know that field is not mandatory, so how is that possible? How can I solve this problem without asking for a new certificate? That's not an option.
Any suggestion would be appreciated.
I check the pom.xml of SOAPUI project for 5.2 versión, and it use not-yet-commons-ssl versión 0.3.11:
<dependency>
<groupId>commons-ssl</groupId>
<artifactId>not-yet-commons-ssl</artifactId>
<version>0.3.11</version>
</dependency>
And If you check the build method for org.apache.commons.ssl.KeyStoreBuilder class as the exception thrown in your error log you'll see:
public static KeyStore build(byte[] jksOrCerts, byte[] privateKey,
char[] jksPassword, char[] keyPassword)
throws IOException, CertificateException, KeyStoreException,
NoSuchAlgorithmException, InvalidKeyException,
NoSuchProviderException, ProbablyBadPasswordException,
UnrecoverableKeyException {
...
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, jksPassword);
Iterator keysIt = keys.iterator();
Iterator chainsIt = chains.iterator();
int i = 1;
while (keysIt.hasNext() && chainsIt.hasNext()) {
Key key = (Key) keysIt.next();
Certificate[] c = (Certificate[]) chainsIt.next();
X509Certificate theOne = buildChain(key, c);
String alias = "alias_" + i++;
// The theOne is not null, then our chain was probably altered.
// Need to trim out the newly introduced null entries at the end of
// our chain.
if (theOne != null) {
c = Certificates.trimChain(c);
alias = Certificates.getCN(theOne);
/* line 176 */ alias = alias.replace(' ', '_');
}
ks.setKeyEntry(alias, key, keyPassword, c);
}
return ks;
}
}
So seems that you're right and the problem is that your certificate has no common name, so org.apache.commons.ssl.Certificates.getCN(X509Certificate) returns null as alias and then alias.replace is throwing the NPE.
alias = Certificates.getCN(theOne);
/* line 176 */ alias = alias.replace(' ', '_');
I don't see nothing that says that Common Name is mandatory in RFC5280, however various code/software use it for different purposes as not-yet-commons-ssl does.
Your certificate is probably right but you can't use it with SOAPUI 5.2 version to test your environment if it hasn't the CN, so if you want to use SOAPUI to test your environment I think that you've to reissue the certificate generating a CSR with CN. Or you can report the problem to http://juliusdavies.ca/commons-ssl/ and then ask to SOAPUI to include the latest version...
Hope this helps,

Bouncy Castle i cannot get all certificate

I'm trying to read certificate from smime.p7s file, the certificate chain is:
Baltimora Cyber Trust --> DigitPA --> Aruba PEC
So when i'm trying to extract, I retrieve only the last two certificate, the last like subject and the first like issuer.
What am I wrong?
the code:
private List<CertificateInfo> reading(ASN1InputStream asn1Stream) throws IOException, CMSException, CertificateException {
ArrayList<CertificateInfo> infos = new ArrayList<CertificateInfo>();
ASN1Primitive obj = asn1Stream.readObject();
ContentInfo contentInfo = ContentInfo.getInstance(obj);
CMSSignedData cms = new CMSSignedData(contentInfo);
JcaX509CertificateConverter converter = new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
Store store = cms.getCertificates();
SignerInformationStore signersInfoStore = cms.getSignerInfos();
Collection<SignerInformation> signers = signersInfoStore.getSigners();
logger.debug("signers num [" + signers.size() + "]");
for (SignerInformation si : signers) {
SignerId sid = si.getSID();
Collection<X509CertificateHolder> holders = store.getMatches(sid);
logger.debug("holders num [" + holders.size() + "]");
for (X509CertificateHolder certholder : holders) {
X509Certificate cert = converter.getCertificate(certholder);
logger.debug("Issuer [" + cert.getPublicKey() + "]");
CertificateInfo certInfo = util.parse(cert);
infos.add(certInfo);
}
}
return infos;
}
I'm using these bouncy castle jar like dependecies:
<dependency>
<groupId>bouncycastle</groupId>
<artifactId>bcprov-jdk15</artifactId>
<version>150</version>
</dependency>
<dependency>
<groupId>bouncycastle</groupId>
<artifactId>bcmail-jdk15</artifactId>
<version>150</version>
</dependency>
<dependency>
<groupId>bouncycastle</groupId>
<artifactId>bcpg-jdk15</artifactId>
<version>150</version>
</dependency>
<dependency>
<groupId>bouncycastle</groupId>
<artifactId>bcpkix-jdk15</artifactId>
<version>150</version>
</dependency>
thanks in advance.
Probably nothing is wrong. PKI works with a tree-like structure. It is possible to trust Aruba PEC using DigitPA. But how can you trust DigitPA? The most common method is to store the root certificate in a trust store. This trust store is e.g. distributed by the application (like the trust store within web browsers).
Now if the Baltimora Cyber Trust is already in the trust store, there is no need to send it within the PKCS#7 container. The certificate chain can be constructed to the trusted root without it.
So you either read the cert from the trust store directly, or you retrieve the root cert from the certificate chain created for verification.

Categories