Accessing MSCAPI with JAVA 6 - Problem with identical aliases
Hi all,
I'm trying to access MS Windows keystore from JAVA. It works with the new JAVA 6 SunMSCAPI support.
But: I have three certificates in the MS store - all with the same 'alias'. The KeyStore.aliases() Enumeration gives me these three identical Strings, but afterwards I can not access a particular certificate as the only way to access them is by 'alias'....
Of course I could get the first Certificate and delete it from the store, then the next etc.. until I have found the one I need. But this is bad, because afterwards the certificates are not any more in the MS store.
Does any body know another possibility to access certificates in the keystore then accessing them by their alias ?
this is some sample code illustrating the problem:
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
for(java.util.Enumeration e = ks.aliases(); e.hasMoreElements(); ) {
String alias = (String)e.nextElement();
System.out.print(alias);
X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
System.out.println(" ,ID: "+cert.getSerialNumber().toString(16));
}
This gives (in my case) three identical Strings because I have three certificates in the store. When I access them and print out their serial nummer, I can see that always the same (the first) certificate is taken....
Thanks very much for any ideas !
[1446 byte] By [
BorisZa] at [2007-11-27 3:19:15]

# 3
One possible way is go through reflections, but its most ugly code in the universe.
Hey sun, its so easy! Add serial or hash to alias name or whatever else...
public static Object getField(Class cls, Object instance, String field) throws Exception {
Field[] flds = cls.getDeclaredFields();
for (int i = 0; i < flds.length; i++) {
Field fld = flds;
if (fld.getName().equals(field)) {
fld.setAccessible(true);
Object o = fld.get(instance);
return o;
}
}
throw new Exception("Field not found");
}
public static Object executeMethod(Object instance, String method) throws Exception {
Method[] methods = instance.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
Method met = methods;
if (met.getName().equals(method)) {
met.setAccessible(true);
Object result = met.invoke(instance, new Object[] {});
return result;
}
}
throw new Exception("Method not found");
}
/**
* @param args
*/
public static void main(String[] args) throws Exception {
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null);
// keystoreSpi
Object keystorespi = getField(ks.getClass(), ks, "keyStoreSpi");
// get entries
Collection entries = (Collection)getField(keystorespi.getClass().getSuperclass(), keystorespi, "entries");
for (Iterator iter = entries.iterator(); iter.hasNext(); ) {
Object entry = iter.next();
java.security.cert.X509Certificate[] x509s = (java.security.cert.X509Certificate[])executeMethod(entry, "getCertificateChain");
if (x509s != null) {
for (int i = 0; i < x509s.length; i++) {
X509Certificate x509 = (X509Certificate)x509s;
if ( i > 0 )
System.out.print(" ");
System.out.println(x509s.hashCode() + " " + x509.getSubjectDN());
}
System.out.println("");
}
}
}