413 lines
13 KiB
Markdown
413 lines
13 KiB
Markdown
|
||
## wolfCrypt JCE Provider
|
||
|
||
The wolfCrypt JCE Provider is currently set up to be compiled together into
|
||
the same JAR file as the normal wolfcrypt-jni classes.
|
||
|
||
The wolfCrypt JCE Provider is located in the following package:
|
||
|
||
com.wolfssl.wolfcrypt.jce.provider
|
||
|
||
Compiling the JCE provider is done using the same instructions as
|
||
wolfcrypt-jni. Follow direction in the README.md for compiling the package,
|
||
but make sure to use one of the following "ant" build targets:
|
||
|
||
build-jce-debug
|
||
build-jce-release
|
||
|
||
This JCE provider has been tested on OSX (Oracle JVM), Linux (OpenJDK),
|
||
and Android platforms.
|
||
|
||
Pre-compiled and signed wolfCrypt JNI/JCE JAR's are included with the stable
|
||
releases of the JCE provider. See below for more details.
|
||
|
||
### System and Security Property Support
|
||
---------
|
||
|
||
wolfJCE supports the following System and Security properties for behavior
|
||
customization and debugging.
|
||
|
||
#### Security Property Support
|
||
|
||
The following Java Security properties can be set in the `java.security`
|
||
file for JCE provider customization:
|
||
|
||
| Security Property | Default | To Enable | Description |
|
||
| --- | --- | --- | --- |
|
||
| wolfjce.wks.iterationCount | 210,000 | Numeric | PBKDF2 iteration count (10,000 minimum) |
|
||
| wolfjce.wks.maxCertChainLength | 100 | Integer | Max cert chain length |
|
||
| wolfjce.mapJKStoWKS | UNSET | true | Register fake JKS KeyStore service mapped to WKS |
|
||
| wolfjce.mapPKCS12toWKS | UNSET | true | Register fake PKCS12 KeyStore service mapped to WKS |
|
||
|
||
**wolfjce.mapJKStoWKS** - this Security property should be used with caution.
|
||
When enabled, this will register a "JKS" KeyStore type in wolfJCE, which means
|
||
calling applications using `KeyStore.getInstance("JKS")` will get a KeyStore
|
||
implementation from wolfJCE. BUT, this KeyStore type will actually be a
|
||
WolfSSLKeyStore (WKS) type internally. Loading actual JKS files will fail.
|
||
This can be helpful when FIPS compliance is required, but existing code gets
|
||
a JKS KeyStore instance - and this assumes the caller has the flexibility to
|
||
actually load a real WKS KeyStore file into this KeyStore object. If this
|
||
property is being set at runtime programatically, the wolfJCE provider services
|
||
will need to be refreshed / reloaded, by doing:
|
||
|
||
```
|
||
WolfCryptProvider prov = (WolfCryptProvider)Security.getProvider("wolfJCE");
|
||
prov.refreshServices();
|
||
```
|
||
|
||
**wolfjce.mapPKCS12toWKS** - this Security property should be used with caution.
|
||
When enabled, this will register a "PKCS12" KeyStore type in wolfJCE, which
|
||
means calling applications using `KeyStore.getInstance("PKCS12")` will get a
|
||
KeyStore implementation from wolfJCE. BUT, this KeyStore type will actually be a
|
||
WolfSSLKeyStore (WKS) type internally. Loading actual PKCS12 files will fail.
|
||
This can be helpful when FIPS compliance is required, but existing code gets
|
||
a PKCS12 KeyStore instance - and this assumes the caller has the flexibility to
|
||
actually load a real WKS KeyStore file into this KeyStore object. If this
|
||
property is being set at runtime programatically, the wolfJCE provider services
|
||
will need to be refreshed / reloaded, by doing:
|
||
|
||
```
|
||
WolfCryptProvider prov = (WolfCryptProvider)Security.getProvider("wolfJCE");
|
||
prov.refreshServices();
|
||
```
|
||
|
||
#### System Property Support
|
||
|
||
The following Java System properties can be set on the command line or
|
||
programatically for JCE provider customization:
|
||
|
||
| System Property | Default | To Enable | Description |
|
||
| --- | --- | --- | --- |
|
||
| wolfjce.debug | "false" | "true" | Enable wolfJCE debug logging |
|
||
|
||
### Algorithm Support:
|
||
---------
|
||
|
||
The JCE provider currently supports the following algorithms:
|
||
|
||
MessageDigest Class
|
||
MD5
|
||
SHA-1
|
||
SHA-224
|
||
SHA-256
|
||
SHA-384
|
||
SHA-512
|
||
SHA3-224
|
||
SHA3-256
|
||
SHA3-384
|
||
SHA3-512
|
||
|
||
SecureRandom Class
|
||
DEFAULT (maps to HashDRBG)
|
||
HashDRBG
|
||
|
||
Cipher Class
|
||
AES/CBC/NoPadding
|
||
AES/CBC/PKCS5Padding
|
||
AES/GCM/NoPadding
|
||
DESede/CBC/NoPadding
|
||
RSA
|
||
RSA/ECB/PKCS1Padding
|
||
|
||
Mac Class
|
||
HmacMD5
|
||
HmacSHA1
|
||
HmacSHA224
|
||
HmacSHA256
|
||
HmacSHA384
|
||
HmacSHA512
|
||
HmacSHA3-224
|
||
HmacSHA3-256
|
||
HmacSHA3-384
|
||
HmacSHA3-512
|
||
|
||
Signature Class
|
||
MD5withRSA
|
||
SHA1withRSA
|
||
SHA224withRSA
|
||
SHA256withRSA
|
||
SHA384withRSA
|
||
SHA512withRSA
|
||
SHA3-224withRSA
|
||
SHA3-256withRSA
|
||
SHA3-384withRSA
|
||
SHA3-512withRSA
|
||
SHA1withECDSA
|
||
SHA224withECDSA
|
||
SHA256withECDSA
|
||
SHA384withECDSA
|
||
SHA512withECDSA
|
||
SHA3-224withECDSA
|
||
SHA3-256withECDSA
|
||
SHA3-384withECDSA
|
||
SHA3-512withECDSA
|
||
|
||
KeyAgreement Class
|
||
DiffieHellman
|
||
DH
|
||
ECDH
|
||
|
||
KeyGenerator
|
||
AES
|
||
HmacSHA1
|
||
HmacSHA224
|
||
HmacSHA256
|
||
HmacSHA384
|
||
HmacSHA512
|
||
|
||
KeyPairGenerator Class
|
||
RSA
|
||
EC
|
||
DH
|
||
|
||
CertPathValidator Class
|
||
PKIX
|
||
|
||
SecretKeyFactory
|
||
PBKDF2WithHmacSHA1
|
||
PBKDF2WithHmacSHA224
|
||
PBKDF2WithHmacSHA256
|
||
PBKDF2WithHmacSHA384
|
||
PBKDF2WithHmacSHA512
|
||
PBKDF2WithHmacSHA3-224
|
||
PBKDF2WithHmacSHA3-256
|
||
PBKDF2WithHmacSHA3-384
|
||
PBKDF2WithHmacSHA3-512
|
||
|
||
KeyStore
|
||
WKS
|
||
|
||
### SecureRandom.getInstanceStrong()
|
||
|
||
When registered as the highest priority security provider, wolfJCE will provide
|
||
`SecureRandom` with the underlying `HashDRBG` algorithm.
|
||
|
||
Java applications can alternatively call the `SecureRandom.getInstanceStrong()`
|
||
API to get a "known strong SecureRandom implementation". To provide this
|
||
with wolfJCE, the `java.security` file needs to be modified by setting the
|
||
`securerandom.strongAlgorithms` property to:
|
||
|
||
```
|
||
securerandom.strongAlgorithms=HashDRBG:wolfJCE
|
||
```
|
||
|
||
Note that the `securerandom.source` property in `java.security` has no affect
|
||
on the wolfJCE provider.
|
||
|
||
### WolfSSLKeyStore (WKS) Implementation Details and Usage
|
||
|
||
wolfJCE implements one custom KeyStore class named WolfSSLKeyStore, represented
|
||
as "WKS". If wolfJCE has been installed as a Security provider, this KeyStore
|
||
can be used with:
|
||
|
||
```
|
||
KeyStore store = KeyStore.getInstance("WKS");
|
||
```
|
||
|
||
#### Algorithm Use and FIPS 140-2 / 140-3 Compatibility
|
||
|
||
The WKS KeyStore has been designed to be compatible with wolfCrypt
|
||
FIPS 140-2 and 140-3.
|
||
|
||
PrivateKey and SecretKey objects stored are protected inside the KeyStore
|
||
using AES-CBC-256 with HMAC-SHA512 in an Encrypt-then-MAC manner. PKCS#5
|
||
PBKDF2-HMAC-SHA512 is used to generate 96 bytes of key material which is split
|
||
between a 32-byte AES-CBC-256 key and 64-byte HMAC-SHA512 key.
|
||
|
||
PBKDF2 salt is 16 bytes, randomly generated for each key storage operation
|
||
PBKDF2 iteration count defaults to 210,000 (current OWASP recommendation), but
|
||
is user overridable with wolfjce.wks.iterationCount Security property in
|
||
java.security file. User password is converted from char[] to byte[] using
|
||
UTF-8, consistent with how SunJCE uses UTF-8 for PBKDF2 SecretKeyFactory.
|
||
AES-CBC IV is randomly generated for each key storage operation
|
||
|
||
This KeyStore uses a different format that is not directly compatible with
|
||
existing formats (ex: JKS, PKCS12, etc). Other KeyStore types will need to be
|
||
converted over to WKS KeyStore objects for FIPS compliant use with wolfCrypt
|
||
FIPS 140-2/3.
|
||
|
||
#### Stored Object Compatibility
|
||
|
||
The WKS KeyStore supports storage of PrivateKey, Certificate, and
|
||
SecretKey objects.
|
||
|
||
#### Converting Other KeyStore Formats to WKS
|
||
|
||
The Java `keytool` application can be used to convert between KeyStore formats.
|
||
This can be easily used for example to convert a JKS KeyStore into a WKS
|
||
format KeyStore.
|
||
|
||
The following example command would convert a KeyStore in JKS format named
|
||
`server.jks` to a KeyStore in WKS format named `server.wks`:
|
||
|
||
```
|
||
keytool -importkeystore -srckeystore server.jks -destkeystore server.wks \
|
||
-srcstoretype JKS -deststoretype WKS \
|
||
-srcstorepass "pass" -deststorepass "pass" \
|
||
-provider com.wolfssl.provider.jce.WolfCryptProvider \
|
||
--providerpath /path/to/wolfcrypt-jni.jar
|
||
```
|
||
|
||
To list entries inside a WKS keystore using the `keytool`, a command
|
||
similar to the following can be used (with the `-list` option):
|
||
|
||
```
|
||
keytool -list -provider com.wolfssl.provider.jce.WolfCryptProvider \
|
||
--providerpath /path/to/wolfcrypt-jni.jar \
|
||
-storetype WKS -storepass "pass" -keystore server.wks
|
||
```
|
||
|
||
If running the above commands gives an error about the native wolfcryptjni
|
||
shared library not being found, you may need to add the library location
|
||
to `LD_LIBRARY_PATH` (Linux) or `DYLD_LIBRARY_PATH` (Mac OSX), ie:
|
||
|
||
```
|
||
export LD_LIBRARY_PATH=/path/to/libwolfcryptjni.so:$LD_LIBRARY_PATH
|
||
```
|
||
|
||
#### Converting System cacerts to WKS Format KeyStore
|
||
|
||
For FIPS compatibility, users who do not want to use non-wolfSSL KeyStore
|
||
implementations (ex: JKS) may need to convert the system cacerts or
|
||
jssecacerts KeyStore to WKS format. This can be done using the keytool
|
||
command as described above (default password for cacerts is 'changeit'), or
|
||
the helper script located in this package at:
|
||
|
||
```
|
||
examples/certs/systemcerts/system-cacerts-to-wks.sh
|
||
```
|
||
|
||
This is a shell script that takes no arguments. It tries to detect the
|
||
location of the active Java installation and converts `cacerts` and/or
|
||
`jssecacerts` to WKS format if they are found. Converted KeyStores are placed
|
||
under the same directory as the script, specifically:
|
||
|
||
```
|
||
examples/certs/systemcerts/cacerts.wks
|
||
examples/certs/systemcerts/jssecacerts.wks
|
||
```
|
||
|
||
#### Design Notes
|
||
|
||
More complete design documentation can be found in
|
||
[docs/WolfSSLKeyStore.md](./docs/design/WolfSSLKeyStore.md).
|
||
|
||
### Example / Test Code
|
||
---------
|
||
|
||
JUnit test code can act as a good usage reference, and is located under the
|
||
`./src/test/java/com/wolfssl/provider/jce/test/` directory for each wolfJCE
|
||
engine class.
|
||
|
||
There are some JCE examples located under the `examples/provider` directory,
|
||
including:
|
||
|
||
**ProviderTest**
|
||
|
||
This is an example that prints out all Security providers that are registered
|
||
in the system. It then programatically registers wolfJCE as the highest-level
|
||
provider and prints out the list again.
|
||
|
||
This example will be built when using the following ant targets:
|
||
|
||
```
|
||
$ ant build-jce-debug
|
||
$ ant build-jce-release
|
||
```
|
||
|
||
The example can then be run using:
|
||
|
||
```
|
||
$ ./examples/provider/ProviderTest.sh
|
||
```
|
||
|
||
**CryptoBenchmark**
|
||
|
||
This example benchmarks the performance of cryptographic operations using the
|
||
wolfJCE provider. It tests AES-CBC with 256-bit key encryption/decryption
|
||
operations.
|
||
|
||
Build and run:
|
||
|
||
```
|
||
# From wolfcrypt-jni root directory
|
||
make # Build native library
|
||
ant build-jce-release # Build JCE JAR
|
||
|
||
# Run benchmark
|
||
./examples/provider/CryptoBenchmark.sh
|
||
```
|
||
|
||
This script requires for `JAVA_HOME` to be set.
|
||
|
||
For Bouncy Castle comparison testing:
|
||
|
||
CryptoBenchmark.sh will prompt with the following:
|
||
|
||
```
|
||
Would you like to download Bouncy Castle JARs? (y/n)
|
||
```
|
||
|
||
If you respond with 'y', the script will download the Bouncy Castle JARs and
|
||
run the benchmark with Bouncy Castle. At the end of the benchmark, the script
|
||
will prompt whether or not to remove the Bouncy Castle JAR files.
|
||
|
||
If you prefer to download the JARs manually, follow the instructions below:
|
||
|
||
Visit [bouncy-castle-java](https://www.bouncycastle.org/download/bouncy-castle-java/)
|
||
|
||
Download:
|
||
|
||
```
|
||
bcprov-jdk18on-1.79.jar # Bouncy Castle Provider
|
||
bctls-jdk18on-1.79.jar # Bouncy Castle DTLS/TLS API/JSSE Provider
|
||
```
|
||
|
||
Copy jar files to wolfcrypt-jni/lib/:
|
||
|
||
```
|
||
cp bcprov-jdk18on-1.79.jar wolfcrypt-jni/lib
|
||
cp bctls-jdk18on-1.79.jar wolfcrypt-jni/lib
|
||
```
|
||
|
||
### JAR Code Signing
|
||
---------
|
||
|
||
The Oracle JDK/JVM requires that JCE providers who implement several of the
|
||
classes above be signed by a code signing certificate issued by Oracle.
|
||
|
||
Full details on obtaining a JCE Code Signing Certifciate can be found here:
|
||
|
||
http://www.oracle.com/technetwork/java/javase/tech/getcodesigningcertificate-361306.html
|
||
|
||
For instructions on signing the "wolfcrypt-jni.jar" file generated by the
|
||
ant build system, please see the main README.md included in this package.
|
||
|
||
### Using a Pre-Signed JAR File
|
||
|
||
wolfSSL (company) has it's own set of code signing certificates from Oracle
|
||
that allow wolfJCE to be authenticated in the Oracle JDK. With each release
|
||
of wolfJCE, wolfSSL ships a couple pre-signed versions of the
|
||
‘wolfcrypt-jni.jar”, located at:
|
||
|
||
wolfcrypt-jni-X.X.X/lib/signed/debug/wolfcrypt-jni.jar
|
||
wolfcrypt-jni-X.X.X/lib/signed/release/wolfcrypt-jni.jar
|
||
|
||
This pre-signed JAR can be used with the JUnit tests, without having to
|
||
re-compile the Java source files. To run the JUnit tests against this
|
||
JAR file:
|
||
|
||
$ cd wolfcrypt-jni-X.X.X
|
||
$ cp ./lib/signed/release/wolfcrypt-jni.jar ./lib
|
||
$ ant test
|
||
|
||
|
||
### Support
|
||
---------
|
||
|
||
Please email support@wolfssl.com with any questions or feedback.
|
||
|
||
The wolfJCE User Manual (PDF), available from the wolfSSL website contains
|
||
additional details on using the wolfCrypt JCE provider.
|
||
|