Erste Zertifikate von PKCS11-Smartcard ohne PIN/Passwort
Abstract: wenn über JCA über PKCS11 über OpenSC, die PIN wird abgefragt, wenn das extrahieren von Zertifikaten.
Ich habe eine Anwendung, die Bedürfnisse anmelden mit einer smartcard. Die smartcard wird unterstützt von OpenSC, so bin ich mit der Java-built-in-pkcs11-wrapper-Anbieter zu verwenden. Aus funktionellen Gründen, die ich brauche zum abrufen der Zertifikate in die Karte, ohne einen PIN angefordert. Wenn der Benutzer schließlich Zeichen, dann, natürlich, die PIN benötigt wird.
Ich sehe, ich kann es von der Kommandozeile aus, ohne einen PIN:
pkcs11-tool --module C:\WINDOWS\system32\opensc-pkcs11.dll -r -a 50-MDS_Signature -y cert -o p.cer
Using slot 1 with a present token (0x1)
So weit, So gut.
In der Dokumentation von Oracle deutlich sagt: "Der generator wird nach einem Kennwort gefragt, wie erforderlich, unter Verwendung der zuvor konfigurierten callback-handler" (http://docs.oracle.com/javase/6/docs/technotes/guides/security/p11guide.html#Login). Aber mein code ist immer der pin als Sohn wie rufe ich KeyStore ks0 = ksbuilder0.getKeyStore();
sogar, während nur das extrahieren von öffentlichen Informationen (z.B. Zertifikate).
Folgt ein Auszug aus dem code:
private static final String PKCS11_LIB = "C:\\WINDOWS\\system32\\opensc-pkcs11.dll";
private static final String NAME = "OpenSCpkcs11";
private static final String SLOT = "1";
private static final String PIN = "11111111";
private static final String ALIAS = "myCert";
[...]
private static CallbackHandler myCallbackHandler = new CallbackHandler() {
@Override
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof PasswordCallback) {
PasswordCallback passwordCallback = (PasswordCallback) callback;
System.out.println(passwordCallback.getPrompt() + PIN);
passwordCallback.setPassword(PIN.toCharArray());
}
}
}
};
[...]
String configString = "name = "
+ NAME.replace(' ', '_')
+ "\n"
+ "library = "
+ PKCS11_LIB
+ "\n slot = "
+ SLOT
+ " "
+ "\n attributes = compatibility \n"
+ "attributes(*,*,*)=\n{\nCKA_TOKEN=true\nCKA_LOCAL=true\n}";
ByteArrayInputStream configStream = new ByteArrayInputStream(
configString.getBytes());
SunPKCS11 pkcs11Provider0 = new SunPKCS11(configStream);
pkcs11Provider0.login(null, myCallbackHandler);
Security.addProvider(pkcs11Provider0);
KeyStore.CallbackHandlerProtection chp = new KeyStore.CallbackHandlerProtection(
myCallbackHandler);
KeyStore.Builder ksbuilder0 = KeyStore.Builder.newInstance(
"PKCS11", pkcs11Provider0, chp);
KeyStore ks0 = ksbuilder0.getKeyStore();
X509Certificate cert0 = (X509Certificate) ks0.getCertificate(ALIAS);
//System.out.println("Cert " + cert0.toString());
Principal p = cert0.getSubjectDN();
System.out.println("I am: " + cert0.getSubjectDN().getName());
Es ergibt sich auf:
Contraseña de la tarjeta de claves PKCS11 [SunPKCS11-OpenSCpkcs11]: 11111111
2014-01-16 17:48:11.275 cannot lock memory, sensitive data may be paged to disk
I am: CN=pepe perez, SURNAME=pepe, L=qwerty
Wie Sie sehen können, das Passwort wird angefordert, bevor das Zertifikat bekam. Mittels Debuggen kann ich sehen, dass das Passwort angefordert wird, in der Zeile KeyStore ks0 = ksbuilder0.getKeyStore();
Irgendeine Idee? Gibt es keine Möglichkeit, es zu konfigurieren, wie ich will? Jede weitere Idee oder test?
Außerdem: kennen Sie eine andere Möglichkeit zum Zugriff auf smartcards, zum Beispiel direkt durch ein JAVA2OpenSC wrapper oder wie?
Dank,
Du musst angemeldet sein, um einen Kommentar abzugeben.
GELÖST
Habe ich einen Weg gefunden, um das öffentliche Zertifikat von der smart card.
KeyStore.load() sollte mit PaswordProtection Objekt mit leer-pin.
Dies ermöglicht mir, zu Lesen, das öffentliche Zertifikat und extrahieren Sie die Daten aus es.
Habe ich getestet mit 3 verschiedenen Arten von smart-Karten und es funktioniert auf allen von Ihnen
Gut, was ich schon einmal getan, war so etwas wie
Pkcs.cfg ist eine Datei, zeigen auf die "libpteidpkcs11.also" Bibliothek und Sie sollten in der Lage sein, um eine Anpassung an den code. Meins liest:
load(null, null)
wirftjavax.security.auth.login.LoginException: no password provided, and no callback handler available for retrieving password
Schließlich gab es keine Lösung über JCA. Die endgültige Lösung war, die direkt angreifen, die PKCS11 Treiber. Ich habe verwendet, jacknji11 (https://github.com/joelhockey/jacknji11) und die PKCS11-spec (http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-11-cryptographic-token-interface-standard.htm).
Andere Möglichkeit ist die Verwendung IAIK-PKCS#11-Wrapper. JavaDoc hier. Beispiel-code unten.