2013-03-19 15 views
7

Der folgende Code erstellt einen Client authentifizierten SSL-Kontext mit PKCS # 11-Gerät (Smartcard). Das alles funktioniert gut mit Java 6:SSL-Client-Authentifizierung mit Smartcard funktioniert in Java 6, schlägt aber in Java fehl 7

// Configure the SunPkcs11 provider 
String pkcs11config; 
pkcs11config = "name = Cryptoki"; 
pkcs11config += "\nlibrary = /SCDriver/libbit4ipki.dylib"; 
InputStream confStream = new ByteArrayInputStream(pkcs11config.getBytes()); 
SunPKCS11 sunpkcs11 = new SunPKCS11(confStream); 
Security.addProvider(sunpkcs11); 

// Specify keystore builder parameters for PKCS#11 keystores 
Builder scBuilder = Builder.newInstance("PKCS11", sunpkcs11, new KeyStore.CallbackHandlerProtection(new PasswordRetriever())); 

// Create and init KeyManagerFactory 
KeyManagerFactory factory = KeyManagerFactory.getInstance("NewSunX509"); 
factory.init(new KeyStoreBuilderParameters(scBuilder)); 

// create and init ssl context 
m_ssl_context = SSLContext.getInstance("TLS"); 
m_ssl_context.init(factory.getKeyManagers(), new TrustManager[] {new PkTrustManager()}, null);  
SSLContext.setDefault(m_ssl_context); 

Die PkTrustManager ist einfach und ‚leere‘ Klasse, wobei jeder Server/Client-Zertifikat für gute und PasswordRetriever fragt nur für Passwort über ein Dialogfeld (Auf Wunsch poste ich Quellcode für diese). Auf Java 7 statt ich die folgende Ausnahme während der SSL-Handshake des ssl Kontextes erhalten:

java.security.InvalidKeyException: Class does not represent an RSA key: sun.security.pkcs11.P11Key$P11PrivateKey 
    at iaik.pkcs.pkcs1.RSACipher.engineInit(Unknown Source) 
    at iaik.pkcs.pkcs1.RSACipher.engineInit(Unknown Source) 
    at iaik.security.rsa.RSA.init(Unknown Source) 
    at iaik.security.rsa.RawRSASignature.engineInitSign(Unknown Source) 
    at java.security.SignatureSpi.engineInitSign(SignatureSpi.java:103) 
    at java.security.Signature.initSign(Signature.java:529) 
    at sun.security.ssl.RSASignature.engineInitSign(RSASignature.java:125) 
    at java.security.Signature$Delegate.engineInitSign(Signature.java:1136) 
    at java.security.Signature.initSign(Signature.java:529) 
    at sun.security.ssl.HandshakeMessage$CertificateVerify.<init>(HandshakeMessage.java:1556) 
    at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:982) 
    ... 14 more 

Im besten Fall würde ich sagen, etwas in Java Interna geändert hat, aber die Oracle-Dokumentation Überprüfung, I didn‘ t irgendwelche vermuteten Änderungen auf dem NewSunX509-Schlüsselmanager oder anderen Komponenten finden. Ich habe den Code überprüft und es scheint konform zu den Spezifikationen (durch dort ist sicher etwas, was ich verpasst habe!).

Ich habe versucht, die Konfigurationsflags hinzuzufügen:

System.setProperty("javax.net.ssl.keyStoreType", "pkcs11"); 
System.setProperty("javax.net.ssl.keyStore", "NONE"); 
System.setProperty("javax.net.ssl.trustStoreType", "pkcs11"); 
System.setProperty("javax.net.ssl.trustStore", "NONE"); 
System.setProperty("javax.net.ssl.keyStoreProvider", sunpkcs11.getName()); 
JCEMapper.setProviderId(sunpkcs11.getName()); 

Aber keine Veränderung, gleiche Fehler ... und sie sind nicht in Java 6, in der alle Arbeiten erforderlich. Vielen Dank im Voraus kann jeder helfen oder hat Ideen!

PS: Auf Wunsch von @owlstead hinzugefügt -Djava.security.debug = sunpkcs11 und bekam die folgende Ausgabe:

SunPKCS11 loading ---DummyConfig-1--- 
sunpkcs11: Initializing PKCS#11 library /SCDriver/libbit4ipki.dylib 
Information for provider SunPKCS11-Cryptoki 
Library info: 
    cryptokiVersion: 2.20 
    manufacturerID: bit4id srl      
    flags: 0 
    libraryDescription: bit4id PKCS#11     
    libraryVersion: 1.02 
All slots: 0 
Slots with tokens: 0 
Slot info for slot 0: 
    slotDescription: bit4id miniLector-U38 00 00          
    manufacturerID: unknown       
    flags: CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT 
    hardwareVersion: 0.00 
    firmwareVersion: 0.00 
Token info for token in slot 0: 
    label: CNS        
    manufacturerID: ST Incard      
    model: CNS (LB)   
    serialNumber: 7420057800291590 
    flags: CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED 
    ulMaxSessionCount: CK_EFFECTIVELY_INFINITE 
    ulSessionCount: 0 
    ulMaxRwSessionCount: CK_EFFECTIVELY_INFINITE 
    ulRwSessionCount: CK_UNAVAILABLE_INFORMATION 
    ulMaxPinLen: 8 
    ulMinPinLen: 5 
    ulTotalPublicMemory: 31988 
    ulFreePublicMemory: CK_UNAVAILABLE_INFORMATION 
    ulTotalPrivateMemory: 780 
    ulFreePrivateMemory: CK_UNAVAILABLE_INFORMATION 
    hardwareVersion: 0.00 
    firmwareVersion: 0.00 
    utcTime: 0000000000000000 
Mechanism CKM_RSA_PKCS: 
    ulMinKeySize: 1024 
    ulMaxKeySize: 1024 
    flags: 2561 = CKF_HW | CKF_DECRYPT | CKF_SIGN 
Mechanism CKM_RSA_PKCS_KEY_PAIR_GEN: 
    ulMinKeySize: 1024 
    ulMaxKeySize: 1024 
    flags: 65537 = CKF_HW | CKF_GENERATE_KEY_PAIR 
Mechanism CKM_SHA1_RSA_PKCS: 
    ulMinKeySize: 1024 
    ulMaxKeySize: 1024 
    flags: 2049 = CKF_HW | CKF_SIGN 
Mechanism CKM_SHA_1: 
    ulMinKeySize: 0 
    ulMaxKeySize: 0 
    flags: 1024 = CKF_DIGEST 
Mechanism CKM_SHA256: 
    ulMinKeySize: 0 
    ulMaxKeySize: 0 
    flags: 1024 = CKF_DIGEST 
Mechanism CKM_SHA256_RSA_PKCS: 
    ulMinKeySize: 1024 
    ulMaxKeySize: 1024 
    flags: 2049 = CKF_HW | CKF_SIGN 
Mechanism CKM_SHA384: 
    ulMinKeySize: 0 
    ulMaxKeySize: 0 
    flags: 1024 = CKF_DIGEST 
Mechanism CKM_SHA384_RSA_PKCS: 
    ulMinKeySize: 1024 
    ulMaxKeySize: 1024 
    flags: 2049 = CKF_HW | CKF_SIGN 
Mechanism CKM_SHA512: 
    ulMinKeySize: 0 
    ulMaxKeySize: 0 
    flags: 1024 = CKF_DIGEST 
Mechanism CKM_SHA512_RSA_PKCS: 
    ulMinKeySize: 1024 
    ulMaxKeySize: 1024 
    flags: 2049 = CKF_HW | CKF_SIGN 
Mechanism CKM_RSA_X_509: 
    ulMinKeySize: 1024 
    ulMaxKeySize: 1024 
    flags: 2561 = CKF_HW | CKF_DECRYPT | CKF_SIGN 
Password per token PKCS11 [SunPKCS11-Cryptoki]: sunpkcs11: login succeeded 
sunpkcs11: user already logged in 
javax.net.ssl.SSLHandshakeException: Error signing certificate verify 
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) 
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886) 
    *....... (continues with the exception as described above)* 

Hinweis: Mit dem letzten Update von Java 6, mein Code nicht mehr funktioniert auf als auch Java 6 :(

+0

Können Sie versuchen, '-Djava.security.debug = sunpkcs11' an die Java VM-Befehlszeile zu senden und die Ausgabe zu posten? –

+0

Hallo @owlstead, ich habe getan, wie Sie gefragt haben: In der Nachricht ist die angeforderte Ausgabe (das Signaturzertifikat, das ich zu verwenden versuche, ist SHA256withRSA). – FrizzTheSnail

+0

Kann nichts falsch sehen, vielleicht ist es eine Art von Miss zwischen der 'sun.security.pkcs11.P11Key $ P11PrivateKey' Klasse und dem Open Source IAIK PKCS # 11 Wrapper, den sie benutzt haben, um den PKCS # 11 Provider zu implementieren. Aber das würde einen Fehler darstellen. Vielleicht möchten Sie es als solches melden und sehen, was passiert. –

Antwort

7

Gelöst durch die Codezeile hinzu:

Security.removeProvider("IAIK"); 

vor der Zeile:

Security.addProvider(sunpkcs11); 

Dies funktioniert korrekt mit allen Versionen von java6 und Java7 (in der Hoffnung sie nicht wieder etwas in java8 Schraube wird ... :)

wie der Anbieter fügt IAIK Sieht sich als Der PKCS11-Provider ruft dann jedoch den privaten Schlüssel als Softwareschlüssel an, da es sich tatsächlich um einen Softwareanbieter handelt.

+0

Ja, das ist der Grund. Bei genauer Betrachtung Ihres StackTrace können Sie 'at iaik.pkcs.pkcs1.RSACipher.engineInit (Unknown Source)' sehen. Meine hat das gleiche Problem, nur mit einem anderen Anbieter, "Entrust". Entfernen Sie diesen Anbieter. – FaithReaper

Verwandte Themen