SAML Security token 取得の実装で、Bouncy Castleライブラリがpom.xmlにありました。
Bouncy Castleライブラリを導入した理由について、本稿で説明します。
POC of consuming Sharepoint onlineでも触れましたが、Sharepoint Onlineサイトはhttpsプロトコルを使用します。
つまり、クライアントとサーバー間でSSL handshakeが発生します。
SSL handshakeでは、TLSバージョン及び、Cipher Suite(暗号スイート)1)の交換が行われます。
Sharepoint OnlineサイトのTLSバージョンと、Cipher Suiteは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です。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ライブラリを導入した理由になります。
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 | FIPS3) 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 Suite4)を提供しますが、利用可能なPlatformに制限5)があります。
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 * <br> * @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のインスタンスを生成する際、ものすごい時間が掛かる場合があります。