1、环境说明

ORACLE 客户端版本

11.2.0.1

ORACLE 服务端版本

12.2.0.1

2、异常现象

客户端(下文也称为Cp)访问服务端(Sp),报了一个错误:

Figure 1

以错误码为关键字在网上查找原因,有网友建议把服务器的sqlnet.ora文件中的SQLNET.ALLOWED_LOGON_VERSION_SERVER参数 和 SQLNET.ALLOWED_LOGON_VERSION_CLIENT参数改为8(原值为12)。如下图所示:

Figure 2

改过之后重新连接,糟糕,出现了新的错误:

Figure 3

可是我从其它的客户端(后来发现这些客户端版本均高于11.2.0.1)连接该Sp均没有问题。我以为是不是有什么后台程序会把输入的所有小写强制转成大写,于是我将账户密码从sys修改为SYS,然后再连接:

Figure 4

成功了。从现象上来看,似乎真的就是大小写的关系。可是真的是的吗?我现在将密码从SYS改回sys,然后再连接:

Figure 5

这回用sys作为密码登陆,也成功了。看来真正的原因,不是什么后台程序强制转换了大小写。那究竟是什么原因呢?

3、原理解释

其实,从现象上来看,变化最初是在设置了

SQLNET.ALLOWED_LOGON_VERSION_CLIENT

和SQLNET.ALLOWED_LOGON_VERSION_SERVER两个参数后产生的。那这两个参数到底起什么作用呢?

先看一下SQLNET.ALLOWED_LOGON_VERSION_CLIENT在官方文档中的说明:

Figure 6

这个参数是12C新引进的参数。它表示Cp在向Sp发送认证(authentication)申请时,所使用的最低版本的认证协议。注意此处的认证协议版本并不等同于Oracle Database的版本。那不同的认证协议版本主要区别在哪儿呢?除了协议语义上的区别,在我看来,最重要的区别在于不同认证协议的版本对应着不同的database version,而不同的database version则可能使用不同的hash算法对密码进行加密。不同的hash算法就是不同的password_version,这个可以从dba_users字典表的password_versions字段中得到说明:

Figure 7

Oracle在存储每个account的密码时,并非是明文存储,而是会将明文进行哈希加密存储,哈希加密算法即为该密码的version,即password_version。从上图Figure 7中可知,password_version实际上表示是同版本(并非完全一致,见最后的附表)的database 所提供的hash算法,例如password_version 10g就表示database 10g所提供的hash算法。如果Oracle所有的新版本都只使用新版本所特有的hash算法,那么一些较早的客户端因为还没有这些hash算法,就没法通过hash算法得到hash值,也就没法让服务器去验证这些hash值。为了解决兼容性的问题,Oracle会同时用多种hash算法(即password_version)对密码进行运算,并将多个运算结果均保留下来。在低版本客户端访问高版本的服务器时,低版本的客户端可以通报自己使用的认证协议以及使用该协议对应的hash算法所得到的密码hash值,服务器根据认证协议去查看是否存储了该协议对应的hash算法的hash值,如果存在,就比对两个hash值是否一致;如果不存在或两个hash值不一致,就报错。其流程图大致如下所示(仅代表自己的理解):

在上述密码认证流程图中,标红的子流程——"判断该账户的password_versions中是否包含client version",有一个疑问:account有哪些password version,是由什么决定的呢?这就引出了另一个参数:SQLNET.ALLOWED_LOGON_VERSION_SERVER。

关于这个参数的作用,它介绍了为这个参数设置不同的值所带来的影响,主要是对PASSWORD_VERSIONS的影响。最后附带了一张表,详细了列出了SQLNET.ALLOWED_LOGON_VERSION_SERVER设置不同值,所对应的password_versions。也说明了如果要与设置成当前值的12C数据库进行密码认证,所支持的client version。从上图可以看出,即使SQLNET.ALLOWED_LOGON_VERSION_SERVER设置为8,但生成的最低版本的password version也是10G。因此也说明,8I,9I的客户端因为没法理解10G的哈希函数,也就没法完成登陆认证。关于客户端到服务器端相互之间的兼容性如下表:

4、案例重演

  1. 在SQLNET.ALLOWED_LOGON_VERSION_SERVE=12时,为sys用户设置了密码,因此sys账户的password_versions=11G,12C

  2. 这时用client version 11.2.0.1请求登陆,因为client version 11.2.0.1的认证协议版本为11(该版本小于11.2.0.3,并没有打CPUOct2012补丁,因为认证协议版本为11),所以流程如红线1所示:

  3. 然后手动将SQLNET.ALLOWED_LOGON_VERSION_SERVE改为8,但因为只是参数变化,并没有重建密码,因此该account的实际password仍然为11G,12C,所以请求登陆的流程如红线2所示:

  4. 重新生成密码。因为是在SQLNET.ALLOWED_LOGON_VERSION_SERVE=8的情况下生成的密码,因此该account所对应的password_versions=10G,11G,12C,如下图所示:

    而该password_versions是支持client version 11.2.0.1密码认证的,所以请求登陆的流程如红线3所示:

5、认证协议版本、database版本与password版本之间的关系

如下表:

从一个案例窥探ORACLE的PASSWORD_VERSIONS的更多相关文章

  1. 通过一个案例彻底读懂10046 trace--字节级深入破解

    转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/37840583 2014.7.23晚20:30 Oracle support组猫大师分享&l ...

  2. 案例:Oracle报错ASM磁盘组不存在或没有mount

    案例:Oracle报错ASM磁盘组不存在或没有mount 环境:RHEL 6.5 + Oracle Standby RAC 11.2.0.4 我做Standby RAC实验时,在恢复控制文件时,报错无 ...

  3. Vue一个案例引发「内容分发slot」的最全总结

    今天我们继续来说说 Vue,目前一直在自学 Vue 然后也开始做一个项目实战,我一直认为在实战中去发现问题然后解决问题的学习方式是最好的,所以我在学习一些 Vue 的理论之后,就开始自己利用业余时间做 ...

  4. Vue一个案例引发的递归组件的使用

    今天我们继续使用 Vue 的撸我们的实战项目,只有在实战中我们才会领悟更多,光纸上谈兵然并卵,继上篇我们的<Vue一个案例引发的动态组件与全局事件绑定总结> 之后,今天来聊一聊我们如何在项 ...

  5. 【权限设计】一个案例,三个角色,简单说下B端产品的权限设计

    入行以来也接触过一些B端产品,这些产品之中权限管理是重中之重,权限管理不仅仅是整个系统的一个小小的模块,它一直贯穿整个系统,从登陆到操作到最后的登出.说它相当的复杂真不为过. 对于权限,如果从控制力来 ...

  6. urlretrieve关于循环下载的一个案例

    # -*- coding: cp936 -*- #python 27 #xiaodeng #urlretrieve关于循环下载的一个案例 import urllib def down_list(sto ...

  7. sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)

    sql server 关于表中只增标识问题   由于我们系统时间用的过长,数据量大,设计是采用自增ID 我们插入数据的时候把ID也写进去,我们可以采用 关闭和开启自增标识 没有关闭的时候 ,提示一下错 ...

  8. 从零写一个兼容MySQL/Oracle的Proxy中件间(一)《初识Oracle的通信协议》

    0.前言 MySQL由于开源的原因,有各式各样的中件间Proxy ,极大的丰富了做高可用或迁移的方案,习惯了MySQL生态圈的灵活和便利,Oracle官方不开源代码和协议,没有中间件proxy,显得很 ...

  9. 作为一个新手的Oracle(DBA)学习笔记【转】

    一.Oracle的使用 1).启动 *DQL:数据查询语言 *DML:数据操作语言 *DDL:数据定义语言 DCL:数据控制语言 TPL:事务处理语言 CCL:指针控制语言 1.登录 Win+R—cm ...

随机推荐

  1. JQ js 对数组的操作

    1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限, ...

  2. 上下左右居中 无固定高的div

    <style type=“text/css”> #vc { display:table; background-color:#C2300B; width:500px; height:200 ...

  3. volatile原理

    内存可见性 内存可见性相关概念:线程对共享变量修改的可见性.当一个线程修改了共享变量的值,其他线程能够立刻得知这个修改. 后面会继续总结一篇<Java内存模型(JMM)总结>以详细描述内存 ...

  4. Sql语句中Like嵌套用法

    一般的Like用法: SELECT U_NAME FROM T_USER WHERE U_NAME LIKE '%A%' 但是,我此次like关键字后面的对应值是一个变量,需要用select语句来实现 ...

  5. Xamarin.Forms 入门

    介绍 Xamarin.Forms是一个开源UI框架,Xamarin.Forms允许开发人员从单个共享代码库构建Android,iOS和Windows应用程序. Xamarin.Forms允许开发人员使 ...

  6. [USACO12MAR]花盆 二分 单调队列

    [USACO12MAR]花盆 二分 单调队列 存在一个长度为\(x\)的区间\([l,r]\),使得区间中最大值与最小值差至少为\(w\),求这个最小的\(x\) \(n\le 100000\),\( ...

  7. string拼接时去掉最后一个逗号

     str.replace(str.length() - 1, str.length(), "");

  8. delphi调用https接口

    delphi调用http接口直接使用idhttp就可以了,但是调用https接口的时候就需要和IdSSLIOHandlerSocket1控件一起使用. 截图中是两个控件的具体配置,需要注意的是IdSS ...

  9. Cloudera-Manager(一) —— 基本概念及使用

    概念 Cloudera Manager(简称CM)是Cloudera公司开发的一款大数据集群安装部署利器,这款利器具有集群自动化安装.中心化管理.集群监控.报警等功能,极大的提高集群管理的效率. AP ...

  10. uniapp - 关于ios调试

    [ios调试] 1.一台windows电脑.一根apple数据线(一旦连接以后,apple设备就会自动识别itunes软件,如果没有安装会提示) 2.安装itunes (爱思助手) 3.官方教程:ht ...