没有合适的资源?快使用搜索试试~ 我知道了~
Solaris操作系统的用户认证.doc
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 120 浏览量
2022-05-17
10:33:43
上传
评论
收藏 600KB DOC 举报
温馨提示
试读
32页
Solaris操作系统的用户认证.doc
资源推荐
资源详情
资源评论
Solaris 操作系统的用户认证: 第 1 部分 本文介绍了 Solaris 操作系统的用户认证与授权技术,
并通过代码示例说明如何实现口令的加密与存储。
简介
认证与授权
口令存储与加密算法
用户口令的读取
口令加密
用户影子文件的读取
将各部分合并在一起
结束语
致谢
参考资料
简介
通常我们的程序需要检验用户的身份,尤其是我们需要执行有潜在危险或特权操作时,这
一点尤为必要。例如,大多数 Solaris 用户所熟悉的登录,只有我们正确输入用户名和口令
后,方可使用系统;而另一个常见例子就是,当屏幕加锁后我们需要解锁。
在本系列文章中,我们将介绍如何在程序中利用口令和其他方法验证用户身份。在本文的
第 1 部分中,我们将讨论验证原理,并通过基于口令技术的身份验证的示例来加以详解。
而在第 2 部分中,我们将了解如何利用 PAM 技术(插入式验证模块)来使我们的程序更加
灵活。
身份验证与授权
人们在讨论口令时通常会涉及两个术语,即身份验证与授权。但它们往往会被误用,在此
我们对其定义如下。 身份验证发生于计算机校验用户身份时:当用户用正确口令登录后,
操作系统会授权给用户。另一方面, 授权将决定用户是否有权限执行既定任务或访问系统
特定资源。
既然我们可以通过认证,那么我们的所做就没有必要被授权才可以完成。例如,我们以普
通用户登录后,通常不会对其他用户的文件造成影响:即使我们的身份通过难证,我们也
没有足够的权限。而倘若我们是管理员用户,我们则有权限随心所欲的使用系统。为简单
起见,我们忽略了 RBAC(角色访问控制)和权限细粒化。对 RBAC 感兴趣的读者可参考
System Administration Guide: Security Services 。权限细粒化详见 Programming in the Solaris
OS With Privileges。
虽然有多种途径可实现身份验证(如,生物测定、身份证等等),但本文只讨论口令验证。
口令存储与加密算法
如果用户输入的响应询问口令需要与正确口令相比较,则正确口令必须存储在系统中的某
个文件中。在 Solaris 系统中,用户口令存储在文件 /etc/shadow 中,但之前一直存储在
/etc/passwd 文件中(由于其名称)。由于多种原因, /etc/passwd 须可供所有用户读取。为
避免口令被破译,UNIX 平台(Solaris 即为其中之一)中的系统 V 变量可把口令存储在
/etc/shadow 中,只可供超级用户读取。(注意,前述内容假定口令存储于本地文件中。而
许多大型站点往往使用 NIS, LDAP, or NIS+将用户口令存储于集中式存储库中。)
存储在 /etc/shadow 中的口令使用单向哈希算法进行加密,因为如果以明文格式,即解密格
式存储口令,则欠失理智!所谓单向哈希算法加密是指无法从加密口令得出口令。在 Solaris
9 12/02 之前,加密算法都基于 DES(加密算法标准)的各种变体,采取各种措施来阻止硬
件中对密钥的搜索。
自 1977 年 DES 面世以来,随着计算机处理速率的显著提高,暴力破译 DES 加密口令所带
来的威胁也与日俱增,并且其口令长度局限于 8 位字符。为减缓威胁,Solaris 9 12/02 采用
了一种新型编码,促进了一些更为强大的加密算法(如 MD5 和 Blowfish)的广泛使用。由
于在新型编码中增加了密钥长度和算法复杂度,欲暴力破译使用新型加密算法编码的口令
需要比破译 DES 加密口令高出几个数量级的时间。
谈到这里,读者不禁会问:我们该如何决定用哪种算法来加密口令?为了回答这个问题,
我们需检查几个影子文件的内容。下面是作者一台计算机中的影子文件内容的例子:
rich:TISFHhgBSAtgU:13608:::::
shadow(4)手册页详细说明了这些字段。我们主要关注于头两部分:第一个字段是用户名,
第二个字段是加密后的口令。如果口令的第一个字符不是 "$",那么此口令使用的是基于
DES 的加密。加密后的口令共有 13 个字符,其中前两个字符是 salt,salt 是用于扰乱 DES
算法的 4096 种算法中的一种,而余下的 11 位字符即为加密口令本身。如果第一个字符
是"$",一直到下一个"$"间的这些字符则表明所使用的加密算法,而处于第二和第三
个"$"间的字符即为 salt。
而在作者另一台计算机中,使用的是另一种加密算法。下面是对应的影子文件内容:
rich:$2a$04$NZJWn7W2skvQRC5lW3H7q.ZTE8bz4xbCAtU1ttzUOy63si3phphUu:13613:::::
可以看出,第一个字符是"$",表明使用的是另一种加密算法(在本例中,我们用"2a"来标
识 算 法 , 即 为 Blowfish ) 。 标 识 符 到 各 自 库 的 映 射 ( 及 它 们 的 特 定 算 法 ) 定 义 在
/etc/security/crypt.conf 文件中。每种算法都有各自的手册页,其中包含更为详细的信息及可
用的选项。在示例中我们使用了 Blowfish 加密,详细信息请见 crypt_bsdbf(5)。
用于比较存在口令的加密算法可通过影子文件得出,但是我们应该如何决定使用哪种算法
创建新口令呢?答案是:使用 code>/etc/security/policy.conf 文件中 CRYPT_DEFAULT 指定
的 算 法 创 建 新 口 令 。 但 是 , 在 修 改 口 令 且 旧 口 令 是 使 用 相 同 文 件 中
CRYPT_ALGORITHMS_ALLOW 指定的算法加密时,这种情况下将使用该算法创建新口令。
无论使用哪种加密算法,在对用户进行身份验证前需采集用户输入的口令。
用户口令的读取
要提示用户输入口令,一种方法就是使用 printf 和 fgets 函数分别打印提示并读取口令。这
种方法的缺陷就是除非我们按步录入,否则输入的口令将显示在屏幕上:多么严重的缺陷
我们可以编写方法来处理这种屏幕回显响应,但是要完全解决此问题则需要使用一些提供
的函数。第一个方法为为 getpass:
char *getpass (const char *
prompt);
getpass 函数将打印输出 prompt,关闭回显并从终端读取换行符之前的文本( newline-
terminated line),并将终端恢复为之前状态,然后返回指向输入字符串的指针。该方法与
标准兼容,但是我们需要考虑它的致命缺陷:即只有录入字符串的前 8 个字符可返回给调
用函数 getpass ,从而将口令限制 8 位有效字符(而无论采用的哪种加密算法)。为避免出
现这种问题的出现,我们应该使用 getpassphrase:
char *getpassphrase (const char *
prompt);
此函数与 getpass 的功能相同,不过它可读取和返回的字符串长达 257 个字符。在下面的例
子中我们将使用到它。虽然目前没有通用标准详细说明该方法,但我们仍可广泛使用
getpassphrase 而无需担心不可移植的问题。换言之, getpassphrase 是一个事实标准。
口令加密
获取用输入的口令之后,我们需要将其与存储于影子文件中的密码进行比较。第一步需将
其加密。如果我们对新型加密算法不熟悉,则尽其可能调用 crypt 函数:
char *crypt (const char *
key, const char *
salt);
比较输入口令与存储于影子文件中的口令时,将正确的 salt 传给 crypt 的最简便的办法就是
将加密的用户口令传给它。在接下来的章节中我们将向大家介绍如何读取用户影子文件的
内容。
倘若我们不将输入口令与存储口令相比较,而是创建一个新口令,并且支持新型加密算法
我们可以调用 crypt_gensalt 来生成传递给 crypt 的 salt:
char *crypt_gensalt (const char *
oldsalt, const struct passwd *
userinfo);
如果 oldsalt 值为 NULL,则使用 /etc/security/policy.conf 中的 CRYPT_DEFAULT 指定的算法。
userinfo 结构可使用 getpwnam 函数家族填充(该内容不在本文讨论范畴内)。
用户影子文件的读取
正如先前所指出的,将加密口令与用户当前口令相比较时,我们必须将正确的 salt 传递给
它。较为简便的方法就是将加密后的用户口令传递给 crypt 函数。除此之外,我们还应该从
影子文件中读取用户口令。为此,可以使用 getspnam 函数:
struct spwd *getspnam (const char *
name);
getspnam 函数返回指向以 name 标识的影子文件信息结构的指针。此结构体由几个成员组
成,而现在,我们感兴趣的只是其中之一: sp_pwdp,它指向加密后的口令。此指针将作
为 salt 传递给 crypt。
需要指出的是,由于 /etc/shadow 只可供管理员用户使用,并且只可供有效用户 ID 为“0的
用户成功调用 getspnam。(权限感知处理要求 FILE_DAC_READ 权限位于它们的有效权
限集中。)
将各部分合并在一起
现在,我们可利用迄今所学编写一个简单的程序,实现口令的验证。在示例中,应用程序
将将会重复要求输入密码,直至输入正确的用户口令,若口令正确则程序结束。(当前用
户取决于进程的真实用户 ID。)示例源代码如下:
1 #include <sys/types.h>
2 #include <unistd.h>
3 #include <pwd.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <shadow.h>
7 #include <crypt.h>
8 #include <string.h>
9 int main (void)
10 {
11 struct passwd *pwd_info;
12 struct spwd *spwd_info;
13 char *ct_passwd;
14 char *enc_passwd;
15 if ((pwd_info = getpwuid (getuid ())) == NULL) {
16 fprintf (stderr, "Call to getpwuid failed\n");
17 exit (1);
剩余31页未读,继续阅读
资源评论
cailibin
- 粉丝: 4
- 资源: 7018
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功