====== 3rd Party Security Providerの導入について ====== [[study:java:sharepointonline:implement1|SAML Security token 取得の実装]]で、Bouncy Castleライブラリがpom.xmlにありました。\\ Bouncy Castleライブラリを導入した理由について、本稿で説明します。\\ [[study:java:sharepointonline:poc|POC of consuming Sharepoint online]]でも触れましたが、Sharepoint Onlineサイトはhttpsプロトコルを使用します。\\ つまり、クライアントとサーバー間でSSL handshakeが発生します。\\ SSL handshakeでは、TLSバージョン及び、Cipher Suite(暗号スイート)((暗号スイートは鍵交換アルゴリズム・鍵認証方式・サイファー・メッセージ認証符号の組み合わせです。ECDHE_RSA_WITH_AES_128_GCM_SHA256の場合、ECDHEは鍵交換アルゴリズム、RSAは鍵認証方式、AES-128はサイファー、GCMは暗号利用モード、SHA-256はメッセージ認証符号を表しています。))の交換が行われます。\\ Sharepoint OnlineサイトのTLSバージョンと、Cipher Suiteは[[https://www.ssllabs.com|ssl lab test]]で確認できます。\\ テスト結果で、protocolsとCipher Suites部分を以下に示します。\\ ^Protocols^Support^ ^TLS 1.3^No^ ^TLS 1.2^Yes^ ^TLS 1.1^No^ ^TLS 1.0^No^ ^SSL 3^No^ ^SSL 2^No^ ^Cipher Suites^length^ ^TLS 1.2(suites in server-preferred order)^^ ^TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xc030) ECDH secp384r1 (eq.7680 bits RSA) FS^256^ ^TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(0xc02f) ECDH x25519 (eq.3072 bits RSA) FS^128^ ^TLS_DHE_RSA_WITH_AES_256_GCM_SHA384(0x9f) DH 2048 bits FS^256^ ^TLS_DHE_RSA_WITH_AES_128_GCM_SHA256(0x9e) DH 2048 bits FS^128^ 一方、Java 7が提供するTLS Versionは、TLS1.0, TLS1.1, TLS1.2です。((defaultが1.0なので、CLIENT HELLO送信時TLS1.2を指定する必要があります。))\\ Cipher Suiteについては、以下に示します。 ^Cipher Suites^length^ ^TLS_EMPTY_RENEGOTIATION_INFO_SCSV^ ^ ^SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256^128^ ^SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256^128^ ^SSL_RSA_WITH_AES_128_CBC_SHA256^128^ ^SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA256^128^ ^SSL_ECDH_RSA_WITH_AES_128_CBC_SHA256^128^ ^SSL_DHE_RSA_WITH_AES_128_CBC_SHA256^128^ ^SSL_DHE_DSS_WITH_AES_128_CBC_SHA256^128^ ^SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA^128^ ^SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA^128^ ^SSL_RSA_WITH_AES_128_CBC_SHA^128^ ^SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA^128^ ^SSL_ECDH_RSA_WITH_AES_128_CBC_SHA^128^ ^SSL_DHE_RSA_WITH_AES_128_CBC_SHA^128^ ^SSL_DHE_DSS_WITH_AES_128_CBC_SHA^128^ ^SSL_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA^ ^ ^SSL_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA^ ^ ^SSL_RSA_WITH_3DES_EDE_CBC_SHA^ ^ ^SSL_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA^ ^ ^SSL_ECDH_RSA_WITH_3DES_EDE_CBC_SHA^ ^ ^SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA^ ^ ^SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA^ ^ 見て、気づいたかも知れませんが、Shatepoint onlineサイト要求のCipher Suiteと一致するのが見当たりません。\\ これが、Bouncy Castleライブラリを導入した理由になります。\\ {{keywords>Java add Bouncy Castle Provider, Sharepoint online}} ===== Bouncy Castleライブラリについて ===== Bouncy CastleはJCE(Java Cryptography Enxtension)及びJSSE(Java Security Socket Extension)のProviderです。\\ Bouncy CastleがサポートするCipher Suiteについては、ReferenceのBC-FJA-(D)TLSUserGuide-1.0.9.pdfの「Appendix B – Supported Cipher Suites」部分を参照してください。\\ 該当する部分を以下に示します。 ^Cipher Suite Name^FIPS((FIPS(Federal Information Processing Standards)は、米国連邦政府のコンピューター・システム用に米国連邦情報・技術局 (NIST) によって発行された標準および指針です。 FIPS は、セキュリティーや相互運用性などの、標準を必要とする差し迫った連邦政府の要求があるのに、許容可能な業界標準やソリューションが存在しない場合に作成されます。)) mode?^ ^TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384^N^ ^TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256^Y^ ^TLS_DHE_RSA_WITH_AES_256_GCM_SHA384^N^ ^TLS_DHE_RSA_WITH_AES_128_GCM_SHA256^N^ Bouncy Castle以外にもConscryptというProviderは上記一部分のCipher Suite((TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256))を提供しますが、利用可能なPlatformに制限((Nativeライブラリを利用可能なPlatformは現在次の通りです。Linux x86_64 (64-bit), Mac x86_64 (64-bit), Windows x86 (32-bit), Windows x86_64 (64-bit)。例えば、Linux s390x distributionでは、利用不可なので注意が必要です。))があります。 ===== Mainコード ===== Bouncy Castleを適用するコードを以下に示します。 private static final String JCE_PROVIDER_BOUNCY_CASTLE_FIPS = "BCFIPS"; private static final String BOUNCY_CASTLE_RNG_HYBRID_MODE = "C:HYBRID;ENABLE{ALL};"; private static final byte[] NONCE = Strings.toByteArray("number only used once"); /** * setup BouncyCastleFipsProvider *
* @throws RuntimeException */ public static void setUpProvider() throws RuntimeException { /* * Insert BouncyCastle's FIPS-compliant encryption and SSL providers. */ BouncyCastleFipsProvider _bcFipsProvider = new BouncyCastleFipsProvider(BOUNCY_CASTLE_RNG_HYBRID_MODE); ★Point1 //setup default SecureRandom setDefaultDrbg(); /* * We remove BCFIPS provider pessimistically. This is a no-op if provider does not exist. * This is necessary to always add it to the first position when calling insertProviderAt. * * JavaDoc for insertProviderAt states: * "A provider cannot be added if it is already installed." */ Security.removeProvider(JCE_PROVIDER_BOUNCY_CASTLE_FIPS); Security.insertProviderAt(_bcFipsProvider, 1); ★Point2 }//setUpProvider //set default SecureRandom private static void setDefaultDrbg() { EntropySourceProvider _entSource = new BasicEntropySourceProvider(new SecureRandom(), true); //DRBG(Deterministic Random Bit Generators) FipsDRBG.Builder _drgbBldr = FipsDRBG.SHA512.fromEntropySource(_entSource) .setSecurityStrength(256) .setEntropyBitsRequired(256); CryptoServicesRegistrar.setSecureRandom(_drgbBldr.build(NONCE, true)); ★Point3 }//setDefaultDrbg
★Point1\\ FIPSモードでProviderを生成します。 ★Point2\\ Providerを最優先にするために、位置を指定します。インストール済みの場合は、追加されません。 ★Point3\\ デフォルトのSecureRandomアルゴリズムを登録します。\\ 登録しない場合、SSLContextのインスタンスを生成する際、ものすごい時間が掛かる場合があります。 ===== Reference ===== * [[https://developer.mozilla.org/ja/docs/Glossary/Cipher_suite|Cipher suite (暗号スイート)]] * [[https://downloads.bouncycastle.org/fips-java/BC-FJA-(D)TLSUserGuide-1.0.9.pdf|BC-FJA-(D)TLSUserGuide-1.0.9]] * [[https://www.bouncycastle.org/fips-java/BCFipsIn100.pdf|The Bouncy Castle FIPS Java API in 100 Examples]] * [[https://github.com/google/conscrypt|Conscrypt - A Java Security Provider]] ~~DISCUSSION~~