Utilisation de Java pour établir une connexion sécurisée à MySQL Amazon RDS (SSL / TLS)


J'essaie de me connecter en toute sécurité à Amazon RDS en utilisant JDK 1.8 et MySQL Connector/J version 5.1.23 et je suis confus au sujet des instructions dans la documentation MySQL Connector/J.

Les instructions indiquent de créer un truststore dans le répertoire courant et d'importer le certificat CA du serveur. Lorsque j'exécute la commande ci-dessous, on me demande un mot de passe et je ne sais pas quoi entrer:

keytool -import -alias mysqlServerCACert -file file_location.pem -keystore truststore

Les instructions d'Amazon d'autre part soulignent que les certificats sont signés par une autorité de certification. Le certificat SSL inclut le point de terminaison d'instance de base de données comme nom commun (CN). La clé publique est stockée à http://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem.

Bien que je comprenne le concept de SSL/TSL et de clés privées/publiques, je ne sais pas comment implémenter cela?

Lorsque j'exécute la commande SHOW VARIABLES LIKE 'have_ssl';, je reçois "yes" en tant que valeur. Lorsque je suis connecté à la base de données et que j'exécute SHOW SESSION STATUS LIKE 'Ssl_version'; , je ne reçois pas la valeur de retour.

Comment établir une connexion sécurisée de Java à une base de données MySQL?

Mise à Jour: J'utilise ubuntu et j'ai utilisé le keytool pour générer un fichier truststore.jks dans le répertoire JRE /usr/lib/jvm/java/jre/. J'ai également exécuté la commande suivante: GRANT USAGE ON db_name.* To 'username'@'address' REQUIRE SSL;

Le code ci-dessous est la façon dont je me connecte à la base de données:

import com.mysql.jdbc.Connection;

public class mainClass{

    public static void main(String[] args){

        System.setProperty("javax.net.ssl.trustStore", "/usr/lib/jvm/java/jre/truststore.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "truststore_password");

        final String url = "jdbc:mysql://mysql_rds_enpoint:port/db_name?verifyServerCertificate=true&useSSL=true&requireSSL=true";
        final String username = "username";
        final String password = "password";

        Connection mysqlConnection = null;
        mysqlConnection = (Connection) mysqlMethods.connectToMysql(url, username, password);
    }
}

Le code ci-dessus produit un message Communications link failure et The last packet successfully received from the server was 24 milliseconds ago. The last packet sent successfully to the server was 24 milliseconds ago. Je suis capable de me connecter avec succès lorsque ?verifyServerCertificate=true&useSSL=true&requireSSL=true est supprimé de l'uri et que REQUIRE SSL est supprimé des autorisations utilisateur.

Mise à Jour 2: J'ai ramené le code à l'essentiel et quand j'exécute le code ci-dessous:

import java.sql.DriverManager;
import java.sql.SQLException;

class testClass{

    public static void main(String[] args){
        System.setProperty("javax.net.ssl.trustStore", "/usr/lib/jvm/java/jre/truststore.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "truststore_password");

        final String url = "jdbc:mysql://mysql_rds_enpoint:port/db_name?verifyServerCertificate=true&useSSL=true&requireSSL=true";
        final String username = "username";
        final String password = "password";

        try {
            Object connection = DriverManager.getConnection(url, username, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Je reçois le message d'erreur suivant:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 206 milliseconds ago.  The last packet sent successfully to the server was 203 milliseconds ago.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:389)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1038)
    at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:110)
    at com.mysql.jdbc.MysqlIO.negotiateSSLConnection(MysqlIO.java:4760)
    at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1629)
    at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1206)
    at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2239)
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2270)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2069)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:794)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:44)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:389)
    at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:399)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:325)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)
    at apples.main(mainClass.java:18)

Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1906)
    at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1889)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1410)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:95)
    ... 18 more

Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:90)
    at sun.security.validator.Validator.getInstance(Validator.java:179)
    at sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:312)
    at sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:171)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:184)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1488)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    ... 20 more

Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
    at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
    at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120)
    at java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104)
    at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:88)
    ... 32 more

J'ai également confirmé utiliser Workbench et le .fichier pem que l'utilisateur peut se connecter en utilisant SSL.

Mise à jour 3: Informations de débogage après avoir défini javax. net. debug sur ssl:

keyStore is : 
keyStore type is : jks
keyStore provider is : 
init keystore
init keymanager of type SunX509
trustStore is: /usr/lib/jvm/java/jre/truststore.jks
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:
  Subject: CN=aws.amazon.com/rds/, OU=RDS, O=Amazon.com, L=Seattle, ST=Washington, C=US
  Issuer:  CN=aws.amazon.com/rds/, OU=RDS, O=Amazon.com, L=Seattle, ST=Washington, C=US
  Algorithm: RSA; Serial number: 0xe775b657e21a8128
  Valid from Tue Apr 06 08:44:31 AEST 2010 until Sun Apr 05 08:44:31 AEST 2015

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1425012760 bytes = { 250, 182, 202, 168, 139, 248, 125, 121, 251, 188, 182, 110, 1, 234, 29, 105, 158, 219, 212, 122, 105, 57, 87, 80, 44, 141, 121, 154 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [type=host_name (0), value=abcd.abcd123.ap-southeast-1.rds.amazonaws.com]
***
main, WRITE: TLSv1 Handshake, length = 202
main, READ: TLSv1 Handshake, length = 74
*** ServerHello, TLSv1
RandomCookie:  GMT: -1571637097 bytes = { 78, 228, 80, 30, 162, 233, 208, 59, 196, 166, 88, 129, 155, 99, 123, 252, 123, 153, 129, 25, 144, 235, 185, 112, 68, 79, 2, 79 }
Session ID:  {104, 7, 155, 31, 238, 102, 222, 218, 193, 219, 108, 206, 57, 235, 53, 253, 1, 200, 64, 46, 92, 60, 63, 251, 142, 106, 233, 54, 27, 110, 79, 128}
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
***
Warning: No renegotiation indication extension in ServerHello
%% Initialized:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
** TLS_RSA_WITH_AES_128_CBC_SHA
main, READ: TLSv1 Handshake, length = 1057
*** Certificate chain
chain [0] = [
[
  Version: V3
  Subject: C=US, ST=Washington, L=Seattle, O=Amazon.com, OU=RDS, CN=sifrmedium.cove4uttgoa2.ap-southeast-2.rds.amazonaws.com
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 1024 bits
  modulus: 7182371456073335432842458631460148573771628715802835656528548198324749485547005738326606223242830258829871966755842342342342344059076665280539770508892924695580383343581127930380098999434723444448883595421930164673020286553920728427
  public exponent: 65537
  Validity: [From: Sun Jun 21 11:55:57 AEST 2015,
               To: Fri Mar 06 09:03:24 AEDT 2020]
  Issuer: CN=Amazon RDS ap-southeast-2 CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", L=Seattle, ST=Washington, C=US
  SerialNumber: [    810c7b2c 621bcf07 366cad3b ab405b]

Certificate Extensions: 2
[1]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 89 50 9D 8D 0A 1D 42 A7   D6 36 2E 99 27 44 61 FC  .P.......6..'Ia.
0010: 23 FC D7 F0                                        #...
]
[CN=Amazon RDS Root CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", L=Seattle, ST=Washington, C=US]
SerialNumber: [    46]
]

[2]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 0C 5C 64 D5 CE C4 27 13   34 01 A0 0D 64 8C B1 C9  .\d...'.4...d<..
0010: 4D 6C 3D 16                                        M\=.
]
]

]
  Algorithm: [SHA1withRSA]
  Signature:
0000: 16 53 AA 7A 55 49 84 87   5C EC 49 B9 BD 51 98 83  .S.zUI..\.I..Q..
0010: BA 91 84 72 29 77 19 6C   F7 CA 0A 36 09 AC 70 F4  ...r)w.l...6..p.
0020: 8A 2C 90 FD 36 3D 3D CD   E9 BA 2C 5C 95 C3 79 78  .,..6==...,\..yx
0030: CE FA 46 A0 3D 77 31 11   E3 5B 9C 84 AF 4D 60 51  ..F.=w1..[...M`Q
0040: 80 52 04 1E 65 4D 6E 5B   92 E1 69 79 12 8E 56 0F  .R..eMn[..iy..V.
0050: 83 E4 F8 31 4E A7 65 4E   C2 BB 97 A8 B4 67 79 F4  ...1N.eN.....gy.
0060: CD 37 F7 00 A5 42 B9 E0   CB D9 CA 81 EC E3 A3 E3  .7...B..........
0070: FB 05 40 2F 9A 4B 5D AE   7C 30 F4 BA ED DC 74 AC  ..@/.K]..0....t.
0080: 89 30 AD 13 26 F7 88 09   66 01 E1 4B 3A 8C B1 3D  .0..&...f..K:..=
0090: 28 6F 74 1D B0 00 25 FB   9B 1E 00 8D F1 1F 83 84  (ot...%.........
00A0: CE D7 92 39 78 C4 70 26   8E 3C 05 1C 10 3C A3 E0  ...9x.p&.<...<..
00B0: CC 30 F0 A0 68 B1 26 C4   23 AC C0 C6 8A 27 DB 3C  .0..h.&.#....'.<
00C0: 7F 38 DD EE 92 1B A3 A4   99 13 9F 80 62 66 C8 F0  .8..........bf..
00D0: 46 25 38 C3 99 0A A2 A7   04 E5 FF 4D 31 2B E4 82  F%8........M1+..
00E0: BE D9 D5 07 28 96 17 07   30 B9 EC BA 26 F3 7B C3  ....(...0...&...
00F0: 1A CF 13 73 58 96 F2 87   3F FD 86 09 35 FA A3 7B  ...sX...?...5...

]
***
%% Invalidated:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
main, SEND TLSv1 ALERT:  fatal, description = certificate_unknown
main, WRITE: TLSv1 Alert, length = 2
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
main, called close()
main, called closeInternal(true)
Author: hjpotter92, 2015-08-22

3 answers

Lorsque vous exécutez la commande ci-dessous et qu'on vous demande le mot de passe, vous devez taper "changeit". C'est le mot de passe par défaut pour le magasin de clés

keytool -import -alias mysqlServerCACert -file file_location.pem -keystore truststore

Ensuite, assurez-vous que l'utilisateur mysql que vous utilisez est configuré pour exiger SSL comme ci-dessous

GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' REQUIRE SSL;

Ensuite, assurez-vous que le bundle rds que vous avez téléchargé à partir de http://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem{[10] } est importé sur les cacerts java par défaut du serveur d'applications qui tente de se connecter à AWS RDS.

Enfin, vous devez ajouter les trois propriétés ci-dessous avec la valeur 'true' à votre URL mysql

?verifyServerCertificate=true&useSSL=true&requireSSL=true

Par exemple:

final String url = "jdbc:mysql://mysql_rds_enpoint:port/db_name?verifyServerCertificate=true&useSSL=true&requireSSL=true";

J'espère que cela aide!

 8
Author: virag, 2015-10-07 22:05:05

Java keytool n'importe qu'un seul certificat à la fois, mais le bundle RDS combined CA contient de nombreux certificats CA. Vous devrez importer chaque certificat du bundle séparément. Lorsque vous essayez d'importer le bundle, il importe seulement un certificat, qui peut ne pas être l'autorité de certification racine que vous devez faire confiance à l'instance RDS.

Sous linux, vous pouvez diviser le pem avec l'outil CSPLIT:

csplit -b %02d.pem -z rds-combined-ca-bundle.pem /-----BEGIN/ {*}

Ensuite, vous devez importer chaque pem dans votre magasin de clés séparément.

 5
Author: Alec Henninger, 2016-05-17 19:30:19

Sur Mac OS X et FreeBSD, la procédure est similaire. Cela décomposera et importera tous les certificats du rds-combined-cabundle.pem. Vous devrez changer le chemin pour OS X, mais sinon c'est identique.

split -p "-----BEGIN CERTIFICATE-----" rds-combined-ca-bundle.pem individual-

find . -iname 'individual*' -exec keytool -import -file {} -alias {} -storepass changeit -keystore /usr/local/openjdk8/jre/lib/security/cacerts \;
 3
Author: Lucas Holt, 2017-06-20 20:45:53