2010-08-31 5 views
4

Возможно ли получить доступ к сертификатам, хранящимся в хранилище локального компьютера (а не к текущему пользователю) из Java Servlet? Я пробовал использовать провайдер MSCAPI, открывая магазины «Windows-MY» и «Windows-ROOT», но ни один из них не содержит сертификатов из хранилища Local Machine.Доступ к локальному хранилищу сертификатов в Java?

+0

Вы достигли того, чего хотели? У меня такая же проблема, и мне не повезло. – skw

+0

@skw Нет, я никогда не мог получить локальные сертификаты машины из чистой Java, я в конечном итоге использовал провайдера Entrust (который выполняет вызов JNI) для получения необходимых мне сертификатов. –

+0

Спасибо за ваш ответ. Жаль, что это не родной Java. Я думаю, что это может быть проблема безопасности. – skw

ответ

-1

сертификатов вы ищете в файле Java хранилища ключей или передаются в кот при запуске сервера

http://tomcat.apache.org/tomcat-4.0-doc/ssl-howto.html

, если вы пытаетесь загрузить их в приложении, а затем посмотреть здесь, чтобы делать запросы HTTPS, то документация HTTPClient поможет вам начать работу

http://www.jdocs.com/httpclient/3.0.1/api-index.html?m=class&p=org.apache.commons.httpclient.contrib.ssl&c=AuthSSLProtocolSocketFactory&render=classic

не уверен, если это поможет, но если вы можете предоставить больше д то вы могли бы получить более конкретный ответ

public class KeyStoreLookup { 
    public static void main(String args[]) { 
     try { 
      KeyStore ks = 
         KeyStore.getInstance(KeyStore.getDefaultType()); 
      String fname = System.getProperty("user.home") + 
           File.separator + ".keystore"; 
      FileInputStream fis = new FileInputStream(fname); 
      ks.load(fis, null); 
      if (ks.isKeyEntry(args[0])) { 
       System.out.println(args[0] + 
           " is a key entry in the keystore"); 
       char c[] = new char[args[1].length()]; 
       args[1].getChars(0, c.length, c, 0); 
       System.out.println("The private key for" + args[0] + 
          " is " + ks.getKey(args[0], c)); 
       Certificate certs[] = ks.getCertificateChain(args[0]); 
       if (certs[0] instanceof X509Certificate) { 
        X509Certificate x509 = (X509Certificate) certs[0]; 
        System.out.println(args[0] + " is really " + 
         x509.getSubjectDN()); 
       } 
       if (certs[certs.length - 1] instanceof 
            X509Certificate) { 
        X509Certificate x509 = (X509Certificate) 
             certs[certs.length - 1]; 
        System.out.println(args[0] + " was verified by " + 
         x509.getIssuerDN()); 
       } 
      } 
      else if (ks.isCertificateEntry(args[0])) { 
       System.out.println(args[0] + 
          " is a certificate entry in the keystore"); 
       Certificate c = ks.getCertificate(args[0]); 
       if (c instanceof X509Certificate) { 
        X509Certificate x509 = (X509Certificate) c; 
        System.out.println(args[0] + " is really " + 
         x509.getSubjectDN()); 
        System.out.println(args[0] + " was verified by " + 
         x509.getIssuerDN()); 
       } 
      } 
      else { 
       System.out.println(args[0] + 
         " is unknown to this keystore"); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+1

Я не ищу SSL. Я хотел бы получить доступ к машинным сертификатам и вытащить их пару ключей для шифрования/дешифрования определенных параметров в файлах конфигурации. Я сделал это с сертификатами в хранилище личных сертификатов текущего пользователя, но я хотел бы вытащить (SSL) сертификаты из хранилища Local Machine для криптографии. –

+1

Этот код совсем не то, о чем просит ОП. – Justin

2

По умолчанию реализация JDK довольно ограничена. AFAIK он вернет ключи RSA и сертификаты. Это не универсальный адаптер для MSCAPI. Мне удалось вернуть некоторые сертификаты, используя описанный вами механизм.

+0

Все, что я хочу, это пара ключей RSA. Вы правы. Я могу получить пару ключей из личного хранилища текущего пользователя (Windows-MY), но вместо этого я хотел бы получить их из хранилища личных сертификатов локальной машины. Я не нашел способ указать, в каком хранилище сертификатов (текущий пользователь/локальный компьютер) читать. Кажется, он хочет читать только от текущего пользователя. –

+0

Я вижу, что вы хотите сделать, но: Почему это должно позволить вам читать из магазинов других пользователей? Есть ли в локальном компьютере пары ключей в своем магазине? - если так, вашему процессу Java потребуется разрешение действовать как часть ОС. – Justin

+0

Да, локальная машина имеет пару ключей в своем магазине; любая идея, как я мог бы разрешить моему процессу Java действовать как часть ОС? –

2

Я использовал использованную JNA для доступа к сертификатам с использованием того же окна, что и всплывающее окно, если вы использовали какую-либо специальную программу для Windows - это может не отвечать на ваш вопрос, но, конечно, позволяет вам предоставить доступ к чему-либо в окне way ':

NativeLibrary cryptUI = NativeLibrary.getInstance("Cryptui"); 
    NativeLibrary crypt32 = NativeLibrary.getInstance("Crypt32"); 

    Function functionCertOpenSystemStore = crypt32.getFunction("CertOpenSystemStoreA"); 
    Object[] argsCertOpenSystemStore = new Object[] { 0, "CA"}; 
    HANDLE h = (HANDLE) functionCertOpenSystemStore.invoke(HANDLE.class, argsCertOpenSystemStore); 

    Function functionCryptUIDlgSelectCertificateFromStore = cryptUI.getFunction("CryptUIDlgSelectCertificateFromStore"); 
    System.out.println(functionCryptUIDlgSelectCertificateFromStore.getName()); 
    Object[] argsCryptUIDlgSelectCertificateFromStore = new Object[] { h, 0, 0, 0, 16, 0, 0}; 
    Pointer ptrCertContext = (Pointer) functionCryptUIDlgSelectCertificateFromStore.invoke(Pointer.class, argsCryptUIDlgSelectCertificateFromStore); 

    Function functionCertGetNameString = crypt32.getFunction("CertGetNameStringW"); 
    char[] ptrName = new char[128]; 
    Object[] argsCertGetNameString = new Object[] { ptrCertContext, 5, 0, 0, ptrName, 128}; 
    functionCertGetNameString.invoke(argsCertGetNameString); 
    System.out.println("Selected certificate is " + new String(ptrName)); 

    Function functionCertFreeCertificateContext = crypt32.getFunction("CertFreeCertificateContext"); 
    Object[] argsCertFreeCertificateContext = new Object[] { ptrCertContext}; 
    functionCertFreeCertificateContext.invoke(argsCertFreeCertificateContext); 

    Function functionCertCloseStore = crypt32.getFunction("CertCloseStore"); 
    Object[] argsCertCloseStore = new Object[] { h, 0}; 
    functionCertCloseStore.invoke(argsCertCloseStore); 

Это всего лишь фрагмент кода, который работает; не стесняйтесь применять свои методы кодирования.

+0

Как я могу получить провайдера PrivateKey, используя этот способ? – codenamezero