public class P12KeyStore extends PKCS12KeyStore
PKCS12KeyStore
implementation about the possibility of specifying protection parameters when adding
a KeyStore entry or storing
the KeyStore.
For protecting a PKCS#12 KeyStore protection parameters may be requured for encrypting the key store
entries and for calculating a mac value from the keystore contents when finally storing the keystore.
Key entries maybe protected by means of P12 password protection parameters
,
certificate entries by means of P12 cert entry protection parameters
. Both types of
protection parameters may use a PKCS12PbeAlgorithm
or PKCS12Pbes2Algorithm
algorithm for protecting the key or certificate entry. When finally storing
the keystore P12 store parameters
may be used for protecting the
integrity of the keystore by means of a PKCS12MacAlgorithm
.
Although it is possible to specify a specific (or even different) PBE algorithm for each separate key
or certificate entry and a specific MAC algorithm when storing the keystore, for interoperability reasons
it is recommended to use the name of one of the two PKCS#12 algorithm sets "PBES2"
or "PBES1"
only. For security reasons
it is recommended to use "PBES2". Thus a typical work flow for generating a PKCS#12 keystore,
adding certificate and key entries and storing the key store (with the use of protection parameters) may
look like:
// the protection algorithm set name String protectionAlg = "PBES2"; // the keystore password char[] password = ...; // create a new PKCS12 KeyStore KeyStore ks = KeyStore.getInstance("PKCS12", "IAIK"); ks.load(null, null); // add a key entry PrivateKey privateKey = ...; X509Certificate[] certChain = ...; String keyAlias = ...; KeyStore.PrivateKeyEntry keyEntry = new KeyStore.PrivateKeyEntry(privateKey, certChain); P12PasswordProtection pwdProtection = new P12PasswordProtection(password, protectionAlg); ks.setEntry(keyAlias, keyEntry, pwdProtection); // add a cert entry X509Certificate trustedCert = ...; String certAlias = ...; KeyStore.TrustedCertificateEntry certEntry = new KeyStore.TrustedCertificateEntry(trustedCert); P12CertEntryProtection p12Protection = new P12CertEntryProtection(protectionAlg); ks.setEntry(certAlias, certEntry, p12Protection); // store keystore OutputStream os = ...; P12StoreParameter storeParams = new P12StoreParameter(os, password, protectionAlg); ks.store(storeParams);In this example the
PBES2
algorithm set is used for adding
keystore entries (by using the PBES2WithHmacSHA256AndAES256
algorithm and protecting the integrity of the keystore with the HMAC_SHA256
algorithm).
Note that since PBES2 is the default PKCS#12 algorithm set the code example above would do exactly the same as when using the PKCS#12 KeyStore implementation in the accustomed way without any protection parameters:
// the keystore password char[] password = ...; // create a new PKCS12 KeyStore KeyStore ks = KeyStore.getInstance("PKCS12", "IAIK"); ks.load(null, null); // add a key entry PrivateKey privateKey = ...; X509Certificate[] certChain = ...; String keyAlias = ...; ks.setKeyEntry(keyAlias, privateKey, password, certChain); // add a cert entry X509Certificate trustedCert = ...; String certAlias = ...; ks.setCertificateEntry(certAlias, cert); // store keystore OutputStream os = ...; ks.store(os, password);Using protection parameters may only be required when having to protect some particular PKCS#12 KeyStore with an algorithm (set) that differs from the default (PBES2) set. For instance, for interoperability reasons with some PKCS#12 application that does not support PBES2 yet, it might be required to protect a particular PKCS#12 KeyStore by using the PBES1 algorithm set (
HMAC_SHA1
as mac algorithm,
PBEWithSHAAnd40BitRC2_CBC
for encrypting cert entries and
PBEWithSHAAnd3_KeyTripleDES_CBC
for
encrypting key entries):
// the protection algorithm set name String protectionAlg = "PBES1"; // the keystore password char[] password = ...; // create a new PKCS12 KeyStore KeyStore ks = KeyStore.getInstance("PKCS12", "IAIK"); ks.load(null, null); // add a key entry PrivateKey privateKey = ...; X509Certificate[] certChain = ...; String keyAlias = ...; KeyStore.PrivateKeyEntry keyEntry = new KeyStore.PrivateKeyEntry(privateKey, certChain); P12PasswordProtection pwdProtection = new P12PasswordProtection(password, protectionAlg); ks.setEntry(keyAlias, keyEntry, pwdProtection); // add a cert entry X509Certificate trustedCert = ...; String certAlias = ...; KeyStore.TrustedCertificateEntry certEntry = new KeyStore.TrustedCertificateEntry(trustedCert); P12CertEntryProtection p12Protection = new P12CertEntryProtection(protectionAlg); ks.setEntry(certAlias, certEntry, p12Protection); // store keystore OutputStream os = ...; P12StoreParameter storeParams = new P12StoreParameter(os, password, protectionAlg); ks.store(storeParams);Note that when
adding
a key entry it is immediately encrypted with the specified protection parameters. However, when adding a certificate entry,
the protection parameters are actually applied when finally storing the KeyStore. Thus, when adding more than one certificate
entry and specifying a different protection algorithm for each (or some) certificate entry, the protection algorithm
that is specified for the certificate entry that has been added as last one is used for all certificate
entries. This means that whereas it is possible (though not recommended) to use different
protection algorithms for different key entries, all certificate entries are protected by the same algorithm.
As mentioned above best practice is to only use the "PBES2" or "PBES1" algorithm set
for protecting PKCS#12 KeyStore.Constructor and Description |
---|
P12KeyStore()
Default constructor.
|
Modifier and Type | Method and Description |
---|---|
void |
engineSetEntry(java.lang.String alias,
java.security.KeyStore.Entry entry,
java.security.KeyStore.ProtectionParameter protParam)
Assigns the given keystore entry to the given alias.
|
void |
engineStore(java.security.KeyStore.LoadStoreParameter param)
Uses the given parameters to store this KeyStore.
|
addSunTrustedKeyUsageAttributeToCertificateBags, engineAliases, engineContainsAlias, engineDeleteEntry, engineGetCertificate, engineGetCertificateAlias, engineGetCertificateChain, engineGetCreationDate, engineGetKey, engineIsCertificateEntry, engineIsKeyEntry, engineLoad, engineSetCertificateEntry, engineSetKeyEntry, engineSetKeyEntry, engineSize, engineStore, getUseJKSFallBack, setUseJKSFallBack
public P12KeyStore()
Shall not be used by an application. A PKCS#12 KeyStore shall be created by calling method
KeyStore.getInstance()
:
KeyStore ks = KeyStore.getInstance("PKCS12", "IAIK");
public void engineSetEntry(java.lang.String alias, java.security.KeyStore.Entry entry, java.security.KeyStore.ProtectionParameter protParam) throws java.security.KeyStoreException
P12 password protection parameters
for protecting
key entries or P12 cert entry protection
parameters
for protecting trusted certificate entries.
It is recommended to use "PBES2"
(for security reasons) or
"PBES1"
(for backwards interoperability reasons to PKCS#12
applications that do not support PBES2 yet) as protection algorithm.
When adding a key entry it is immediately encrypted with the specified protection parameters. However, when adding a certificate entry, the protection parameters are actually applied when finally storing the KeyStore. Thus, when adding more than one certificate entry and specifying a different protection algorithm for each (or some) certificate entry, the protection algorithm that is specified for the certificate entry that has been added as last one is used for all certificate entries. This means that whereas it is possible (though not recommended) to use different protection algorithms for different key entries, all certificate entries are protected by the same algorithm. As mentioned above best practice is to only use the "PBES2" or "PBES1" algorithm set for protecting PKCS#12 KeyStore.
engineSetEntry
in class java.security.KeyStoreSpi
alias
- the alias nameentry
- the (key or cert) entry to be associated with the aliasprotParam
- the protection parameters to be used for protecting the
keystore entry (either P12 password protection parameters
for protecting key entries or P12 cert entry protection parameters
for protecting certificate entriesjava.security.KeyStoreException
- if this operation fails, e.g. the protection parameters are invalidpublic void engineStore(java.security.KeyStore.LoadStoreParameter param) throws java.io.IOException, java.security.NoSuchAlgorithmException, java.security.cert.CertificateException
The parameters have to be P12 store parameters
and
have to supply the output stream to which to write this keystore and the password to be
used for protecting the integrity of the keystore. They also may provide the protection algorithm to
be used for calculating a MAC value from the contents of this keystore. The default algorithm is
"PBES2"
using HMAC_SHA256
for calculating the MAC value. For interoperability to PKCS#12 applications that do not support PBES2 yet,
the legacy "PBES1"
algorithm (with HMAC_SHA1
for MAC calculation) maybe used instead of.
engineStore
in class java.security.KeyStoreSpi
param
- the P12 store parameters
specifying the output stream
to which to write this keystore, and the password (and optionally algorithm) to be
used for protecting the intergrity of the keystore
the output stream to which this keystore is written.java.io.IOException
- if there I/O related problem occursjava.security.NoSuchAlgorithmException
- if the appropriate data integrity algorithm could not be foundjava.security.cert.CertificateException
- if any of the certificates included in the keystore data could
not be stored