Oracle データベースに接続しようとしたとき、次のエラーメッセージが表示されることがあります。
ORA-28040: No matching authentication protocol
このエラーは、クライアントとサーバーでサポートする認証プロトコルのバージョンが一致しない場合に発生します。たとえば Oracle 10g の古いクライアントから Oracle 19c のサーバーに接続しようとした場合や、パスワードバーニファイア(ハッシュ方式)が古い形式のまま残っている場合に発生します。
本記事では、ORA-28040 の発生メカニズムから、パスワードバーニファイアの確認・再設定、SQLNET.ORA パラメータの設定、クライアント別の対処法(JDBC・SQL*Plus・ODP.NET 等)、そしてセキュリティリスクを考慮した推奨対処順序まで体系的に解説します。
・ORA-28040 が発生する仕組み(認証プロトコルバージョンとは何か)
・Oracle バージョン別 ALLOWED_LOGON_VERSION デフォルト値の一覧
・パスワードバーニファイア(PASSWORD_VERSIONS)の確認方法
・SQLNET.ORA の ALLOWED_LOGON_VERSION_SERVER / CLIENT の設定方法
・パスワード再設定でバーニファイアを更新する方法
・JDBC・SQL*Plus・ODP.NET 等クライアント別の対処法
・セキュリティリスクを踏まえた推奨対処順序
・よくあるエラーパターンと対処法
ORA-28040 の発生原因
Oracle の認証プロトコルは、バージョンごとにパスワードのハッシュ方式が強化されてきました。クライアントとサーバーの間で、双方がサポートする認証プロトコルバージョンに重なりがないとき ORA-28040 が発生します。
認証プロトコルバージョンの変遷
| バージョン値 | Oracle リリース | パスワードハッシュ方式 | 概要 |
|---|---|---|---|
| 8 | 8i 以前 | DES ベース | 最も古い形式。セキュリティ上は脆弱 |
| 10 | 10g | SHA-1 ベース(Case-Insensitive) | 大文字小文字を区別しないハッシュ |
| 11 | 11g | SHA-1 + ソルト(Case-Sensitive) | 大文字小文字を区別。O5LOGON プロトコル |
| 12 | 12c 以降 | SHA-2 (SHA-512) + PBKDF2 | 最も安全。Oracle 12c で追加 |
| 12a | 12.1.0.2+ | SHA-2 (SHA-512) 改良版 | 12c Release 2 以降のデフォルト |
新しいサーバーが「バージョン 12 以上のみ許可」と設定している場合、バージョン 10 までしかサポートしない古いクライアントは接続できず ORA-28040 が発生します。
発生する典型的なパターン
| パターン | クライアント側 | サーバー側 | 結果 |
|---|---|---|---|
| ① | Oracle 10g Client / 古い JDBC ドライバ(ojdbc14.jar など) | Oracle 19c / 21c(デフォルト設定) | ORA-28040 |
| ② | Oracle 11g Client | Oracle 12c 以降(ALLOWED_LOGON_VERSION_SERVER=12a) | ORA-28040 |
| ③ | Oracle 12c 以降の Client | Oracle 19c だがユーザーのパスワードバーニファイアが 10g 形式のみ | ORA-28040 |
| ④ | サードパーティツール(古いバージョン) | Oracle 19c / 21c | ORA-28040 |
クライアントもサーバーも新しいのに ORA-28040 が出る場合、原因はユーザーのパスワードバーニファイアが古い形式のままであることが多いです。Oracle のアップグレード前に作成されたユーザーは、古いハッシュ方式のパスワードのまま残っている場合があります。
Oracle バージョン別 ALLOWED_LOGON_VERSION デフォルト値
Oracle のバージョンによって SQLNET.ALLOWED_LOGON_VERSION_SERVER のデフォルト値が異なります。アップグレード時にこの値が変わることで、これまで接続できていたクライアントが ORA-28040 になるのが最も多いケースです。
| Oracle バージョン | ALLOWED_LOGON_VERSION_SERVER デフォルト | ALLOWED_LOGON_VERSION_CLIENT デフォルト | 接続可能な最古のクライアント |
|---|---|---|---|
| 11g R2 | 8 | 8 | Oracle 8i 以降 |
| 12c R1 (12.1) | 11 | 11 | Oracle 11g 以降 |
| 12c R2 (12.2) | 12 | 12 | Oracle 12c 以降 |
| 18c | 12 | 12 | Oracle 12c 以降 |
| 19c | 12 | 12 | Oracle 12c 以降 |
| 21c | 12a | 12a | Oracle 12.1.0.2+ 以降 |
Oracle 11g(デフォルト: 8)→ 12c(デフォルト: 11)にアップグレードすると、10g 以前のクライアントが ORA-28040 で接続不可になります。さらに 12c R2 / 19c(デフォルト: 12)にすると、11g クライアントも接続不可になります。アップグレード計画では、すべてのクライアントのバージョンを事前に調査してください。
パスワードバーニファイア(PASSWORD_VERSIONS)の確認
DBA_USERS ビューの PASSWORD_VERSIONS 列で、各ユーザーのパスワードがどのハッシュ方式で保存されているかを確認できます。
-- 全ユーザーのパスワードバーニファイアを確認
SELECT username, account_status, password_versions
FROM dba_users
WHERE username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB')
ORDER BY username;
| PASSWORD_VERSIONS の値 | 含まれるハッシュ方式 | 対応するプロトコルバージョン |
|---|---|---|
| 10G 11G 12C | DES + SHA-1 + SHA-512 | 8, 10, 11, 12 すべてに対応 |
| 11G 12C | SHA-1 + SHA-512 | 11, 12 に対応(10g 以前のクライアントは不可) |
| 12C | SHA-512 のみ | 12 以上にのみ対応(11g 以前のクライアントは不可) |
| 10G 11G | DES + SHA-1 | 8, 10, 11 に対応(古い形式のみ、12 には対応しない場合がある) |
| 10G | DES のみ | 8, 10 のみ対応(最も古い。早急に再設定が必要) |
-- 12C バーニファイアを持たないユーザーを検出(要パスワード再設定) SELECT username, account_status, password_versions FROM dba_users WHERE password_versions NOT LIKE '%12C%' AND account_status = 'OPEN' ORDER BY username;
そのユーザーは古いハッシュ方式のパスワードしか持っていません。サーバーの ALLOWED_LOGON_VERSION_SERVER が 12 以上だと、クライアントが新しくても ORA-28040 が発生します。パスワードを再設定して新しいバーニファイアを生成する必要があります(後述)。
対処法(推奨順序)
ORA-28040 の対処法は複数ありますが、セキュリティリスクを考慮した推奨順序で解説します。原則として「セキュリティレベルを下げる」対処(SQLNET.ORA の値を下げる)は最後の手段としてください。
対処法①:クライアントをアップグレードする(最も推奨)
古いクライアントを最新バージョンにアップグレードすれば、新しい認証プロトコルに対応できます。これが最も安全な対処法です。
| クライアント種別 | 推奨バージョン |
|---|---|
| Oracle Instant Client | 19c 以降(19.x は長期サポート) |
| JDBC ドライバ(ojdbc) | ojdbc8.jar(JDK 8+)/ ojdbc11.jar(JDK 11+) |
| SQL*Plus | Oracle 19c 以降の SQL*Plus |
| ODP.NET | Oracle.ManagedDataAccess 21.x 以降 |
| SQL Developer | バージョン 21.x 以降 |
| Toad / PL/SQL Developer | Oracle 19c Instant Client と組み合わせ |
対処法②:パスワードを再設定してバーニファイアを更新する
サーバーもクライアントも新しいのに ORA-28040 が出る場合は、ユーザーのパスワードバーニファイアが古い形式のままです。パスワードを再設定(同じパスワードでも可)すると、現在のサーバー設定に基づいた新しいバーニファイアが生成されます。
-- 特定ユーザーのパスワードを再設定(同じパスワードでもOK) ALTER USER app_user IDENTIFIED BY new_password; -- 再設定後にバーニファイアを確認 SELECT username, password_versions FROM dba_users WHERE username = 'APP_USER'; -- 結果: 11G 12C(新しいバーニファイアが追加される) -- 古いバーニファイアしか持たない全ユーザーを一覧(要対応リスト) SELECT 'ALTER USER ' || username || ' IDENTIFIED BY <new_password>;' AS alter_stmt FROM dba_users WHERE password_versions NOT LIKE '%12C%' AND account_status = 'OPEN';
・
SEC_CASE_SENSITIVE_LOGON が TRUE(デフォルト)であることを確認してください。FALSE の場合、11G / 12C のバーニファイアが正しく生成されません・アプリケーション接続用のユーザーは、パスワード変更前にアプリケーション側の接続設定も同時に更新してください
・
PASSWORD_VERSIONS に「10G」のみのユーザーは、DB アップグレード前に作成されたまま放置されている可能性が高いです対処法③:SQLNET.ORA で許可するプロトコルバージョンを下げる(暫定対処)
クライアントのアップグレードやパスワード再設定がすぐにできない場合の暫定対処です。セキュリティレベルを下げる設定なので、恒久対策としては非推奨です。
# サーバー側: $ORACLE_HOME/network/admin/sqlnet.ora # 値を下げると古いクライアントからの接続を許可する # ---- 11g クライアントを許可する場合 ---- SQLNET.ALLOWED_LOGON_VERSION_SERVER = 11 SQLNET.ALLOWED_LOGON_VERSION_CLIENT = 11 # ---- 10g クライアントまで許可する場合 ---- # SQLNET.ALLOWED_LOGON_VERSION_SERVER = 10 # SQLNET.ALLOWED_LOGON_VERSION_CLIENT = 10 # ---- 8i クライアントまで許可する場合(非推奨: DESベース認証を許可)---- # SQLNET.ALLOWED_LOGON_VERSION_SERVER = 8 # SQLNET.ALLOWED_LOGON_VERSION_CLIENT = 8
| パラメータ | 説明 | 影響 |
|---|---|---|
| SQLNET.ALLOWED_LOGON_VERSION_SERVER | サーバーが許可する最低の認証プロトコルバージョン | 値を下げるほど古いクライアントが接続可能になるが、セキュリティリスクが増大 |
| SQLNET.ALLOWED_LOGON_VERSION_CLIENT | クライアント側から要求する最低のサーバー認証バージョン | 通常はサーバー側と同じ値に設定 |
-- sqlnet.ora を編集した後、リスナーを再起動 $ lsnrctl stop $ lsnrctl start -- データベースインスタンスは再起動不要 -- (sqlnet.ora は接続ごとに読み込まれるため) -- ただし ALLOWED_LOGON_VERSION を下げた場合は -- パスワードの再設定が必要になることがある ALTER USER app_user IDENTIFIED BY same_password;
・DES ベースの認証を許可するため、パスワードが総当たり攻撃に脆弱になります
・Oracle セキュリティ監査(DBSAT 等)で警告が出ます
・Oracle 21c 以降ではバージョン 8 / 10 のサポートが廃止される予定です
・暫定対処として設定した場合は、クライアントのアップグレード後に必ず元の値に戻してください
sqlnet.ora の場所と編集方法
-- Linux / Unix $ echo $ORACLE_HOME/network/admin/sqlnet.ora # 例: /u01/app/oracle/product/19c/dbhome_1/network/admin/sqlnet.ora -- Windows # %ORACLE_HOME%\network\admin\sqlnet.ora # 例: C:\app\oracle\product\19c\dbhome_1\network\admin\sqlnet.ora -- TNS_ADMIN 環境変数で別の場所を指定している場合 $ echo $TNS_ADMIN # TNS_ADMIN が設定されていれば、そのディレクトリの sqlnet.ora が使われる -- sqlnet.ora が存在しない場合は新規作成して上記パラメータを記述
リスナー設定の詳細については「Oracle リスナー設定完全解説」を参照してください。
クライアント別の対処法
JDBC(Java)
-- ORA-28040 が出る場合、ojdbc ドライバが古い -- 推奨ドライババージョン: -- ojdbc8.jar (JDK 8+) → Oracle 12c / 19c / 21c に対応 -- ojdbc11.jar (JDK 11+) → Oracle 19c / 21c に対応 -- ojdbc14.jar (JDK 1.4) → Oracle 10g 用(非推奨) -- ojdbc6.jar (JDK 6) → Oracle 11g 用(非推奨) -- Maven の場合(ojdbc8 の例): -- <dependency> -- <groupId>com.oracle.database.jdbc</groupId> -- <artifactId>ojdbc8</artifactId> -- <version>21.9.0.0</version> -- </dependency> -- 接続 URL は変更不要 -- jdbc:oracle:thin:@//hostname:1521/service_name
SQL*Plus
-- SQL*Plus のバージョン確認 $ sqlplus -V # SQL*Plus: Release 19.0.0.0.0 -- 古い SQL*Plus(10g / 11g)の場合: -- ① Oracle Instant Client 19c をインストール -- ② 新しい sqlplus を使用して接続 -- ③ 古い ORACLE_HOME が PATH に残っていないか確認
ODP.NET(.NET アプリケーション)
-- NuGet でマネージドドライバをアップグレード -- Install-Package Oracle.ManagedDataAccess -Version 21.12.0 -- .NET Core / .NET 6+ の場合 -- Install-Package Oracle.ManagedDataAccess.Core -Version 23.3.0 -- マネージドドライバは Oracle Client のインストール不要 -- sqlnet.ora の代わりに接続文字列で制御する
Python(python-oracledb / cx_Oracle)
# python-oracledb(推奨: cx_Oracle の後継)
# pip install oracledb
# Thin モード(デフォルト)は Oracle Client 不要で最新プロトコル対応
import oracledb
conn = oracledb.connect(user='app_user', password='pw',
dsn='hostname:1521/service_name')
# cx_Oracle は非推奨(python-oracledb に移行推奨)
# cx_Oracle は Oracle Instant Client に依存するため、
# Instant Client のバージョンが古いと ORA-28040 が発生する
トラブルシューティング
設定変更後もエラーが出る場合の確認ポイント
| 確認項目 | 確認方法 | 対処 |
|---|---|---|
| sqlnet.ora の場所が正しいか | echo $TNS_ADMIN で確認。設定されていなければ $ORACLE_HOME/network/admin/ |
TNS_ADMIN に正しいパスを設定するか、$ORACLE_HOME 配下に配置 |
| sqlnet.ora の構文エラー | cat sqlnet.ora で内容確認。行末のスペースや余分な引用符がないか |
不要な文字を除去。パラメータ名と値の間は = と半角スペース |
| パスワードバーニファイアが古いまま | SELECT password_versions FROM dba_users WHERE username=... |
ALTER USER ... IDENTIFIED BY ... でパスワード再設定 |
| リスナーのキャッシュ | sqlnet.ora 変更後にリスナーを再起動したか | lsnrctl stop → lsnrctl start |
| 複数の ORACLE_HOME が存在する | echo $ORACLE_HOME / echo $PATH で確認 |
古い ORACLE_HOME の sqlnet.ora を参照していないか確認 |
| 接続プーリングのキャッシュ | アプリケーションサーバーの接続プールが古い接続を保持していないか | 接続プールをリフレッシュまたはアプリケーションを再起動 |
関連するエラーコード
| エラーコード | 意味 | 関連 |
|---|---|---|
| ORA-28040 | 認証プロトコル不一致 | 本記事の対象 |
| ORA-01017 | ユーザー名/パスワードが無効 | パスワード再設定後にログインできない場合は入力ミスを確認 |
| ORA-28000 | アカウントがロックされている | パスワード連続失敗で LOCKED になった場合。ALTER USER ... ACCOUNT UNLOCK |
| ORA-28001 | パスワードが期限切れ | パスワードの有効期限が切れている。ALTER USER ... IDENTIFIED BY ... |
| ORA-12560 | TNS プロトコル・アダプタ・エラー | リスナーやネットワーク設定の問題。「ORA-12560 の対処法」を参照 |
よくある質問
lsnrctl stop → lsnrctl start)。また、アプリケーションサーバーの接続プールをリフレッシュすることも忘れないでください。_SERVER はサーバーが許可する最低バージョンで、クライアントがこのバージョン以上のプロトコルをサポートしていないと接続が拒否されます。_CLIENT はクライアントが要求する最低のサーバーバージョンで、サーバーがこのバージョン未満のプロトコルしかサポートしていない場合に接続を拒否します。通常は両方を同じ値に設定します。ALTER USER を実行してもバーニファイアは再生成されます。つまり、現在のパスワードがわかっていれば ALTER USER app_user IDENTIFIED BY 現在のパスワード で更新できます。ただし、PASSWORD_REUSE_MAX や PASSWORD_REUSE_TIME プロファイル制約がある場合は同じパスワードの再設定が拒否されることがあります。ALTER USER app_user IDENTIFIED BY new_password を実行すると両方のエラーが解消されます。①まず
DBA_USERS.PASSWORD_VERSIONS で全ユーザーのバーニファイアを確認②12C バーニファイアを持たないユーザーを特定してパスワードを再設定
③それでも解決しない場合のみ SQLNET.ORA の値を最小限下げる(8 ではなく 11 から試す)
④クライアントのアップグレード完了後に SQLNET.ORA を元に戻す
いきなり ALLOWED_LOGON_VERSION=8 にするのではなく、段階的に対処するのが安全です。
まとめ
ORA-28040 の対処方法を整理します。
| 対処法 | 安全性 | 即効性 | 推奨度 |
|---|---|---|---|
| ①クライアントのアップグレード | 最も安全 | 時間がかかる(テストが必要) | 最も推奨 |
| ②パスワード再設定(バーニファイア更新) | 安全 | 即効(ALTER USER 一発) | 推奨 |
| ③SQLNET.ORA で ALLOWED_LOGON_VERSION を下げる | セキュリティリスクあり | 即効(ファイル編集のみ) | 暫定対処のみ |
①パスワードバーニファイアを確認(
DBA_USERS.PASSWORD_VERSIONS)②バーニファイアが古ければパスワードを再設定
③クライアントが古ければアップグレード
④どうしても無理ならSQLNET.ORA を最小限だけ下げる(値は 11 から試す。8 は最終手段)
