public class PKIHandler
extends java.lang.Object
The Public Private Key Infrastructure (PKI) is an important part of the EHR data exchange between the actors.
In cryptography, PKCS#12 defines an archive file format for storing many cryptography objects as a single file. A X509 certificate is a public key certificate that binds the public key together with an idententity (person, organisation, device or another subject). The X509 certificate also contains a digital signature of a 3rd party or the owner itself (self signed). For bundling certificates as a chain of trust the PKCS#12 can be used. The file name extension is 'pfx' or 'p12' by default.
//command to generate the RSA based private key $openssl genrsa -out DE-0000000-0000000-00000000.rsa 2048 //convert PrivKey to PKSC#8 to use key by Java $openssl pkcs8 -topk8 -inform PEM -outform DER \ -in DE-0000000-0000000-00000000.rsa \ -out DE-0000000-0000000-00000000.priv -nocrypt //create the public key to be use by Java $ openssl rsa -in DE-0000000-0000000-00000000.rsa \ -pubout -outform DER -out DE-0000000-0000000-00000000.pub
Constructor and Description |
---|
PKIHandler() |
PKIHandler(java.security.KeyStore ks)
Get an instance of the handler using the given KeyStore.
|
PKIHandler(java.lang.String alg,
int keyLen)
Get an instance of the handler for generating public-private-keys.
|
Modifier and Type | Method and Description |
---|---|
void |
assignKeyStore(java.lang.String pathToSEHRKeyStore)
For using the given keystore in a TLS (former SSL) handshake by JVM system
propery 'trustStore'.
|
java.lang.String |
dumpStoredCerts()
Generate a dump of all certificates stored in the KeyStore.
|
java.security.cert.X509Certificate |
generateCert(java.lang.String dnOwner,
java.security.PublicKey pubKeyOwner,
javax.security.auth.x500.X500Principal x500Issuer,
java.security.PrivateKey privkeyIssuer,
int days,
java.lang.String algorithm)
Create a X.509 certificate for an owner by an issuer.
|
java.security.KeyPair |
generateKeyPair(java.lang.String fnPrivKeyFile,
java.lang.String fnPubKeyFile)
Generate a public-private-key pair and store the public and private key
into given files by name.
|
java.security.cert.X509Certificate |
generateSelfSignedCert(java.lang.String dnOwner,
java.security.KeyPair pair,
int days,
java.lang.String algorithm)
Create a self-signed X.509 Certificate.
|
java.util.List<PKIDataObject> |
getRevokeList()
Get a list of public keys (and/or certificates) that have been revoked.
|
java.security.cert.X509Certificate[] |
getX509ServerCertificates(java.lang.String host,
int port)
Get the X509 certificate chain from a TLS/SSH connection.
|
boolean |
initKeyStore(java.io.File f,
java.lang.String key)
Create/initialize a new KeyStore file by given parameters.
|
static javax.net.ssl.SSLSocketFactory |
initSSLSocketFactory(java.io.File pKeyFile,
java.lang.String pKeyPassword)
Using a private key file and a password of this file to initiate a TLS
(SSL) connection.
|
boolean |
isCertStored(java.security.cert.X509Certificate cert)
Check if a X509 certificate is already stored in the KeyStore.
|
static java.security.cert.X509Certificate |
loadDERCertificate(java.io.File fDER)
Load X509Certificate object from DER file.
|
boolean |
loadKeyStore(java.io.File f,
java.lang.String key)
Load the content of a given (SEHR) KeyStore by given parameters.
|
static java.security.PrivateKey |
loadPrivateKey(java.lang.String filename) |
static java.security.PrivateKey |
loadPrivatePEMKey(java.io.File pemFile) |
static java.security.PublicKey |
loadPublicKey(java.lang.String pubKeyFile) |
java.security.PublicKey |
loadPublicPEMKey(java.lang.String pemFile)
Get RSA generated PublicKey object from PEM file.
|
java.security.PublicKey |
loadPublicPEMKey(java.lang.String pemFile,
java.lang.String algorithm)
Get PublicKey object from a given PEM file and algorithm (DSA or RSA).
|
java.security.cert.X509Certificate |
readCert(java.lang.String alias)
Get X509 certificate from the KeyStore of this instance.
|
void |
setKeyAlgorithm(java.lang.String algorithm)
Set the algorithm, RSA or DSA.
|
boolean |
signDataFile(java.lang.String privKeyFile,
java.lang.String dataFile,
java.lang.String sigFile)
Sign a data file using a given PrivateKey.
|
boolean |
storeCert(java.lang.String alias,
java.security.cert.X509Certificate cert)
Stores a X509 certificate in the KeyStore of this instance.
|
boolean |
verifyDataFile(java.lang.String pubKeyFile,
java.lang.String sigFile,
java.lang.String dataFile)
Verify a data file with a signature file we got from another SEHR app.
|
static void |
writeCert(java.security.cert.X509Certificate cert,
java.io.File fOut)
Write the X509 certificate to a given file.
|
public PKIHandler()
public PKIHandler(java.security.KeyStore ks)
The KeyStore is required e.g. to get X509ServerCertificates.
Note:To store certificates or to change content of the KeyStore use
the parameterless contructor and
initKeyStore(java.io.File, java.lang.String)
ks
- public PKIHandler(java.lang.String alg, int keyLen)
The KeyStore is required e.g. to get X509ServerCertificates.
alg
- e.g. RSA (default)keyLen
- e.g. 2048public void assignKeyStore(java.lang.String pathToSEHRKeyStore)
The only necessary step is to reference the keystore file in an application using the "trustStore" system property of the underlaying JVM. This can be done on the command line with:
-Djavax.net.ssl.trustStore=/path/to/cacerts
To assign the keystore for this use case programatically use this method.
Note:Create the keystore by running 'InstallCert' from the 'Sehr-osi' package. 'InstallCert' is using this PKIHandler.
pathToSEHRKeyStore
- By default 'sehrroot/etc/cacerts'public static javax.net.ssl.SSLSocketFactory initSSLSocketFactory(java.io.File pKeyFile, java.lang.String pKeyPassword) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.io.FileNotFoundException, java.io.IOException, java.security.cert.CertificateException, java.security.UnrecoverableKeyException, java.security.KeyManagementException
The administrator of a SEHR community (zone) host (server) may (should) secure the network by assigning certificates to any client that connects to the server. By convention SEHR follows the 2-way authentification which requires two keys. A private key provided by the SEHR zone responsible for a client (app, device or user) authentication, and a public key downloaded from the secured zone host (Glassfish, Port 8181) to authenticate the host on client site. Potential users, apps or devices of SEHR data exchange (usinf SOAP, REST etc.) must contact the zone administrator to request access. They retrieve (by snail mail) an USB card/stick with a private key and a password. Client uthentication is performed in the client code by creating an SSLSocketFactory with the private key and the password using this method. The app associates the SocketFactory with the HttpsURLConnection to the SEHR zone host.
Authentication of the server is performed by downloading the public key
from the SEHR zone host using 'InstallCert' from the package 'sehr-osi' and
loading it into a local keystore that is referenced by the client
application via a runtime property using
#assignTruststore(java.lang.String)
. 'InstallCert' is using this
PKIHandler.
pKeyFile
- pKeyPassword
- java.security.KeyStoreException
java.security.NoSuchAlgorithmException
java.io.FileNotFoundException
java.io.IOException
java.security.cert.CertificateException
java.security.UnrecoverableKeyException
java.security.KeyManagementException
public boolean initKeyStore(java.io.File f, java.lang.String key)
f
- key
- public void setKeyAlgorithm(java.lang.String algorithm)
algorithm
- public java.security.cert.X509Certificate[] getX509ServerCertificates(java.lang.String host, int port)
host
- port
- public java.security.KeyPair generateKeyPair(java.lang.String fnPrivKeyFile, java.lang.String fnPubKeyFile)
fnPrivKeyFile
- fnPubKeyFile
- public java.security.cert.X509Certificate generateCert(java.lang.String dnOwner, java.security.PublicKey pubKeyOwner, javax.security.auth.x500.X500Principal x500Issuer, java.security.PrivateKey privkeyIssuer, int days, java.lang.String algorithm) throws java.security.GeneralSecurityException, java.io.IOException
By convention the issuer should never know the private key of an certificate owner. So the 'KeyPair' has to be taken from the owner 'as is'.
dnOwner
- X.509 Distinguished Name, eg 'CN=Jane Doe,L=Hamburg,C=DE'pubKeyOwner
- the public key of a key pair, e.g. generated by
generateKeyPair(java.lang.String, java.lang.String)
x500Issuer
- contains X.509 Distinguished Name, eg 'CN=General
Hospital c#0601311,L=Manila,C=PH'privkeyIssuer
- the private key of the issuer to sign the CAdays
- how many days from now the Certificate is valid foralgorithm
- the signing algorithm, eg "SHA1withRSA"java.security.GeneralSecurityException
java.io.IOException
public java.security.cert.X509Certificate generateSelfSignedCert(java.lang.String dnOwner, java.security.KeyPair pair, int days, java.lang.String algorithm) throws java.security.GeneralSecurityException, java.io.IOException
dnOwner
- X.509 Distinguished Name, eg 'CN=Jane Doe,L=Hamburg,C=DE'pair
- the KeyPair, e.g. generated by
generateKeyPair(java.lang.String, java.lang.String)
days
- how many days from now the Certificate is valid foralgorithm
- the signing algorithm, eg "SHA1withRSA"java.security.GeneralSecurityException
java.io.IOException
public boolean signDataFile(java.lang.String privKeyFile, java.lang.String dataFile, java.lang.String sigFile)
privKeyFile
- dataFile
- sigFile
- The sign-file will be created with the name of the data file
and the extension '.sig' if parameter is 'null'public boolean verifyDataFile(java.lang.String pubKeyFile, java.lang.String sigFile, java.lang.String dataFile)
pubKeyFile
- sigFile
- dataFile
- public static java.security.PrivateKey loadPrivateKey(java.lang.String filename) throws java.io.FileNotFoundException, java.security.NoSuchAlgorithmException, java.security.spec.InvalidKeySpecException, java.io.IOException
java.io.FileNotFoundException
java.security.NoSuchAlgorithmException
java.security.spec.InvalidKeySpecException
java.io.IOException
public static java.security.PrivateKey loadPrivatePEMKey(java.io.File pemFile) throws java.lang.Exception
java.lang.Exception
public static java.security.PublicKey loadPublicKey(java.lang.String pubKeyFile) throws java.io.FileNotFoundException, java.security.NoSuchAlgorithmException, java.security.spec.InvalidKeySpecException, java.io.IOException
java.io.FileNotFoundException
java.security.NoSuchAlgorithmException
java.security.spec.InvalidKeySpecException
java.io.IOException
public java.security.PublicKey loadPublicPEMKey(java.lang.String pemFile) throws java.lang.Exception
pemFile
- java.lang.Exception
public java.security.PublicKey loadPublicPEMKey(java.lang.String pemFile, java.lang.String algorithm) throws java.lang.Exception
pemFile
- algorithm
- java.lang.Exception
public static java.security.cert.X509Certificate loadDERCertificate(java.io.File fDER)
The specified DER file specified must contain a single DER encoded X.509 certificate. The DER encoded certificate can be in either binary or ASCII format.
Use Case:Load an external generated certifićate for signing purposes or further usage within the SEHR context.
fDER
- public java.lang.String dumpStoredCerts()
public boolean isCertStored(java.security.cert.X509Certificate cert)
cert
- public java.security.cert.X509Certificate readCert(java.lang.String alias)
alias
- public boolean storeCert(java.lang.String alias, java.security.cert.X509Certificate cert)
alias
- cert
- public static void writeCert(java.security.cert.X509Certificate cert, java.io.File fOut) throws java.io.IOException
cert
- fOut
- java.io.IOException
public boolean loadKeyStore(java.io.File f, java.lang.String key)
f
- The path-and-file handler to the KeyStorekey
- The passord to load the KeyStorepublic java.util.List<PKIDataObject> getRevokeList()
Certificate revocation is an important feature to be implemented in the very next future. See also/Lit.Ref.: