Moin,
neben den dort beschriebenen Möglichkeiten besteht noch die Möglichkeit des Aufbaues einer eigenen Public Key Infrastruktur (PKI). Insbesondere firmenintern skaliert das besser, da nur das firmeneigene Wurzelzertifikat auf die Firmenrechner ausgerollt werden muss. Dabei kann Java auch so angepasst werden, das bei bedarf nur noch der eigenen Zertifizierungsstelle vertraut wird.
Auch während der Entwicklung kann das nützlich sein, da das Verhalten genau dem eines kommerziellen Zertifikates entspricht.
Das Vorgehen wäre beispielsweise:
- Die Zertifizierungsstelle aufsetzen (OpenSSL muss installiert sein)
- Dateien und Verzeichnisse anlegen:
X:\>mkdir CA
X:\>cd CA
X:\CA>mkdir certs
X:\CA>touch index
X:\CA>echo 01 > serial
- openssl.conf anlegen und anpassen:
[ ca ]
default_ca = ca_default
[ ca_default ]
dir = X:/CA
private_key = $dir/ca.key
certificate = $dir/ca.pem
database = $dir/index
serial = $dir/serial
new_certs_dir = $dir/certs/
default_days = 1095
default_crl_days = 365
default_md = sha512
policy = policy
x509_extensions = v3_usr
[ policy ]
commonName = supplied
[ req ]
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
commonName = Common Name (eg, YOUR name)
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
basicConstraints = CA:true
crlDistributionPoints = URI:http://mschorn.net/crl.pem
[ v3_usr ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
basicConstraints = CA:false
nsCertType = server, client, email
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
crlDistributionPoints = URI:http://mschorn.net/crl.pem
[ v3_code_sign ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
basicConstraints = CA:false
nsCertType = client, email, objsign
keyUsage = digitalSignature
extendedKeyUsage = codeSigning, msCodeInd, msCodeCom
crlDistributionPoints = URI:http://mschorn.net/crl.pem
- Schlüssel und Wurzelzertifikat der CA erzeugen:
X:\CA>openssl req -config openssl.conf -extensions v3_ca -x509 -days 3650 -newkey rsa:4096 -keyout ca.key -out ca.pem
Generating a 4096 bit RSA private key
[..]
writing new private key to 'ca.key'
Enter PEM pass phrase: catest
Verifying - Enter PEM pass phrase: catest
[..]
Common Name (eg, YOUR name) []:Foobar Enterprise CA
- eine leere Widerrufsliste (CRL) erzeugen:
X:\CA>openssl ca -config openssl.conf -gencrl -out crl.pem
Using configuration from openssl.conf
Enter pass phrase for X:/CA/ca.key: catest
Diese CRL muss an der in der openssl.conf angegebenen Adresse veröffentlicht werden, sonnst wirft Java später eine Warnung.
- das Wurzelzertifikats PEM zum CER umwandeln:
X:\CA>openssl x509 -in ca.pem -outform der -out ca.cer
- das Wurzelzertifikat in die Java cacerts importieren:
X:\CA>keytool -import -keystore "C:\Program Files\Java\jre8\lib\security\cacerts " -trustcacerts -alias foobarenterprise -file ca.cer
Enter keystore password: changeit
Owner: CN=Foobar Enterprise CA
[..]
Trust this certificate? [no]: yes
Certificate was added to keystore
Das Java Default Passwort für die cacerts lautet: changeit. Um die cacerts verändern zu dürfen, muss der Befehl mit Administratorrechten ausgeführt werden. Je nach Nutzerkreis kann entweder die ca.cer oder direkt die cacerts ausgerollt werden. Die cacerts kann bei bedarf ausgemistet werden, so das nur noch der eigenen Zertifizierungsstelle vertraut wird.
Wenn Java mehrmals installiert ist, sollte die cacerts von jeder Installation angepasst werden (z.B. bei 32 Bit / 64 Bit).
- Das eigentliche Code Sign Zertifikat erstellen:
- Schlüssel und Zertifikatrequest erstellen:
X:\CA>openssl req -config openssl.conf -new -newkey rsa:2048 -keyout foobar.key -out foobar.csr
Generating a 2048 bit RSA private key
[..]
Enter PEM pass phrase: mypass
Verifying - Enter PEM pass phrase: mypass
[..]
Common Name (eg, YOUR name) []:Foobar Development
- das Zertifikatrequest signieren:
X:\CA>openssl ca -config openssl.conf -extensions v3_code_sign -in foobar.csr -out foobar.pem
Using configuration from openssl.conf
Enter pass phrase for X:/CA/ca.key: catest
[..]
Sign the certificate? [y/n]:y
[..]
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
- Schlüssel und Zertifikat zu einer P12 Datei vereinigen:
X:\CA>openssl pkcs12 -export -out foobar.p12 -inkey foobar.key -in foobar.pem -certfile ca.pem
Enter pass phrase for foobar.key: mypass
Enter Export Password: mypass
Verifying - Enter Export Password: mypass
- P12 zu einem JKS umwandeln:
X:\CA>keytool -importkeystore -srckeystore foobar.p12 -srcstoretype PKCS12 -alias 1 -destkeystore foobar.jks -destalias foobar
Enter destination keystore password: testtest
Re-enter new password: testtest
Enter source keystore password: mypass
- Das Applet:
import java.awt.BorderLayout;
@SuppressWarnings("serial")
public class HelloWorld extends JApplet {
public HelloWorld() {
getContentPane().add(new JLabel("Hello World!"), BorderLayout.NORTH);
}
}```
- bauen und signieren mit Maven:
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
foobar
applet
0.0.1-SNAPSHOT
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<finalName>applet</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Sealed>true</Sealed>
<Permissions>sandbox</Permissions>
<Codebase>*</Codebase>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<id>sign</id>
<phase>package</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
```
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/settings/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<profiles>
<profile>
<id>foobar</id>
<properties>
<jarsigner.keystore>X:/CA/foobar.jks</jarsigner.keystore>
<jarsigner.alias>foobar</jarsigner.alias>
<jarsigner.storepass>testtest</jarsigner.storepass>
<jarsigner.keypass>mypass</jarsigner.keypass>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>foobar</activeProfile>
</activeProfiles>
</settings>
mvn install
<!DOCTYPE html>
<html lang="en">
<head><title>Hello World</title></head>
<body>
<script src="https://www.java.com/js/deployJava.js"></script>
<script>
var attributes = { code:'will.be.ignored', width:300, height:300} ;
var parameters = { jnlp_href: 'applet.jnlp'} ;
deployJava.runApplet(attributes, parameters, '1.7');
</script>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<jnlp href="applet.jnlp">
<information>
<title>HelloWorld</title>
<vendor>Foobar</vendor>
</information>
<update check="always" policy="always"/>
<resources>
<java version="1.7+" href="http://java.sun.com/products/autodl/j2se" initial-heap-size="64m" max-heap-size="128m"/>
<jar href="applet.jar" main="true"/>
</resources>
<applet-desc
name="HelloWorld"
main-class="foobar.HelloWorld"
width="300"
height="300">
</applet-desc>
</jnlp>
- vor dem Start des Applet erscheint derselbe Dialog wie bei einem kommerziellen Zertifikat:
So läuft das Applet ganz normal innerhalb der Sandbox. Damit es ohne Sandbox läuft, muss das Permissions Attribute im Manifest geändert werden und die JNLP um ein
<security>
<all-permissions/>
</security>
ergänzt werden.
Viele Grüße
Fancy