目次

3rd Party Security Providerの導入について

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部分を以下に示します。

ProtocolsSupport
TLS 1.3No
TLS 1.2Yes
TLS 1.1No
TLS 1.0No
SSL 3No
SSL 2No
Cipher Suiteslength
TLS 1.2(suites in server-preferred order)
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xc030) ECDH secp384r1 (eq.7680 bits RSA) FS256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(0xc02f) ECDH x25519 (eq.3072 bits RSA) FS128
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384(0x9f) DH 2048 bits FS256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256(0x9e) DH 2048 bits FS128

一方、Java 7が提供するTLS Versionは、TLS1.0, TLS1.1, TLS1.2です。2)
Cipher Suiteについては、以下に示します。

Cipher Suiteslength
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256128
SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256128
SSL_RSA_WITH_AES_128_CBC_SHA256128
SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA256128
SSL_ECDH_RSA_WITH_AES_128_CBC_SHA256128
SSL_DHE_RSA_WITH_AES_128_CBC_SHA256128
SSL_DHE_DSS_WITH_AES_128_CBC_SHA256128
SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA128
SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA128
SSL_RSA_WITH_AES_128_CBC_SHA128
SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA128
SSL_ECDH_RSA_WITH_AES_128_CBC_SHA128
SSL_DHE_RSA_WITH_AES_128_CBC_SHA128
SSL_DHE_DSS_WITH_AES_128_CBC_SHA128
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ライブラリについて

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 NameFIPS3) mode?
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384N
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256Y
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384N
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256N

Bouncy Castle以外にもConscryptというProviderは上記一部分のCipher Suite4)を提供しますが、利用可能なPlatformに制限5)があります。

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
   * <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のインスタンスを生成する際、ものすごい時間が掛かる場合があります。

Reference

1)
暗号スイートは鍵交換アルゴリズム・鍵認証方式・サイファー・メッセージ認証符号の組み合わせです。ECDHE_RSA_WITH_AES_128_GCM_SHA256の場合、ECDHEは鍵交換アルゴリズム、RSAは鍵認証方式、AES-128はサイファー、GCMは暗号利用モード、SHA-256はメッセージ認証符号を表しています。
2)
defaultが1.0なので、CLIENT HELLO送信時TLS1.2を指定する必要があります。
3)
FIPS(Federal Information Processing Standards)は、米国連邦政府のコンピューター・システム用に米国連邦情報・技術局 (NIST) によって発行された標準および指針です。 FIPS は、セキュリティーや相互運用性などの、標準を必要とする差し迫った連邦政府の要求があるのに、許容可能な業界標準やソリューションが存在しない場合に作成されます。
4)
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
5)
Nativeライブラリを利用可能なPlatformは現在次の通りです。Linux x86_64 (64-bit), Mac x86_64 (64-bit), Windows x86 (32-bit), Windows x86_64 (64-bit)。例えば、Linux s390x distributionでは、利用不可なので注意が必要です。