Forum TT Soft Sp. z o.o.

Forum poświęcone produktom firmy TT Soft
Teraz jest 11 wrz 2010, 03:04

Wszystkie czasy w strefie UTC + 1




Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 9 ] 
Autor Wiadomość
 Tytuł: Kwalifikowany podpis elektroniczny - JAVA
PostNapisane: 15 cze 2008, 17:15 
Offline
Avatar użytkownika

Dołączył(a): 15 maja 2008, 13:32
Posty: 314
Lokalizacja: Mrowla
Ku mojemu zdumieniu napisana pół roku temu aplikacja do podpisu elektronicznego nie działa z kartami Sigillum. Powód był dość śmieszny - oczywiście rozbiło się o prawidłową inicjalizację JCA. Moja prywatna karta Sigillum ma odpis elektroniczny na slocie nr 3... Tymczasem Java inicjalizując JCA dokladniej PKCS#11 domyślnie grzebie w slocie o numerze zero. Teraz pozostaje dowiedzieć się gdzie kwalifikowane klucze umieszcza UNIZETO i KIR. Poprawna inicjalizacja dla kart Sigillum:

Kod:
String pkcs11ConfigSettings = "";
pkcs11ConfigSettings += "name = SmartCard\n";
pkcs11ConfigSettings += "library = C:\\Windows\\system32\\CCPkiP11.dll\n";
pkcs11ConfigSettings += "slot = 3\n"; // **** TO JEST POWÓD PROBLEMÓW Z ZAŁADOWANIEM KLUCZA ****
ByteArrayInputStream confStream = new ByteArrayInputStream(pkcs11ConfigSettings.getBytes());

// Instantiate the provider dynamically with Java reflection
Class sunPkcs11Class = Class.forName("sun.security.pkcs11.SunPKCS11");
Constructor pkcs11Constr = sunPkcs11Class.getConstructor(InputStream.class);
Provider pkcs11Provider = (Provider) pkcs11Constr.newInstance(confStream);
Security.addProvider(pkcs11Provider);
       
pkcs11ProviderName =  pkcs11Provider.getName();
       
// info about SC provider
System.out.println("SC Provider info: ");
System.out.println("Name: "    + pkcs11Provider.getName());
System.out.println("Info: "    + pkcs11Provider.getInfo());
System.out.println("Version: " + pkcs11Provider.getVersion());


A potem już łatwo można dobrać się do klucza prywatnego:
Kod:
char[] pin = "1111".toCharArray();
KeyStore keyStore = KeyStore.getInstance("PKCS11");
keyStore.load(null, pin);

_________________
Bartłomiej Prokop
tel. +48 509 258 502
http://bart.prokop.name
http://bartprokop.blogspot.com/


Góra
 Zobacz profil  
 
 Tytuł: Re: Kwalifikowany podpis elektroniczny - JAVA
PostNapisane: 21 cze 2009, 20:06 
Offline

Dołączył(a): 21 cze 2009, 19:48
Posty: 3
Witam,

Czy prubowałeś może z kartami Unizeto i czytnikeim ACR38? Masz może jakiś fragment kodu dla tych kart?
Próbowałem uruchmić podany przez Ciebie kod własnie dla czytnika ACR38 i karty Unizeto i niestety pojawia się następujący błąd:
Kod:
SC Provider info:
Name: SunPKCS11-SmartCard
Info: SunPKCS11-SmartCard using library C:\Windows\SysWOW64\cryptoCertumPKCS11.dll
Version: 1.6

java.security.KeyStoreException: PKCS11 not found
        at java.security.KeyStore.getInstance(KeyStore.java:587)

Caused by: java.security.NoSuchAlgorithmException: PKCS11 KeyStore not available

        at sun.security.jca.GetInstance.getInstance(GetInstance.java:142)
        at java.security.Security.getImpl(Security.java:659)
        at java.security.KeyStore.getInstance(KeyStore.java:584)


Kod programu wygląda tak:
Kod:
String pkcs11ConfigSettings = "";
pkcs11ConfigSettings += "name = SmartCard\n";
pkcs11ConfigSettings += "library = C:\\Windows\\SysWOW64\\cryptoCertumPKCS11.dll\n";
//pkcs11ConfigSettings += "slot = 1\n"; // **** TO JEST POWÓD PROBLEMÓW Z ZAŁADOWANIEM KLUCZA ****
ByteArrayInputStream confStream = new ByteArrayInputStream(pkcs11ConfigSettings.getBytes());

// Instantiate the provider dynamically with Java reflection
Class sunPkcs11Class = Class.forName("sun.security.pkcs11.SunPKCS11");
java.lang.reflect.Constructor pkcs11Constr = sunPkcs11Class.getConstructor(InputStream.class);
Provider pkcs11Provider = (Provider) pkcs11Constr.newInstance(confStream);
Security.addProvider(pkcs11Provider);
       
//pkcs11ProviderName =  pkcs11Provider.getName();
       
// info about SC provider
System.out.println("SC Provider info: ");
System.out.println("Name: "    + pkcs11Provider.getName());
System.out.println("Info: "    + pkcs11Provider.getInfo());
System.out.println("Version: " + pkcs11Provider.getVersion());

         char[] pin = "1111".toCharArray();
         KeyStore ks = KeyStore.getInstance("PKCS11");
         ks.load(null, pin);


Masz może jakiś pomysł co poprawić żeby zadziałało?

Z góry dziękuję.

Pozdrawiam
Marek Faderewski


Góra
 Zobacz profil  
 
 Tytuł: Re: Kwalifikowany podpis elektroniczny - JAVA
PostNapisane: 27 cze 2009, 08:50 
Offline
Avatar użytkownika

Dołączył(a): 15 maja 2008, 13:32
Posty: 314
Lokalizacja: Mrowla
Wygląda na uwaloną bibliotekę DLL. Dla Sigillum zaczęło tak naprawde działać dopiero po upgrade do najaktualniejszej wersji.

_________________
Bartłomiej Prokop
tel. +48 509 258 502
http://bart.prokop.name
http://bartprokop.blogspot.com/


Góra
 Zobacz profil  
 
 Tytuł: Re: Kwalifikowany podpis elektroniczny - JAVA
PostNapisane: 28 cze 2009, 10:45 
Offline

Dołączył(a): 21 cze 2009, 19:48
Posty: 3
Wielkie dzieki, zadziałało po akutalizacji DLL'ki.
Pięknie działa też ze standardem xml'owym podpisu.

Pozdrawiam
Marek Faderewski


Góra
 Zobacz profil  
 
 Tytuł: Re: Kwalifikowany podpis elektroniczny - JAVA
PostNapisane: 07 lip 2009, 08:45 
Offline
Avatar użytkownika

Dołączył(a): 15 maja 2008, 13:32
Posty: 314
Lokalizacja: Mrowla
To fajnie :) mam jeszcze pytanie, czy mógłbyś się odnieść do tego fragmentu kodu:

Kod:
pkcs11ConfigSettings += "library = C:\\Windows\\SysWOW64\\cryptoCertumPKCS11.dll\n";
//pkcs11ConfigSettings += "slot = 1\n"; // **** TO JEST POWÓD PROBLEMÓW Z ZAŁADOWANIEM KLUCZA ****
ByteArrayInputStream confStream = new ByteArrayInputStream(pkcs11ConfigSettings.getBytes());


Konkretnie, czy wymagane jest podawanie numeru slotu dla kart UNIZETO?

_________________
Bartłomiej Prokop
tel. +48 509 258 502
http://bart.prokop.name
http://bartprokop.blogspot.com/


Góra
 Zobacz profil  
 
 Tytuł: Re: Kwalifikowany podpis elektroniczny - JAVA
PostNapisane: 17 lip 2009, 09:02 
Offline

Dołączył(a): 21 cze 2009, 19:48
Posty: 3
U mnie działa bez ustawionego slotu lub gdy slot=1.
Próbowałem z 0 lub 2 to wówczas pojawaia się błąd o nieprawidłowym numerze slotu.


Góra
 Zobacz profil  
 
 Tytuł: Re: Kwalifikowany podpis elektroniczny - JAVA
PostNapisane: 05 lis 2009, 11:45 
Offline

Dołączył(a): 05 lis 2009, 11:33
Posty: 1
Witam serdecznie.
Ja jestem "szczesliwym" posiadaczem zestawu Certum. Bardzo zalezy mi na podpisywaniu maili certyfikatem kwalifikowanym. Niestety nie moge tego zrealizowac poprzez aplikacje webowa ktora kiedys popelniles (http://java.bart.prokop.name/smail/). Byc moze robie cos zle.
Mam zainstalowane najnowsze oprogramowanie SmartSign 3.1.0.1203 (http://www.unizeto.pl/unizeto/uni,oferta_smartsign.xml).
Przy probie wyslania wskazuje biblioteke cryptoCertumPKCS11.dll, Slot 1, wprowadzam Pin, a efekt jest zawsze ten sam.
Obrazek
Czy Twoja aplikacja webowa powinna dzialac z zestawem Certum? Masz moze jakies sugestie?

Pozdrawiam,
remedu


Góra
 Zobacz profil  
 
 Tytuł: Re: Kwalifikowany podpis elektroniczny - JAVA
PostNapisane: 11 lis 2009, 23:38 
Offline

Dołączył(a): 03 wrz 2009, 22:15
Posty: 8
Lokalizacja: USA
Niepotrafię odpowiedzieć na pytanie o CERTUM. Zwyczajnie nie miałem tej karty ani biblioteki do niej w swoich rękach.

_________________
http://www.ttsoft.pl


Góra
 Zobacz profil  
 
 Tytuł: Re: Kwalifikowany podpis elektroniczny - JAVA
PostNapisane: 24 mar 2010, 16:46 
Offline

Dołączył(a): 24 mar 2010, 16:13
Posty: 1
Witam,

Jakoś udało mi się znaleźć ten wątek dokładnie powiązany z moim zadaniem. Mianowicie, muszę dopisać do swojej aplikacji możliwość podpisu elektronicznego kwalifikowanego. Używam urządzenia SMART CARD READER ACR38 z Unizeto. Komunikację z czytnikiem ustawiłem i udało mi się podpisać plik używając providera BouncyCastle, ale zapisuje nim do formatu p7m, gdzie razem z podpisem elektronicznym jest dołączony plik źródłowy. Takie rozwiązanie za bardzo mnie nie interesuje, bo potrzebuje stałego dostępu do źródłowego pliku.
Chciałbym to zrobić metodą opisaną w wątkach powyżej. Czy mogę prosić o jakieś wskazówki, ewentualnie przykładowy kod jak wygenerować plik XML z podpisem i ewentualnie jak go później weryfikować?

To co zrobiłem na podstawie kodu powyżej:
Kod:
String pkcs11ConfigSettings = "";
            pkcs11ConfigSettings += "name = SmartCard\n";
            pkcs11ConfigSettings += "library = E:\\cryptoCertum3PKCS.dll\n";
            ByteArrayInputStream confStream = new ByteArrayInputStream(pkcs11ConfigSettings.getBytes());

            // Instantiate the provider dynamically with Java reflection
            Class sunPkcs11Class = Class.forName("sun.security.pkcs11.SunPKCS11");
            java.lang.reflect.Constructor pkcs11Constr = sunPkcs11Class.getConstructor(InputStream.class);
            Provider pkcs11Provider = (Provider) pkcs11Constr.newInstance(confStream);
            Security.addProvider(pkcs11Provider);

            //pkcs11ProviderName =  pkcs11Provider.getName();

            // info about SC provider
            System.out.println("SC Provider info: ");
            System.out.println("Name: "    + pkcs11Provider.getName());
            System.out.println("Info: "    + pkcs11Provider.getInfo());
            System.out.println("Version: " + pkcs11Provider.getVersion());

         char[] pin = "2222".toCharArray();
         KeyStore ks = KeyStore.getInstance("pkcs11");
         ks.load(null, pin);
         String alias = "16783361";
         PrivateKey key = (PrivateKey) ks.getKey(alias, pin);
         java.security.cert.Certificate[] chain = ks.getCertificateChain(alias);
         X509Certificate cert = (X509Certificate) ks.getCertificate(alias);

         File src = new File("E:\\img.jpg");
          int sizecontent = ( (int) src.length());
          byte[] contentData = new byte[sizecontent];
          FileInputStream freader = new FileInputStream(src);
          freader.read(contentData, 0, sizecontent);
          freader.close();

     //calculate digest of the input data
          byte[] toEncrypt = buildBits(contentData);

          byte[] signature = signDocument(toEncrypt,key);
            for (int i = 0; i < signature.length; i++) {
                System.out.print(signature[i]);
            }


i funkcje pomocnicze:
Kod:
  private static byte[] signDocument(byte[] aDocument,
                                   PrivateKey aPrivateKey) throws GeneralSecurityException {
           Signature signatureAlgorithm =
           Signature.getInstance("SHA1withRSA");
           signatureAlgorithm.initSign(aPrivateKey);
           signatureAlgorithm.update(aDocument);
           byte[] digitalSignature = signatureAlgorithm.sign();
           return digitalSignature;
        }



     public static byte[] buildBits(byte[] bytesToSign) throws
      NoSuchAlgorithmException {

    MessageDigest hash = MessageDigest.getInstance("SHA1");

    hash.update(bytesToSign);
    byte[] digest = hash.digest();

    /*
     The DSI (Digital Signature Input for RSA) format according to PKCS #1 V1.5
     (Block Type 1) has the following structure:
     - Startbyte: ?00?
     - Block type: ?01?
     - Padding-String: ?FF ?FF?
     - Separator: ?00?
     - DigestInfo: ASN.1-Sequence of digestAlgorithm (ASN.1-Sequence of OID and parameter)
      and digest (ASN.1-DO hash value)

     The DigestInfo to be delivered to the card has the following coding:
     SHA-1 with OID: { 1 3 14 3 2 26 }
     DigestInfo: 3021 3009 06052B0E03021A 0500 0414 || hash value (20 bytes)

     */
    String hhStr =
        "30213009" +
        "06052b0e03021a" + //algoritm SHA-1  1.3.14.3.2.26
        "0500" +
        "0414" + toHexString(digest);

    return parse(hhStr);
  }

     public static byte[] parse(String hexString) {
    byte[] ret = new byte[hexString.length() / 2];
    for (int i = 0; i < ret.length; i++) {
      ret[i] = (byte) Integer.parseInt(hexString.substring(2 * i, 2 * (i + 1)), 16);
    }
    return ret;
  }

  public static String toHexString(byte[] arrayHex) {
    return toHexString(arrayHex, 0, arrayHex.length);
  }

  public static String toHexString(byte[] arrayHex, int start, int length) {
    String ret = "";
    String dd = "";
    for (int i = start; i < length; i++) {
      int v = 0;
      dd = "";
      v = (int) arrayHex[i];
      if (v < 0) {
        v += 256;
      }

      dd = Integer.toHexString(v).toUpperCase();
      if (dd.length() == 1) {
        dd = "0" + dd;
      }

      ret += dd;
    }
    return ret;
  }


Za wszelką pomoc z góry dziękuje ;)
Pozdrawiam


Góra
 Zobacz profil  
 
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 9 ] 

Wszystkie czasy w strefie UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 1 gość


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Przyjazne użytkownikom polskie wsparcie phpBB3 - phpBB3.PL