česky | english
Časové razítkování Java
Tato stránka popisuje proces bezplatného důvěryhodného podepisování kódu, časových razítek a jak získat od CA Thawte orazítkovaný certifikát do úložiště klíčů programu Java bez zásahu uživatele, takže soubory ".jar" budou pracovat důvěryhodně po rozšířené období (v mém testu 9 let). V mém případě ".jar" obsahoval aplet a razítkování bylo potřebné.
Tato stránka má určité prvky společné se stránkami wiki Časová razítka a JavaCodeSigningTest. Původní kopie je na http://nerveplexus.com/Java_Timestamping.htm.
Jestliže otevřete bezplatný e-mailový účet Thawte (freemail), můžete si vygenerovat důvěryhodný certifikát pro podpis kódu, umožňující Vám podepsat soubory ".jar". Procedura je již dokumentována jinde: ---
V listopadu 2009 byly programy Thawte freemail a podepisování kódu Java ukončeny. Další překlad je tedy také bezpředmětný.
1. In the section commencing "Personal Freemail account at Thawte" at http://www.crionics.com/products/opensource/faq/signFree.htm
2. About halfway down the page at http://www.dallaway.com/acad/webstart/
The advantage of using Thawte is that their root CA cert is included in the java runtime CA keystore (cacerts file) so the jar security warning popup will be the trusted type automatically for all users.
The popup will show "Thawte Freemail Member" but it is recommended and easy to get your ID verified with Thawte web of trust in which case your name will appear instead.
After a year the certificate will expire and the jar security popup will revert to untrusted. However if you timestamp when signing the jar, and add the below java code to your applet, then the popup should show as trusted for an extended period, 9 years for one that I tried. So the user will not be unduly hassled.
To timestamp the jar include this in the command line when signing:-
-tsa https://timestamp.geotrust.com/tsa
This ties up with Thawte since both Geotrust and Thawte are owned by Verisign.
For example my complete command line for signing the jar is:-
"C:\Program Files\Java\jdk1.6.0_07\bin\jarsigner" -storetype pkcs12 -keystore C:\Control\keystore.p12 -storepass passpass -keypass passpass -tsa https://timestamp.geotrust.com/tsa C:\Master\www\plexos.com\jmUtilm.jar plexel
For the timestamping to work however the Thawte timestamp CA cert needs to be in the java runtime keystore i.e. java.home\lib\security\cacerts. For XP on my system java.home was C:\Program Files\Java\jre1.6.0_07\.
You might think Sun would have put it in there but they didn't so far. It is in Firefox (3.0.3) certificate authorities listed as Thawte Timestamping CA but that doesn't help.
Since you now have a signed jar and if the jar contains an applet then the following code can be added to the applet to import the Thawte timestamp CA cert into the cacerts keystore. It uses the keytool program included with java runtime to import the cert into the keystore located via the java.home property. The user does not need a Java development kit but it is assumed they have installed Java runtime.
If you use an applet init() function then just add in the line timestampCert() otherwise just copy an paste the lot into your applet. An extra class file is generated that needs including in the jar file to be signed. E.g. if your applet is a single file game.class, then game$1.class will also be generated.
public void init() { timestampCert(); return;} public void timestampCert() { // Import TimestampCA.cer to java runtime cacerts keystore. This stops the applet // expiring when the signing cert expires usually with a year. For a timestamped // test applet signed in 2008 for me it now expires in 2017. TimestampCA.cer expires // 31 Dec 2020 so 2017 is a slight mystery. TimestampCA.cer obtained from:- //https://knowledge.verisign.com/resources/sites/VERISIGN/content/live/SOLUTION/9000/SO9699/en_US/TimestampCA.cer // also obtainable from http://www.webneurons.com/TimestampCA.cer // Sign applet including jarsigner switch " -tsa https://timestamp.geotrust.com/tsa " try { Process p = (Process) AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws Exception { String javaHome = System.getProperty("java.home") + "\\"; String javaHomeLs = javaHome + "lib\\security\\"; File timestampFile = new File(javaHomeLs + "TimestampCA.cer"); // Put timestampFile in java.home/lib/security folder if not there. if(!timestampFile.exists()) { String cert = "-----BEGIN CERTIFICATE-----\n" + "MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkEx\n" + "FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN\n" + "BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAd\n" + "BgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcwMTAxMDAwMDAwWhcN\n" + "MjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4g\n" + "Q2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG\n" + "A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1l\n" + "c3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT\n" + "6jR7UZztsOYuGA7+4F+oJ9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQa\n" + "Wt9MevPZQx08EHp5JduQ/vBR5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL\n" + "8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB\n" + "Af8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC\n" + "9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQ\n" + "pgCed/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZ\n" + "CayJSdM=\n-----END CERTIFICATE-----"; BufferedWriter out = new BufferedWriter(new FileWriter(timestampFile)); out.write(cert); out.close(); } // Command to be executed. If the timestamp cert is already in // java runtime cacerts keystore it just gives a warning. String command = javaHome + "bin\\keytool -import -trustcacerts -keystore " + javaHomeLs + "cacerts -alias Thawte_timestamp_CA -file " + timestampFile + " -noprompt -storepass changeit"; Process p = Runtime.getRuntime().exec(command); // Messages section. Read any messages from input and error streams. // This section could be omitted. BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream())); String inLine, errLine; Boolean inRead = true, errRead = true; while (inRead || errRead) { if(inRead) { inLine = in.readLine(); if(inLine == null) { inRead = false; // don't read any more from in } else { System.out.println("Input Stream: " + inLine); } } if(errRead) { errLine = err.readLine(); if(errLine == null) { errRead = false; // don't read any more from err } else { System.out.println("Error Stream: " + errLine); } } } // End of messages section return p; }}); // End of doPrivileged p.waitFor(); p.destroy(); } catch (Exception e) { System.out.println("Exception in timestampCert(): " +e); } return;}
It should be possible to use Certum.pl mentioned on the wiki page TimeStamping for the timestamping in the same way as above.