Linux安全和加解密

概述:

    所有业务的正常运转,离不开一个安全的运行环境,系统安全性直接关系到业务稳定、可靠、以及可用性,本章就介绍一些系统安全相关的话题,具体包括:   

    1、加密基础概念

    2、CA和证书的基础概念

    3、ssl协议和openssl命令

    4、利用openssl建立私有CA,完成证书颁发和管理

    5、利用gpg实现加解密

    6、ssh服务

    7、dropbear提供ssh服务

    8、aide监控文件安全性

    9、sudo相关内容

第一章    加密基础相关概念

   

    1、安全的目标:

        保密性:confidentiality

        完整性:integrity

        可用性:availability

    2、攻击类型:

        威胁保密性的攻击:窃听,通信量分析

        威胁完整性的攻击:更改,伪装,重放,否认

        威胁可用性的攻击:拒绝服务(DoS)

    3、为了完成安全的目标用到的解决方案

        技术:加密和解密               

                加密和解密:

                    传统加密方法:替代加密方法,置换加密方法

                    现代加密方法:现代块加密方法

        服务:用于低于攻击的服务,也就是为了上述安全目标而特地设计的安全服务

                服务:

                    认证机制

                    访问控制机制

    4、对称加密

        对称加密:加密和解密使用同一个秘钥;但加密算法和解密算法可能不同

        工作过程为:

            发送者将发送的数据利用秘钥,使用加密的算法加密成明文,发送给对方;接收方收到加密的数据后,利用同一个秘钥,和解密的算法,将数据由密文解密成明文

        常见的对称加密算法:

                DES:Data Encryption Standard,56位秘钥

                3DES:Triple DES

                AES:Advanced Encryption Standard,支持128位、192位、256位、384位秘钥

                Blowfish

                Twofish

                RC6

                CAST5

        对称加密特性:

            <1>加密解密使用同一个秘钥

            <2>将原始数据分隔成为固定大小块,逐个进行加密

        对称加密的缺陷:

            <1>秘钥过多

            <2>秘钥分发困难

            <3>数据来源无法确认

    5、公钥加密(非对称加密):秘钥分为公钥和与之配对的私钥

        公钥:公钥从私钥中提取产生,可以公开给所有人;pubkey

        私钥:通过工具创建,私钥只能使用则自己留存,必须保证其私密性,secret key

        特点:用公钥加密的数据,只能使用与之配对的私钥解密;反之,用私钥加密的数据只能用与之配对的公钥解密

        用途:

            数字签名:主要在于让接收方确认发送方的身份。将数据用单项加密(MD5、SHA)算法,得出来的特征码,用自己的私钥进行加密,这就是数字签名

            秘钥交换:发送方用对方的公钥加密一个对称加密的秘钥,并发送给对方,以实现秘钥交换

            数据加密:一般很少用公钥加密发送的数据本身,因为公钥加密的加密效率很低,因此一般用对称秘钥加密要发送的数据本身

        公钥机密的工作模式:

            模式一:公钥加密,私钥解密

                    B将数据发送给A,B就拿A的公钥对数据进行加密,然后将加密后的数据发送给A,那此时,加密后的数据只能被A的私钥进行解密,因此,即使有第三方拿到加密的数据,也无法完成解密,只有A自己有自己的私钥,因此实现了数据的保密性

            模式二:私钥加密,公钥解密

                    A用自己的私钥加密一份数据给B,加密后的数据只能被A的公钥进行解密,因此,如果有第三方拿到加密后的数据,是能够解密的,因为A的公钥是公开的,任何人都可以拿到,因此可以解密

                    但此种方式的作用,并不是真正拿来加密数据,而是用来进行身份验证(数字签名),也就是说,A用自己的私钥加密一段数据(数据不是要发送的数据本身,而是要加密数据利用单向加密算法得出来的特征码),然后发送给B,B拿A的私钥进行解密,能够解密成功,就证明发送方一定是A,因为只有A的公钥能解开A的私钥;一旦解开数据后,得到的就是要发送数据的特征码,等后面真正发送数据后,可以利用该段特征码,来验证数据的完整性

        公钥加密的常用的算法:

            RSA:既能实现数字签名,也能实现加解密

            DSA:有时也被称为DSS,数字签名标准。仅能实现数字签名,不能实现加解密

    6、单向加密:只能加密,不能解密。仅能提取数据的特征码

        特性:

            定长输出:无论原始数据多大,得出的特征码都是固定长度的

            雪崩效应:原始数据的微小改变,将导致特征码的巨大变化

        功能:主要用来实现验证数据的完整性

        常见的单向加密算法:

            MD5:Message Digest 5  消息摘要,5版本。128bit定长输出

            SHA1:Secure Hash Algorithm 1,160位定长输出

            SHA224、SHA256、SHA384、SHA512

    7、秘钥交换:IKE(Internet Key Exchange)

        常见的交换算法:

            公钥加密:用对方的公钥加密对称秘钥,这样对方就能以自己的私钥解开,从而获得对称加密的秘钥

            DH(Deffie-Hellman)算法:

                    <1> A: a,p 协商生成公开的整数a, 大素数p
                        B: a,p
                    <2> A:生成隐私数据 x, (x<p ),计算得出 a^x%p,发送给B
                        B:生成隐私数据 y,计算得出 a^y%p,发送给A
                    <3> A:计算得出 ( a^y%p) ^x = a^xy%p, 生成为密钥
                        B:计算得出 ( a^x%p) ^y = a^xy%p, 生成为密钥

    8、加密通信的双方的通信过程展示

    图片1.png

            

        A有一段数据要发送给B,A就用单向加密的算法计算出数据的特征码,而后A用自己的私钥加密这段特征码,生成数字签名,至此能够保证数据的完整性(通过比对特征码),和身份验证(数字签名),但是不能保证数据的保密性,因为数据本身还没被加密。

        因此,A会继续在原有数据和数字签名的基础上,生成一个一次性的对称加密秘钥,然后利用对称加密算法结合秘钥,去加密原有数据和数字签名。然后,A用B的公钥,对对称加密的秘钥进行加密,并附加到之前利用对称加密算法生成的数据的后面,然后发送给B

        当B收到数据后,就用B自己的私钥解密附加在后面的对称加密的秘钥,从而得到了对称加密的秘钥(这就完成了秘钥交换,实际是双方都知道了对称加密的秘钥的过程就是秘钥交换),然后利用对称加密的秘钥进一步解开数据和数字签名,然后利用A的公钥解开数字签名,得到数据本身的特征码,然后利用同样的单项加密算法,计算出收到的数据的特征码,然后比对特征码,从而验证数据的完整性

 

    9、中间人攻击:

        以上通信过程中还是有一个严重的漏洞,就是当A和B键从来没进行过通信,那么A怎么获知B的公钥,或者B怎么获知A的公钥。假设当A没B的公钥时,向B发送请求,要求获知B的公钥,但是此时,如果有第三方C获取到请求后,冒充自己就是B,然后将C自己的公钥发送给A,A就认为C就是B。而C又会冒充自己是A,向B进行通信,从而也获取了真正B的公钥,而此后A和B通信的过程中,就都会交由C,数据的安全性就无从保障。这种情况就是中间人攻击

第二章    CA的和证书的基础概念

    1、PKI:Public Key Infranstructure公钥基础设施

        由四个部分组成:

            签证机构:CA机构

            注册机构:RA,相当于CA的派出机构,用于接收注册申请

            证书吊销列表:CRL

            证书存取库:CB

    2、CA的作用

        CA:保证通信双方,能够可靠的拿到对方的公钥(避免中间人攻击),而设定的双方都信任的第三方可信机构

            A将自己的公钥提请给CA,CA经过特殊的防伪处理后,将处理后的A的公钥发送给A,处理过后的A的公钥就称之为CA证书。以后,如果B如果请求要A的公钥,那么A就将CA证书发送给B,当B拿到证书后,不会立马就任何该证书,而是要验证该证书是否是合法的,还要验证是否是B信任的CA机构颁发的,验证完了之后,才会认可

        CA证书一般会包含:提请证书的人的名称,提请人的公钥,证书有效期,然后CA机构会用自己的私钥,加密以上的一整段数据的特征码,然后将加密后的特征码(也就是数字签名)附加在数据之后,这个整体就是CA证书

        CA证书后面有CA机构用CA机构自己的私钥对证书内容部分的特征码加密的数据,通信方要解开此数字签名就需要用到CA自身的公钥,但是如何获取到CA机构自己的公钥,如果直接申请,那么此时又会存在中间人攻击的可能,因此,一般是CA机构会给自己发一个CA证书,然后获取CA自身的证书,一般不能通过网络发送,因此一般情况下,是线下交易

    3、CA证书格式:

        X.509,定义证书结构和认证协议的标准,在X.509的标准中,定义了证书需要具备的结构:

            版本号:是X.509的v1还是v2还是v3版本

            序列号:CA机构所发出的证书的序列号

            签名算法ID:证书所使用的算法

            发行者的名称:CA机构自己的名称

            证书有效期限

            主体名称:提请CA证书的用户的名称

            主体公钥:

            发行者的唯一标识:CA机构的ID

            主体的唯一标识:提请者的ID

            扩展信息

            发行者的签名:CA机构利用自己的私钥对以上内容的特征码加密,生成的数字签名,将数字签名附加在证书内容之后,作为证书的一部分

第三章    ssl协议和openssl命令

    1、SSL协议:SSL和TLS

        SSL:安全套接字层,由Netscape发布于1994年,分为V1.0、V2.0、V3.0但由于其版权属于Netscape公司,且各版本均被爆出有协议漏洞,因此使用的不多

        TLS:Transport Layer Security,传输层安全,是国际互联网工程师协会发布的类似于SSL的协议,其分为V1.0、V1.1、V1.2、V1.3的版本,使用较多的是V1.2的版本

    2、TLS的分层设计:

        <1>最底层:基础算法的原语的实现,如AES、RSA、MD5

        <2>向上一层:各种算法的实现,也就是算法的具体实现的方式

        <3>再向上一层:组合算法实现的半成品

        <4>最高层:用各种组件拼装而成的各种成品密码学协议软件;

    3、SSL协议的开源实现:OpenSSL

        OpenSSL由三部分组成:

            libencrypt库:加密解密库,专用于实现加密解密功能,主要由开发人员使用

            libssl库:用于实现ssl安全通信机制的库,主要由开发人员使用

            openssl多用途命令行工具:openssl

    4、SSL会话的主要的三步:

        客户端向服务器端所要并验证证书(证书里面有服务器端的公钥信息);

        双方协商生成对称秘钥;

        双方采用对称秘钥,进行加密通信的过程

        会话过程后,进行断开

    5、在SSL会话之前开始之前的双方Handshake Protocol,SSL握手阶段的执行流程

        也就是双方在正式开始SSL会话之前的通信前商量加密算法和生成会话秘钥阶段的详细过程介绍,(以HTTPS协议为例)       

        <1>第一阶段:client-hello

            客户端向服务器端发送:

            支持的协议版本,如:tls1.2

            客户端生成一个随机数,用于稍后生成对称秘钥

            支持的加密算法,比如AES、RSA、SHA

            支持的压缩算法

        <2>第二阶段:server-hello

            服务器端向客户端发送:

            确认使用的加密通信的协议版本,如tls1.2

            生成一个随机数,用于稍后生成对称秘钥

            确认使用的加密算法

            向客户端发送服务器证书

            如果有必要,有可能会向客户端索要客户端的证书(如:当客户端请求的是网银页面时)

        <3>第三阶段:客户端收到服务器端的server-hello后给出的回应

            验证服务器证书,如果没问题,则通过解密证书获取到服务器的公钥;

            验证的内容:

                    发证机构:验证发证机构是否是可信的,也就是验证证书签名(CA的数字签名)

                    证书的完整性,也是验证证书的数字签名里面的解密出来的特征码

                    证书的持有者:验证证书里面的持有者是否与要访问的页面是一致的

                    证书有效期

                    证书是否被吊销

            发送以下信息给服务器端:

                    一个随机数,用于生成对称秘钥

                    编码变更通知:表示随后的信息都将用双方商定的加密方法和秘钥发送

                    客户端握手结束通知:表示客户端在正式通信前的握手阶段结束

        <4>第四阶段:服务器端

            收到客户端发来的最后一个随机数后,利用含此随机数在内的一共三个随机数生成对称秘钥;

            向客户端发送以下信息:

                    编码变更通知:表示随后的信息都将用双方商定的加密方法和秘钥发送

                    服务器端握手结束通知:表示服务器端握手阶段已经结束

    6、基于SSL的通信的实现过程整理总结:

        A、B双方要进行通信时:A为客户端,B为服务器端

        <1>A发送hello信息给B,B接收后,发送hello信息给A,此时为双方建立通信前的确认,需要协商双方真正通信时所用到的加密算法,包括单向加密、对称加密、公钥加密、秘钥交换用的方法

        <2>A请求B的证书,B于是将自己的证书(CA处理后的公钥)发送给A

                一般情况下,客户端不会有证书提供给服务器端,因为一方面是证书的使用费使得客户端不会去用,另一方面客户端访问服务器端的时候,一般不会验证客户端的身份,比如访问某网站,网站不会要求客户端有证书才响应内容给客户端,而客户端是要验证服务器端的证书的,因为为了防止访问的网站的正确性,防止钓鱼网站等。

                但有时服务器端也会验证客户端的证书,比如当客户端访问的是网银页面的时候,会验证证书,当我们去银行开通网银的时候,一般会有个加密狗之类的东西,其实里面存储的就是用户自己的ca证书,只是一般该ca证书的颁发机构不是市面上公认的CA机构,而是银行自己建的一个CA签发机构,仅对自己银行内部有效

        <3>A收到B的证书后,验证B的证书,如果验证没有问题

        <4>A验证B的证书没问题后,生成一个随机数,作为对称加密的秘钥,A利用双方之前协商的秘钥交换算法(假设为公钥加密),则将此秘钥用B的公钥加密后发送给B

        <5>B收到A发送过来的密文的秘钥后,利用自己的私钥,解密得出对称加密的秘钥,然后利用对称加密的秘钥和之前协商的对称加密的算法,给A发送A所请求的数据,进行正常数据的发送

        <6>当正常的数据传输完成后,A(客户端)请求通信断开,服务器也断开,然后通信终止

    7、openssl命令

        openssl命令行工具有众多子命令,主要分为三类:

            标准命令:enc、ca、req、genrsa…

            消息摘要命令(dgst子命令相关)

            加密命令(enc子命令相关)

        <1>使用openssl命令行工具完成对称加密:

            工具:openssl enc子命令

            支持的算法:aes、des、3des等

            enc命令的用法:

                openssl enc -CIPHERNAME -e|d -in /PATH/TO/FILE -out /PATH/TO/FILE 

                选项解释:

                    -CIPHERNAME:加密的算法的名称,可通过openssl –help查看所支持的加密算法的名称

                    -e|d:-e表示加密,-d表示解密

                    -in /PATH/TO/FILE  要加密的文件

                    -out /PATH/TO/FILE  加密后的文件

                    -pass STRING  表示对称加密的秘钥是什么

                    -a|-base64   表示以base64文本格式进行编码,如果不指定,可能是以二进制格式进行编码

                如对/testdir/file1进行对称加密:

                    openssl enc -des3 -e -a -salt -in /testdir/file1 -out /testdir/jmfile1  输入后回车,会要求输入对称加密的秘钥,输入完成,即可完成加密

                            -des3表示采用des3的加密算法,-a表示以base64文本格式进行编码,-salt表示加点杂质

                解密上面加密的文件:

                    openssl enc -des3 -d -a -salt -in /testdir/jmfile1 -out /testdir/file2  输入后回车,会要求输入对称加密的秘钥,输入完成,即可完成解密

        1.png

        <2>单向加密

            工具:openssl dgst、md5sum、sha1sum、sha256sum…

            用法:

                md5sum /PATH/TO/FILE

                sha1sum /PATH/TO/FILE

                openssl dgst -md5|-sha1… /PATH/TO/FILE

        blob.png

        <3>生成用户密码的命令:

            工具:passwd、openssl passwd

            例如:

            openssl passwd -1 -salt 12345然后回车,会提示要求输入密码,输入完成后,即可生成加密后的密码

                -1  表示使用md5方式加密

                -salt STRING表示生成密码时加入的杂质的内容

                -salt后面加的杂质的内容可以用随机数生成,生成随机数可以用openssl的子命令生成

                        openssl passwd -1 -salt `openssl rand -hex 4` 

        blob.png        

        <4>openssl生成随机数:

            工具:openssl rand

            用法:openssl rand [-out FILE] [-base64] [-hex] NUM

                -out FILE  表示将生成的随机数保存在某个文件中

                -base64  表示使用base64编码,生成的随机数后面可能会有=,要去掉=后才是真正的随机数

                -hex  表示使用十六进制数字编码

                NUM  表示生成随机字符串的长度

            如:

                openssl rand -base64 10

                表示生成一个10个字节的随机数,采用base64编码格式进行输出

                openssl rand -hex 10

                输出10个字节的16进制字节长度的随机数,相当于输出20个字符

            Linux上的随机数生成器:

                /dev/random:仅从熵池中返回随机数,当随机数用尽,会阻塞后续请求随机数的应用

                /dev/urandom:从熵池中返回随机数,随机数用尽,会利用软件生成伪随机数,不会阻塞。伪随机数不安全

                熵池中随机数的来源:

                    硬盘I/O中断时间间隔

                    键盘I/O中断时间间隔

        blob.png        

        <5>openssl实现公钥加密:

            加密解密:

                    支持的算法:RSA、ELGamal

                    工具:openssl rsautl

            数字签名:

                    支持的算法:RSA、DSA、ELGamal

                    工具:openssl rsautl

            秘钥交换

                    支持的算法:DH、RSA

            生成私钥:(公钥一般不需要生成,而是自动的会从私钥中提取产生)

                openssl genrsa 512|768|1024|2048…表示生成一个长度为512、768…位的私钥

                openssl genrsa 1024 > /PATH/TO/FILE  表示生成一个1024位的私钥保存到文件中

                openssl genrsa 1024 -out /PATH/TO/FILE 也表示生成一个1024位的私钥保存到文件中

            生成的私钥文件,不能让其他人访问,因此一般要将私钥文件的权限变成600,为了简化步骤,可以直接在生成私钥时就定义其权限,如:

                (umask 077;openssl genrsa 1024 -out /PATH/TO/FILE)

                用了小括号,相当于在一个子shell中运行,因此此时的子shell的umask设置仅对子shell生效

            从私钥中提取公钥:一般不用手工提取

                openssl rsa -in /PATH/TO/私钥文件  -pubout

                表示从私钥文件中提取出公钥

        11.png

        

第四章    利用openssl建立私有CA,完成证书颁发和管理

    1、openssl配置文件中关于CA的配置段介绍

        openssl的配置文件为/etc/pki/tls/openssl.cnf,其中定义了openssl完成CA工作时的相关属性定义

    1.png

    2、建立私有CA

        在确定配置为CA的服务器上生成一个自签证书,为CA提供所需的目录及文件即可

        步骤:

        <1>生成CA自己的私钥,而在openssl的配置文件中定义了私钥存放的位置为/etc/pki/CA/private/cakey.pem

            (umask 077;openssl genrsa -out /etc/pki/CA/private/cakey.pem 2048 )

        blob.png        

        <2>为CA提供工作所需要的目录及文件:

            mkdir /etc/pki/CA/{certs,crl,newcerts}  注意:如果目录不存在才创建

            touch /etc/pki/CA/{serial,index.txt}

            echo 01 >>/etc/pki/CA/serial

            创建两个CA工作需要用到的文件,serial为存放证书编号的文件,并且要给该文件提供一个初始的编号,标号必须是2位数字。

index.txt文件用于存放签署过的证书的索引

        blob.png

        <3>生成CA自己的自签证书,而在openssl的配置文件中,也定义了自签证书的存放位置为/etc/pki/CA/cacert.pem

            发起签署CA证书的请求

            openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem  -out /etc/pki/CA/cacert.pem -days 3650  

                表示发起CA证书签署请求,

                    -new表示这是一个新申请的签署请求

                    -x509 表示这是自签证书,该选项只有在CA为自己生成自签证书时使用

                    -key指明私钥的存放路径

                    -out 标明所生成的请求的文件存放路径,如果是自签证书,将直接生成签署过的证书,如果不是自签证书,则将生成的签署请求文件发送给CA服务器,由CA服务器根据请求文件生成证书文件

                    -days 指明申请的证书的有效期限为多少天

            命令执行后会要求填入一些信息:

                国家代码:CN

                省份:beijing

                城市:beijing

                公司名:nwc

                部门:ops

                持有者名称:ca.nwc.com(注意:此处最好与此CA服务器的主机名保持一致)

                管理员的邮件地址:nwc@nwc.com

        111.png

 

    3、另一个主机建立CA申请请求,CA进行签署颁发证书

        某服务器需要用到证书进行安全通行时,需要向CA服务器请求签署证书:

        步骤:

        <1>在需要使用证书的服务器上建一个目录,生成私钥(真实环境中建议将该目录建在需要用到证书的服务的相关目录下,便于管理)

        <2>生成签署请求

            openssl req -new -key /testdir/testssl/mykey.private -out /testdir/testssl/mykey.csr -days 365

            表示生成证书签署请求,使用的私钥文件路径为/testdir/testssl/mykey.private,生成的签署请求的文件为/testdir/testssl/mykey.csr,申请的证书有效期为365天

            执行命令后会要求填入一些信息:

                国家、身份、城市、单位、部门、持有者、管理员邮箱等

            注意:持有者要写成主机名, 否则可能造成后期用户访问时,提示证书与访问的主机名不一致,此处应为www.nwc.com

        2.png

        <3>将生成的请求文件拷贝到CA服务器上

        <4>在CA服务器上进行签署,生成证书,在openssl的配置文件中,定义了签署完成的证书的存放位置为/etc/pki/CA/certs/目录下

            openssl ca -in /tmp/mykey.csr -out /etc/pki/CA/certs/mykey.crt -days 365

            表示签署证书,-in指明请求签署文件的路径,-out指明生成的证书的路径,-days表示签署多少天

            命令执行后,会让确认两次,确认好了之后,即完成了签署的动作,生成了签署过后的证书

        <5>将签署的证书发给请求方

        blob.png 

        3333.png       

        blob.png

    4、证书的吊销

        <1>在客户端获取要吊销的证书的serial
            openssl x509 -in /PATH/FROM/CERT_FILE -noout -serial -subject
        <2>在CA上,根据客户提交的serial与subject信息,对比检验是否与index.txt文件中的信息一致
            吊销证书:
                openssl ca -revoke /etc/pki/CA/newcerts/SERIAL.pem

        <3>生成吊销证书的编号(第一次吊销一个证书时才需要执行)
                echo 01 > /etc/pki/CA/crlnumber
        <4>更新证书吊销列表
            openssl ca -gencrl -out /etc/pki/CA/crl/ca.crl
            查看crl文件:
            openssl crl -in /etc/pki/CA/crl/ca.crl -noout -text

第五章    利用gpg实现加解密

    

    1、gpg实现对称加密

        <1>对称加密file文件
            gpg -c file
            ls file.gpg
        <2>在另一台主机上解密file
            gpg -o file -d file.gpg

    1.png

    2.png

    2、gpg实现公钥加密

        在hostB主机上用公钥加密,在hostA主机上解密
        <1>在hostA主机上生成公钥/私钥对
            gpg –gen-key
        <2>在hostA主机上查看公钥
            gpg –list-keys
        <3>在hostA主机上导出公钥到nwckey.pub

            gpg -a –export -o nwckey.pub
        <4>从hostA主机上复制公钥文件到需加密的B主机上
            scp nwckey.pub HOST_B:/PATH/TO/SOMEWHERE

        <5>在需加密数据的hostB主机上生成公钥/私钥对
            gpg –list-keys
            gpg –gen-key
        <6>在hostB主机上导入公钥
            gpg –import nwckey.pub
            gpg –list-keys
        <7>用从hostA主机导入的公钥,加密hostB主机的文件file,生成file.gpg
            gpg -e -r nwc file
            file file.gpg

        <8>复制加密文件到hostA主机
            scp file.gpg HOST_A:/PATH/TO/SOMEWHERE
        <9>在hostA主机解密文件
            gpg -d file.gpg
            gpg -o file -d file.gpg
        <10>删除公钥和私钥
            gpg –delete-keys nwc
            gpg –delete-secret-keys nwc

第六章    ssh服务

    1、SSH协议的基本概念

        SSH:Secure Shell

        监听在TCP协议的22号端口

        SSH协议版本:

            sshv1:基于CRC-32做MAC,因此不安全,建议勿用

            sshv2:基于双方主机协商选择最安全的MAC实现机制,建议使用。

                    sshv2基于DH实现秘钥交换,基于RSA或DSA实现身份认证

                    客户端通过检查服务器端的主机秘钥来判定是否与其进一步通信

        服务端程序为:openssh-server,配置文件为/etc/ssh/sshd_config

        客户端程序为:openssh-client,配置文件为/etc/ssh/ssh_config

    2、SSH服务器端的相关配置:

        配置文件:/etc/ssh/sshd_config

        服务脚本:/etc/rc.d/init.d/sshd

        服务脚本配置文件:/etc/sysconfig/sshd

        获取关于服务配置文件的帮助:man sshd_config

        /etc/ssh/sshd_config配置文件中相关指令说明:(#开始的相关选项表示使用的是默认值)

                Port 22  指明ssh服务监听的端口

                ListenAddress IP_ADDR  表示监听的地址,可出现多次

                        0.0.0.0表示当前主机的所有地址

                Protocol 2  表示支持的ssh协议版本,建议是2

                SyslogFacility AUTHPRIV  表示日志记录的设施,要想知道该设置的具体日志放在哪里,则查看rsyslog的配置文件/etc/rsyslog.conf文件中的相关定义,此处相当于日志存在/var/log/secure日志中

                LogLevel INFO  表示定义记录的日志级别

                PermitRootLogin yes|no  是否允许管理员以ssh登录

                MaxAuthTries 6  表示认证时的重试次数,为此数字的一半,超过次数后会被锁定一定时间

                MaxSessions 10 表示支持的最大的ssh会话的个数

                AcceptEnv  接受的环境变量参数

                AllowUsers  接受那些用户使用ssh,做用户白名单,只要不在此名单内的用户,都不允许登录

                        如:AllowUsers nwc1 nwc2 nwc3 root

                AllowGroups  接受那些用户组使用ssh,组的白名单

                DenyUsers  不允许那些用户使用ssh,用户黑名单

                DenyGroups  不允许那些用户组使用ssh,组黑名单

                        白名单和黑名单不要同时使用

                X11Forwarding yes|no  是否转发图形窗口

                #KeyRegenerationInterval 1h  密钥的使用时间

                #ServerKeyBits 1024 密钥长度

                #LoginGraceTime 2m 登陆宽限期

                #PermitRootLogin yes root是否可以登录

                #StrictModes yes 严格模式,家目录 属主 属组

                PasswordAuthentication yes 是否使用用户名和密码的方式

                Kerberos集中认证管理

        使用SSH服务的最佳配置方案:

            1)仅适用sshv2版本

            2)限定仅允许哪些用户访问ssh服务

                Allowusers root vivek jerry

                白名单

                DenyUser saroj anjali foo

                黑名单

            3)配置空闲会话超时长

                ClientAliveCountMax  0 

                ClientAliveInterval  300

            4)使用iptables设置ssh服务安全访问策略

            5)改变默认的端口和监听的IP

                port 300

                ListenAddress 192.168.1.5

                ListenAddress 202.54.1.5

                勿使用默认22端口

            6)使用强密码

                生成随机密码的函数示例:

                genpasswd(){

                    local 1=$1

                    [ "$1" == "" ]&& 1=20

                    tr -dc A-Za-z0-9_</dev/urandom | head -c ${1} | xargs

                }

            7)使用公钥认证

            8)禁止空密码登录

            9)使用前利用漏扫工具先评估下破解的可能性

                google:ssh best practice

            10)限制ssh访问频度

            11)记录好日志,经常做日志分析。

    3、用户登录信息的获取:

        /var/log/wtmp  用户成功登录的日志信息,也可直接用last命令显示

        /var/log/btmp  用户失败登录的日志信息,也可用lastb命令显示

        lastlog 每个用户最近一次成功登录的信息

    4、基于SSH的客户端相关工具:

        客户端的命令:ssh

        ssh [OPTIONS] USERNAME@HOST [COMMAND]

        常见选项:(如果不提供USERNAME,则会以当前系统上的用户,作为登录远程主机的用户,如果远程主机上的用户不存在,则无法连接)

            -p PORT  指定登录的端口(如果远程主机的ssh服务修改了默认监听的端口,则需要用-p指定端口),在生产环境中建议将SSH监听的端口改掉

            COMMAND  表示不登录对方主机,在远程主机执行命令,然后结果返回本机后退出

            -b:指定连接的源IP
            -v:调试模式
            -C:压缩方式
            -X: 支持x11转发
            -Y:支持信任x11转发
                ForwardX11Trusted yes
            -t: 强制伪tty分配
                ssh -t remoteserver1 ssh remoteserver2

    5、配置基于秘钥方式进行SSH登录

        SSH的认证机制:

            基于口令

            基于秘钥:

                客户端在本地生成一对秘钥,客户端将公钥复制到服务器端,要登录的用户的家目录下的隐藏目录.ssh目录下一个名为authorized_keys或authorized_keys2文件中,这样即可实现无需密码登录ssh服务端

        配置过程:

            <1>生成秘钥对

                ssh-keygen -t rsa -P ''

                生成的秘钥默认保存至当前用户家目录下的.ssh目录的id_rsa文件中,公钥在id_rsa.pub文件中

                -P 表示不指定使用秘钥文件时的密码,否则以后每次使用秘钥登录时,都要输入秘钥文件的密码

            <2>复制秘钥至远程主机

                ssh-copy-id -i /PATH/TO/公钥文件 USERNAME@HOST

                表示将本机的公钥文件复制到哪个远程主机的哪个用户

    6、基于ssh的复制文件命令:scp

        scp SRC1 SRC2 … DEST

        常用选项有:

            -r 当源是目录时,实现递归复制

            -p 复制时,保留源文件的复制和修改时间戳以及权限

            -q 复制时静默模式

            -C: 压缩数据流

            -P PORT  指定服务器端的端口(如果远程主机的ssh服务修改了默认监听的端口,则需要用-P指定端口)

        分两种情况:

            <1>源文件在本机,目标为远程:

                scp /PATH/TO/FILE1… USERNAME@HOST:/PATH/TO/SOMEWHERE

                注意:源文件为目录时,要使用-r 选项,实现递归复制;多个源时,目标要是目录

            <2>源文件在远程,目标为本机:

                scp USERNAME@HOST:/PATH/TO/FILE… /PATH/TO/SOMEWHERE

                注意:源文件为目录时,要使用-r 选项,实现递归复制,多个源时,目标要是目录

    7、基于ssh的ftp协议的命令:sftp

        查看openssh是不是支持sftp,查看openssh的配置文件/etc/ssh/sshd_config里面,是否有

            Subsystem sftp /usr/libexec/openssh/sftp-server

        这一行的定义,如果有,则证明支持sftp

        用法:sftp USERNAME@HOST  指明以哪个用户登录哪个主机的ftp服务器,登录后可利用help获取ftp命令的使用格式

    8、rsync命令(比scp更快,只复制不同的文件,对于相同的文件不复制)

        基于ssh和rsh服务实现高效率的远程系统之间复制文件

        使用安全的shell连接做为传输方式

            rsync –av /etc server1:/tmp 复制目录和目录下文件(源路径后面没有/)

            rsync –av /etc/ server1:/tmp 只复制目录下文件(原路径后面有/)

        常见选项:

            -n 模拟复制过程

            -v 显示详细过程

            -r 递归复制目录树

            -p 保留权限

            -t 保留时间戳

            -g 保留组信息

            -o 保留所有者信息

            -l 把符号链接文件做为符号文件进行复制(默认)

            -L 将软链接文件指向文件复制

            -a 存档模式,相当于 –rlptgoD,但不保留ACL( -A)和SELinux属性(-X)

    9、SSH的端口转发

        <1>什么是SSH端口转发?
            SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据。但是, SSH 还能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程也被叫做“隧道”( tunneling),这是因为 SSH 为其他 TCP 链接提供了一个安全的通道来进行传输而得名。例如, Telnet, SMTP, LDAP 这些 TCP 应用均能够从中得益,避免了用户名,密码以及隐私信息的明文传输。而与此同时, 如果工作环境中的防火墙限制了一些网络端口的使用,但是允许SSH 的连接,也能够通过将 TCP 端口转发来使用 SSH 进行通讯

        <2>SSH 端口转发能够提供两大功能:
            加密 SSH Client 端至 SSH Server 端之间的通讯数据
            突破防火墙的限制完成一些之前无法建立的 TCP 连接

        <3>本地转发
            ssh -L localport:host:hostport sshserver
            ssh –L 9527:telnetsrv:23 -N sshsrv
            telnet 127.0.0.1 9527
                当访问本机的9527的端口时,被加密后转发到sshsrv的ssh服务,再解密被转发到telnetsrv:23
                data–>localhost:9527–>localhost:XXXXX–>sshsrv:22–>sshsrv:YYYYY–>telnetsrv:23
            选项:
                -f 后台启用
                -N 不开远程shell
                -g 启用网关功能

        <4>远程转发:
            -R sshserverport:host:hostport sshserver
            ssh –R 9527:telnetsrv:23 –N sshsrv
                让sshsrv侦听9527端口的访问,如有访问,就加密后通过ssh服务转发请求到本机ssh客户端, 再由本机解密后转发到telnetsrv:23
                Data–>sshsrv:9527–>sshsrv:22–>localhost:XXXXX–>localhost:YYYYY–>telnetsrv:23

        <5>动态端口转发:
            当用firefox访问internet时,本机的1080端口做为代理服务器, firefox的访问请求被转发到sshserver上,由sshserver替之访问internet
            在本机firefox设置代理socket proxy:127.0.0.1:1080
            #ssh -D 1080 root@sshserver

第七章    利用dropbear提供ssh服务

    

    ssh协议的另一个实现: dropbear

    编译安装dropbear准备:
        <1>安装开发包组:yum groupinstall "Development Tools" -y
        <2>下载源码包,假设为dropbear-2013.58.tar.bz2

    安装:
        <3> 解压:tar xf dropbear-2013.58.tar.bz2
        <4> 查看安装的帮助手册:less INSTALL
        <5> 切换到解压后的目录,并执行./configure
        <6> make,指定要安装那些工具:make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
        <7> make install,指定安装的工具:make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install

    启动ssh服务:
        <8> ls /usr/local/sbin/ /usr/local/bin/
        <9> /usr/local/sbin/dropbear -h
        <10> mkdir /etc/dropbear
        <11> dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key -s 2048
        <12> dropbearkey -t dss -f /etc/dropbear/dropbear_dsa_host_key
        <13> dropbear -p :2222 -F –E #前台运行(因为本机有SSH,为了避免端口冲突,手动指定其运行在2222端口)
                dropbear -p :2222 #后台运行
    客户端访问:
        <14> ssh -p 2222 root@127.0.0.1
        <15> dbclient -p 2222 root@127.0.0.1

第八章    aide监控文件安全性

    

    1、aide是什么

        AIDE(Advanced Intrusion Detection Environment高级入侵检测环境)是一个入侵检测工具,主要用途是检查文件的完整性,审计计算机上的那些文件被更改过了。
        AIDE能够构造一个指定文件的数据库,它使用aide.conf作为其配置文件。 AIDE数据库能够保存文件的各种属性,包括:权限(permission)、索引节点序号(inode number)、所属用户(user)、所属用户组(group)、文件大小、最后修改时间(mtime)、创建时间(ctime)、最后访问时间(atime)、增加的大小以及连接数。 AIDE还能够使用下列算法: sha1、 md5、 rmd160、 tiger,以密文形式建立每个文件的校验码或散列号.
        这个数据库不应该保存那些经常变动的文件信息,例如:日志文件、邮件、 /proc文件系统、用户起始目录以及临时目录

    2、AIDE安装及其配置文件

        安装:yum install aide

        其配置文件为/etc/aide.conf (指定对哪些文件进行哪些种类的检测)

        配置文件相关的定义:      

@@define DBDIR /var/lib/aide    //定义aide的数据库文件
@@define LOGDIR /var/log/aide   //定义aide的日志文件
database=file:@@{DBDIR}/aide.db.gz   //定义aide比对时使用的数据库文件
database_out=file:@@{DBDIR}/aide.db.new.gz    //定义aide创建数据库时的数据文件
//创建好比对数据库后,数据库的名称默认就是new,如果要比对,需要将new去掉,然后利用去掉new后的数据进行验证
#p:      permissions  //定义文件权限的检测
#i:      inode:     //定义文件inode号的检测
#n:      number of links  //定义文件链接数的检测
#u:      user   //定义文件所属主的检测
#g:      group  //定义文件所属组的检测
#s:      size   //定义文件大小的检测
#b:      block count   //定义文件占用块数量的检测
#m:      mtime   //定义文件内容修改时间的检测
#a:      atime   //定义文件访问时间的检测
#c:      ctime   //定义文件修改时间的检测
#S:      check for growing size  
#acl:           Access Control Lists   //定义文件acl权限的检测
#selinux        SELinux security context   //定义selinux的检测
#xattrs:        Extended file attributes   //定义文件xattrs属性的检测
#md5:    md5 checksum  //定义MD5校验检测
#sha1:   sha1 checksum  //定义SHA1校验检测
#sha256:        sha256 checksum   //定义SHA256校验检测
#sha512:        sha512 checksum
#R:             p+i+n+u+g+s+m+c+acl+selinux+xattrs+md5   //定义一个检测项目的组,组名为R,检测的内容为后面各个单独属性的集合
#L:             p+i+n+u+g+acl+selinux+xattrs             //支持自定义的检测项目组
#E:             Empty group
#>:             Growing logfile p+u+g+i+n+S+acl+selinux+xattrs
ALLXTRAHASHES = sha1+rmd160+sha256+sha512+tiger
NORMAL = R+rmd160+sha256
/opt    NORMAL   //定义检测的文件路径,及对其采用哪种方式的检测,后面NORMAL为定义的一个检测项目的集合
/usr    NORMAL
/root   NORMAL
!/usr/src   //路径前面带!表示不检测
!/usr/tmp

       

    3、使用流程

        初始化默认的AIDE的库:
            /usr/local/bin/aide –init
        生成检查数据库(建议初始数据库存放到安全的地方)
            cd /var/lib/aide
            mv aide.db.new.gz aide.db.gz
        检测:
            /usr/local/bin/aide –check
        更新数据库
            aide –update

        a.png

        b.png

        c.png

        e.png

第九章    sudo相关内容

    1、sudo的基础概念

        <1> sudo能够授权指定用户在指定主机上运行某些命令。 如果未授权用户尝试使用 sudo,会提示联系管理员
        <2>sudo可以提供日志,记录每个用户使用sudo操作
        <3>sudo为系统管理员提供配置文件,允许系统管理员集中地管理用户的使用权限和使用的主机
        <4>sudo使用时间戳文件来完成类似“检票”的系统,默认存活期为5分钟的“入场券”
        <5>通过visudo命令编辑配置文件,具有语法检查功能,用visudo -c 可检查配置文件语法

    2、sudo命令本身:

        sudo [-u user] COMMAND
            -V 显示版本信息等配置信息
            -u user 默认为root
            -l,ll 列出用户在主机上可用的和被禁止的命令
            -v 再延长密码有效期限5分钟,更新时间戳
            -k 清除时间戳,下次需要重新输密码(当用户使用sudo时,会要求输入用户密码,用户密码默认5分钟内有效,如果使用sudo -k则可以让密码立即失效,下次使用sudo又要使用密码)            

            -K 与-k类似,还要删除时间戳文件
            -b 在后台执行指令
            -p 改变询问密码的提示符号
                如 -p ”password on %h for user %p

            sudo –i –u nwc切换身份

    3、sudo的配置文件(/etc/sudoers)

        配置文件: /etc/sudoers, /etc/sudoers.d/
        时间戳文件: /var/db/sudo
        日志文件: /var/log/secure

        <1>配置文件支持使用通配符glob:
            ? :前面的字符或词可出现一次或无
            * :前面的字符或词出现零次或多次
            [nwc]:匹配其中一个字符
            [^nwc]:除了这三个字符的其它字符
            \x : 转义
            [[alpha]] :字母 示例: /bin/ls [[alpha]]*

        <2>配置文件规则有两类;
            别名定义:不是必须的
            授权规则:必须的

        <3>一个sudo条目:

                who  which_host=(runas)  command

                在命令前可以使用标签NOPASSWD:就可以让用户在使用该命令时不用输入密码

            格式说明:
                user: 运行命令者的身份
                host: 通过哪些主机
                (runas):以哪个用户的身份
                command: 运行哪些命令

 

        <4>别名机制:类似组的概念,组里面多个角色

                who:User_alias

                which_host:Host_alias

                runas:Runas_alias

                command:Cmnd_alias

                别名必须全部而且只能全部使用大写英文字母的组合

            用户别名:User_alias 别名 =

                后面可以是:

                    用户名

                    用户UID,用#引用

                    组名,用%引用

                    组的GID,用%#引用

                    还可以包含其他已经定义的用户别名

            主机别名:Host_Alias 别名 =

                后面可以是:

                        主机名

                        IP

                        网络地址

                        其他已经定义的主机别名

            以哪个身份运行:Run_Alias 别名 =

                后面可以是:

                        用户名

                        %组名

                        其他已经定义的runas别名

            命令别名:Cnmd_Alias 别名 =

                后面可以是:

                        命令路径(一般为绝对路径)

                        目录(此目录内的所有命令)

                        其他已定义的命令别名

 

    4、sudo示例:

        例如:以nwc用户以root身份运行useradd,usermod命令

               先visudo

               nwc ALL=(root) /usr/sbin/useradd,/usr/sbin/usermod

               当nwc用的时候格式为:sudo /usr/sbin/useradd newbee

        例如:nwc ALL=(root)NOPASSWD:/usr/sbin/useradd,/usr/sbin/usermod

               表示nwc在使用useradd和usermod时都不需要输入密码

        例如:nwc ALL=(root) NOPASSWD:/usr/sbin/useradd,PASSWD:/usr/sbin/usermod

               表示nwc在使用useradd时不要密码,usermod要密码

        例如:

             定义一个用户组别名

                 User_Alias USERADMIN = nwc,%newbee,%nwc

                 组内包含nwc用户,newbee组和nwc组内的所有用户

             定义一个命令组别名

                 Cmnd_Alias ADMINCOMMAND = /usr/sbin/useradd,/usr/sbin/userdel,/usr/bin/passwd [A-Za-z]*,!/usr/bin/passwd root

                 表示定义useradd、userdel命令,passwd命令后必须跟字符,且不能对root进行passwd命令。

             添加条目:

                 USERADMIN  ALL=(root)  NOPASSWD:ADMINCOMMAND

                 表示USERADMIN别名内的所有用户,在所有主机上,以root身份,不需要密码,执行ADMINCOMMAND内的所有命令

        例如:

            nwc ALL=(ALL) ALL
            %wheel ALL=(ALL) ALL

            表示nwc用户可以在任意主机上,以任意身份运行任意命令,wheel组类的用户可以在任意主机上,以任意身份运行任意命令                 例如:
            nwc ALL=(root) /sbin/pidof,/sbin/ifconfig
            %wheel ALL=(ALL) NOPASSWD: ALL

            表示nwc用户可以在任意主机上以root身份运行/sbin/pidof,/sbin/ifconfig命令

            wheel组类的用户可以在任意主机上,以任意身份无需密码运行任意命令

        例如:
            User_Alias NETADMIN=user1,user2
            Cmnd_Alias NETCMD = /usr/sbin/ip
            NETADMIN ALL=( root) NETCMD

            表示定义一个用户别名NETADMIN,该别名内包含用户user1,user2

            定义一个命令别名NETCMD,包含命令/usr/sbin/ip

            NETADMIN内的用户能够在任意主机上,以root身份,运行NETCMD定义的命令,也就是user1和user2能在任意主机上以root身份运行ip命令

        例如:
            User_Alias SYSADER=nwc,user1,%admins
            User_Alias DISKADER=tom
            Host_Alias SERS=www.nwc.com,10.1.32.0/24
            Runas_Alias OP=root
            Cmnd_Alias SYDCMD=/bin/chown,/bin/chmod
            Cmnd_Alias DSKCMD=/sbin/parted,/sbin/fdisk
            SYSADER SERS=(OP) SYDCMD,DSKCMD

            表示定义一个用户别名SYSADER,包含用户nwc,user1,和admins组内的所有用户

            定义一个用户别名DISKADER,包含用户tom

            定义主机别名SERS包含主机名为www.nwc.com的这台主机和10.1.32.0/24这个网络内的所有主机 

            定义一个运行身份的别名OP,包含身份是root

            定义一个命令别名SYDCMD,包含命令/bin/chown,/bin/chmod

            定义一个命令别名DSKCMD,包含命令/sbin/parted,/sbin/fdisk

            定义SYSADER用户别名的用户,在SERS定义的主机上,以root身份,运行SYDAMD和DSKCMD定义的命令,也就是nwc、user1和admins组内的所有用户,能够在www.nwc.com这台主机和10.1.32.0/24这个网络内的所有主机上,以root身份运行/bin/chown,/bin/chmod,/sbin/parted,/sbin/fdisk命令

            

        例如:
            User_Alias ADMINUSER = adminuser1,adminuser2
            Cmnd_Alias ADMINCMD = /usr/sbin/useradd,/usr/sbin/usermod, /usr/bin/passwd [a-zA-Z]*,!/usr/bin/passwd root
            ADMINUSER ALL=(root) NOPASSWD:ADMINCMD,PASSWD:/usr/sbin/userdel

            表示定义一个ADMINUSER的用户别名,包括adminuser1和adminuser2

            定义一个ADMINCMD命令别名,包括useradd、usermod命令,passwd命令后面跟字母开头的字符串,但不能执行passwd root,也就是不能对root改密

            定义允许adminuser1和adminuser2用户能够在所有主机上,不用输入密码执行useradd、usermod、和passwd定义的相关命令,但是需要密码执行userdel命令

        例如
            Defaults:nwc runas_default=tom
            nwc ALL=(tom,jerry) ALL

            表示授权nwc用户在所有主机上以tom或Jerry身份,运行所有命令

            上面的Defaults 表示当nwc用sodu执行命令时,如果不用-u指明以谁的身份,则默认以tom的身份执行命令

        例如
            nwc 10.1.32.68,10.1.32.22 = (root)  /usr/sbin/,!/usr/sbin/useradd

            表示授权nwc用户在10.1.32.68和10.1.32.22主机上以root身份执行/user/sbin/下的所有命令,但是不包括useradd命令

        例如
            nwc ALL=(ALL) /bin/cat /var/log/message*

            表示授权nwc用户在所有主机上,以任意身份,运行cat /var/log/message*命令

            注意,此种方式是非常危险的,因为用户可以利用命令 cat /var/log/message  /etc/shadow ….因为*代表任意字符,故后面可以跟上任何文件

原创文章,作者:M20-1倪文超,如若转载,请注明出处:http://www.178linux.com/48542

(2)
上一篇 2016-09-23 11:08
下一篇 2016-09-23 15:32

相关推荐

  • 关于取路径名与基名的探讨和扩展-20160806

                          关于取路径名与基名的探讨和扩展     这两天学习grep  ,   egrep  ,  sed  &nb…

    Linux干货 2016-08-07
  • N25-第一周作业

    一,描述计算机的组成及其功能。        计算机(Computer)是一种能够按照事先存储的程序,自动、高速地进行大量数值计算和各种信息处理的现代化智能电子设备。由硬件和软件所组成,两者是不可分割的。        计算机的组成分为控制…

    Linux干货 2016-12-03
  • 关于生命中的根

    关于生命中的根    擦干心中的血和泪痕    留住我们的根 关于生命中的根 鸿蒙初辟,万物生于根 寻根之旅 根就是根 我即为根 路在何方 鸿蒙初辟,万物生于根    自linux老祖Torvalds创根之始至今,根一直为linux之本,而FHS(Filesystem Hierarchy Stand…

    Linux干货 2016-10-27
  • tomcat优化

    安装过程就不多说了,本次主要说明我在实际工作中的一些优化。    1,修改tomcat的运行模式,常见的有 bio,nio, apr三种    我选择的apr模式,这种对tomcat的性能有较大提高. a:可以根据压力测试工具来进行测试观察。(其实我没对修改apr模式后压测,我直接问百度的) b:重新启动tomcat后…

    Linux干货 2016-06-28
  • 磁盘管理之文件系统

                             文件系统     文件系统是操作系统用于…

    Linux干货 2016-09-06
  • Python线程指南

    本文介绍了Python对于线程的支持,包括“学会”多线程编程需要掌握的基础以及Python两个线程标准库的完整介绍及使用示例。 注意:本文基于Python2.4完成,;如果看到不明白的词汇请记得百度谷歌或维基,whatever。 尊重作者的劳动,转载请注明作者及原文地址 >.< 1. 线程基础 1.1. 线程状态 线程有5种状态,状态转换的过程如…

    2015-03-13

评论列表(1条)

  • 马哥教育
    马哥教育 2016-09-26 11:17

    x写的很好,特别是加密揭解密部分,,对各种加密算法的应用场景解析的特别透彻,通读全文能,让人看到很多专业性所在。