一、前言

在经历了人生的很多至暗时刻后,你读到了这篇文章,你会后悔甚至愤怒:为什么你没有早点写出这篇文章?!

你的至暗时刻包括:

1.你所在的项目需要对接银行,对方需要你提供一个加密证书。你手上只有一个六级英语证书,不确定这个是否满足对方需求。由于你迟迟无法提供正确的证书,项目因此延期,加薪计划泡汤,月供断了,女朋友分手了,你感觉人生完了。

2. 你老骥伏枥 2 个月,终于搞懂了.crt 格式证书。加入到新项目,项目在进行证书托管改造。哈哈,这题我会,就是把证书文件上传到托管系统。你对项目组成员大喝一声,放开那些证书,让我来!挤进去一看,是陈年老项目了,根本没有证书,当时使用是公钥和私钥,如何公钥和私钥变成证书⋯⋯由于你迟迟无法提供正确的证书,项目因此延期,加薪计划泡汤,月供断了,女朋友分手了,你感觉人生完了。

3. 你卧薪尝胆 3 个月,摸清楚了 SSL 证书的来龙去脉。踌躇满志加入到新项目,你向项目经理痛陈血泪史,经此一役,你已经成长为安全证书方面的专家。项目经理喜出望外,正好项目在进行数据安全改造,数据库需要启用 SSL,来得正是时候,不着急,明天下班前提供几个密钥文件就行。越明日,下班前半小时,你缓缓走向项目经理,“你要的货到了”,便排出三个证书,这个是 key 文件,这个是公钥文件,这个是证书文件。项目经理点点头又摇摇头,我要的是JKS 文件呀。你说,明天提供。越明日,下班前的半个小时,你把 JKS 格式文件交给项目经理,项目经理点点头又摇摇头,密码呢?没有密码怎么行?由于你迟迟无法提供正确的证书,项目因此延期,加薪计划泡汤,月供断了,女朋友分手了,你感觉人生完了。

本文将从以下几部分来揭示 RSA 密钥文件的鲜为人知的秘密:

  • RSA 算法数学基础
  • RSA秘钥体系六层模型
  • RSA 工具使用
  • RSA密钥使用场景

注:虽然密钥与证书严格意义上并不等同,但为了表述方便,没有特殊指定的话,本文中的密钥一词涵盖了公钥,私钥,证书等概念。

二、RSA 算法数学基础

RSA 算法是基于数论的,RSA算法的复杂性的基础在于一个大数的素数分解是NP难题,非常难破解。RSA 算法相关的数学概念:

对于任意一个数 x,可以计算出 y:

通过 y,可以计算出 x:

也就是说,x 通过数对 (m,e) 生成了 y 后,可以通过数对 (m, d) 将 y 还原成 x。

这里,我们实际上演示了RSA加密解密的数学过程。通过公式 (1),根据 x 计算得出 y 的过程就是加密,通过公式 (2),根据 y 计算得出 x 的过程就是解密。

在实际应用中,RSA 算法通过公钥进行加密,私钥进行解密,因此数对 (m,e) 就是公钥,(m, d) 就是私钥。

实际上为了提高私钥解密速度,私钥会保存一些中间结果,例如 p, q, e, 等等。

所以在实际应用中,可以通过私钥导出公钥。

三、 RSA秘钥六层模型

为了方便理解RSA密钥的原理,本人创造性地发明了RSA密钥六层模型概念。每一层定义了自己的职责和边界,层级越低,其表示的内容越倾向于抽象和理论;层级越高,其表示的内容越倾向于实际应用。

  • Data:数据层,定义了RSA密钥的数学概念(m,e,p,q等)或者参与实体(subject, issuer等)。
  • Serialization:序列化层,定义了将复杂数据结构序列化的方法。
  • Structure:结构层,定义了不同格式的RSA密钥的数据组织形式。
  • Text:文本层,定义了将二进制的密钥转换成文本的方法。
  • Presentation:表现层,定义了文本格式密钥的表现形式。
  • Application:应用层,定义了RSA密钥使用的各种场景。

下面对每一层进行具体说明。

3.2 数据层

从上文可知,秘钥是一个数据结构,每个结构包含了 2 个或更多的成员(公钥包含 m 和 e,私钥包含 m,d,e 以及其他一些中间结果)。为了将这些数据结构保存在文件中,需要定义某种格式对秘钥进行序列化。

3.3 序列化层

目前常见的定义数据结构的格式包括 JSON 和 XML 等文本格式。

比如,理论上我们可以把公钥定义为一个 JSON:

JSON格式密钥

{
"m":"15",
"e":"3"
}

或者,也可以把私钥定义为一个 XML:

<?xml>
<key>
<module>15</module>
<e>3</e>
<d>3</d>
<p>3</p>
<q>5</q>
<key>

但是 RSA 发明的时候,这两种格式都还不存在。因此科学家们选择了当时比较流行的语法格式ASN.1。

3.3.1 ASN.1

ASN.1 全称是 Abstract Syntax Notation dot one,(抽象语法记号第1版)。数字1被ISO加在ASN的后边,是为了保持ASN的开放性,可以让以后功能更加强大的ASN被命名为ASN.2等,但至今也没有出现。

ASN.1描述了一种对数据进行表示、编码、传输和解码的数据格式。它提供了一整套正规的格式用于描述对象的结构,而不管语言上如何执行及这些数据的具体指代,也不用去管到底是什么样的应用程序。

3.3.2 ASN.1 编码规则

ASN.1的具体语法可以参考维基百科(https://zh.wikipedia.org/wiki/ASN.1),在此只作简要说明。

ASN.1 中数据类型表示是 T-L-V 的形式:头 2 个字节代表数据类型,接下来的 2 个字节代表字节长度,V 代表具体值。常见的基础类型的值包括 Integer, UTF8String, 复合结构包括 SEQUENCE, SET.秘钥和证书都是 SEQUENCE 类型,而 SEQUENCE 的 type 是 0x30,且长度是大于 127 的,因此第2 个字节是 0x82. ASN.1 编码表示的数据是二进制数据,通常通过 BASE64 转化成字符串保存在 pem 文件中,而 0x3082 经过 BASE64 编码后,就是字符串 MI,因此所有 PEM 文件存储的秘钥开始的前两个字符是 MI。

BER, CER, DER 是 ASN.1 编码规则。其中 DER(Distinguish Encode Rules) 是无歧义编码规则,保证相同的数据结构产生的序列化结果也相同的。

ASN.1 只是定义了抽象数据的序列化方式,但是具体的编码还需要进一步定义。

严格来说,ASN.1 还不是一种定义数据的格式,而是一种语法标准,按照这种标准,可以制定各种各样的格式。

3.4 结构层

根据秘钥文件用途不同,以下标准定义了不同的结构来对秘钥数据进行 ASN.1 编码。通常而言,不同格式的秘钥暗示了不同的结构。

  • pkcs#1 用于定义 RSA 公钥、私钥结构
  • pkcs#7 用于定义证书链
  • pkcs#8 用于定义任何算法公私钥
  • pkcs#12 用于定义私钥证书
  • X.509 定义公钥证书

这些格式的具体区别比较参见下文3.5.2

3.5 表现层

可以看到 ASN.1 及其编码规则(BER, CER, DER)定义的是二进制规则,保存在文件中也是二进制格式。由于当时的电子邮件标准不支持二进制内容的传输,如果秘钥文件通过电子邮件传输,就需要将二进制文件转换成文本文件。这就是 PEM(Privacy-Enhanced Mail, 私密增强邮件)的由来。因此,PEM 文件中保存的秘钥内容是 ASN.1 编码生成的二进制内容,再进行 base64 编码后的文本。

另外,为了方便用户识别是何种格式,中文件的首尾加上一行表示身份的文本。PEM 文件一般包含三部分:首行标签,BASE64 编码的文本数据,尾行标签。

-----BEGIN <label>-----
<BASE64 ENCODED DATA>
-----END <label>-----

针对不同的格式,<label> 值不一样。

3.5.2 PEM 文件格式小结

3.6 应用层

在实际使用中,不仅仅需要使用公私钥对数据进行加解密,还需要根据不同的使用场景,解决密钥的分发、验证等。第5节列举了RSA密钥的一些常见使用场景。

四、工具

4.1 openssl

注意:下面的命令中-RSAPublicKey_in, -RSAPublicKey_out选项需要openssl1.0以上版本支持,如果报错,请检查 openssl 版本。

4.1.1 创建秘钥文件

# 生成 pkcs#1 格式2048位的私钥
openssl genrsa -out private.pem 2048 #从私钥中提取 pkcs#8 格式公钥
openssl rsa -in private.pem -out public.pem -pubout #从私钥中提取 pkcs#1 格式公钥
openssl rsa -in private.pem -out public.pem -RSAPublicKey_out

4.1.2 秘钥文件格式转换

#pkcs#1 公钥转换成 pkcs#8 公钥
openssl rsa -in public.pem -out public-pkcs8.pem -RSAPublicKey_in #pkcs#8 公钥转换成 pkcs#1 公钥
openssl rsa -in public-pkcs8.pem -out public-pkcs1.pem -pubin -RSAPublicKey_out #pkcs#1 私钥转换成 pkcs#8 私钥
openssl pkcs8 -in private.pem -out private-pkcs8.pem -topk8 #pkcs#8 私钥转换成 pkcs#1 私钥
openssl rsa -in private-pkcs8.pem -out private-pkcs1.pem

4.1.3 查看秘钥文件信息

#查看公钥信息
openssl rsa -in public.pem -pubin -text -noout #查看私钥信息
openssl rsa -in private.pem -text -noout

4.1.4 证书

RSA证书

#从现有私钥创建 CSR 文件
openssl req -key private.pem -out request.csr -new #从现有 CSR 文件和私钥中创建证书,有效期365天
openssl x509 -req -in request.csr -signkey private.pem -out cert.crt -days 365 #生成全新证书和私钥
openssl req -nodes -newkey rsa:2048 -keyout root.key -out root.crt -x509 -days 365 #通 过 现 有 证 书 和 私 钥 (作 为CA ) 为 其 他 CSR 文 件 签 名
openssl x509 -req -in child.csr -days 365 -CA root.crt -CAkey root.key -set_serial 01 -out child.crt #查看证书信息
openssl x509 -in child.crt -text -noout #从证书中提取公钥
openssl x509 -pubkey -noout -in child.crt > public.pem 

4.1.5 JKS

#将CA证书转换成JKS格式
keytool -importcert -alias Cacert -file ca.crt -keystore truststoremysql.jks -storepass password123 #将client.crt和client.key转换成PKCS#12格式
openssl pkcs12 -export -in client.crt -inkey client.key -name "mysqlclient" -passout pass:mypassword -out client-keystore.p12 #将PKCS#12格式转换成JKS格式
keytool -importkeystore -srckeystore client-keystore.p12 -srcstoretype pkcs12 -srcstorepass mypassword -destkeystore clientstore.jks -deststoretype JKS -deststorepass password456

五、 RSA密钥使用场景

5.1 HTTPS单向认证

由于HTTP协议是明文传输,为了保证HTTP报文不被泄露和篡改,HTTPS通过SSL/TLS协议对HTTP报文进行加解密。

简单来说,HTTPS协议要求客户端和服务端建立连接的过程中,首先进行会话密钥交换,然后使用该会话密钥对通信报文进行加解密。整个通信过程如下:

  1. 服务端通过4.1.4所示方法创建RSA证书server.crt和私钥server.key,并在WEB服务器中进行配置。
  2. 客户端与服务端建立连接,服务端向客户端发送证书server.crt。
  3. 客户端对服务端证书进行校验,并随机生成会话密钥,将通过服务端证书对会话密钥进行加密,传给服务端。
  4. 服务端通过server.key对加密后的会话密钥进行解密,获得会话密钥原文。
  5. 客户端通过会话密钥对HTTP报文进行加密,传给服务端。
  6. 服务端通过会话密钥对HTTP加密报文进行解密,获得HTTP报文原文。
  7. 服务端通过会话密钥对HTTP响应报文进行加密,返回给客户端。
  8. 客户端通过会话密钥对HTTP响应报文进行解密,获得HTTP响应报文原文。
​(图1. HTTPS单向认证)

5.2 HTTPS双向认证

5.1节描述的HTTPS场景是一个通用场景,整个过程只有客户端对于服务端的验证,即客户端拿到服务端的证书后,会对证书进行有效性验证,比如是否是CA签名的,是否仍处于有效期内等。这种单向验证在浏览器访问等场景中没有问题,因为这种服务设计地目的就是对外数以万计的用户提供服务。但是在某些场景,比如说仅对特定企业、商户提供服务,服务端需要对客户端进行验证,通过验证的受信客户端才能正常。

访问服务端时,就需要用到HTTPS双向认证。

HTTPS双向认证的过程,就是在HTTPS单向认证的基础之上,增进服务端对客户端的认证。解决方案的思路就是,客户端保存客户端证书client.crt,但是客户端证书不是客户端自己签名或者CA签名,而是由服务端的root.key进行签名。在HTTPS双向认证过程中,客户端需要将客户端证书client.crt发送给服务端,服务端使用root.key进行验证无误后,方可进行后续通信;否则,该客户端即非受信客户端,服务端拒绝提供后续服务。

具体通信过程如下所示:

  1. 服务端通过4.1.4所示方法创建RSA证书server.crt和私钥server.key,并在WEB服务器中进行配置。
  2. 客户端与服务端建立连接,服务端向客户端发送证书server.crt。
  3. 客户端对服务端证书进行校验,验证通过后继续后续流程;验证不通过则断开连接,流程结束。
  4. 服务端向客户端发送报文,请求客户端发送客户端证书。
  5. 客户端向服务端发送客户端证书。
  6. 服务端通过root.key对客户端证书进行验证,验证无误进行后续流程;否则断开连接,流程结束。
  7. 客户端随机生成会话密钥,将通过服务端证书对会话密钥进行加密,传给服务端。
  8. 服务端通过server.key对加密后的会话密钥进行解密,获得会话密钥原文。
  9. 客户端通过会话密钥对HTTP报文进行加密,传给服务端。
  10. 服务端通过会话密钥对HTTP加密报文进行解密,获得HTTP报文原文。
  11. 服务端通过会话密钥对HTTP响应报文进行加密,返回给客户端。
  12. 客户端通过会话密钥对HTTP响应报文进行解密,获得HTTP响应报文原文。

可以看出,向较于HTTPS单向认证过程,HTTPS双向认证过程在客户端验证服务端证书之后,在向服务端发送加密的会话密钥之前,会增加客户端向服务端发送客户端证书client.crt,服务端对该证书进行验证的过程

​(图2. HTTPS双向认证)

5.3 MySQL开启 SSL

MySQL提供SSL的原理,与HTTPS类似,不同之处在于MySQL提供的服务的对象不会是成千上万的普通用户,因此对于CA的需求并不高。

因此实际CA证书通常都是服务端自己生成。

与HTTPS类似,MySQL提供两种形式的SSL认证机制:单向认证和双向认证。

5.3.1 MySQL的SSL单向认证

(1)服务端配置文件:ca.crt, server.crt, server.key,其中server.crt由ca.crt签名生成。

(2)客户端配置文件:ca.crt,ca.crt与服务端的ca.crt相同。

(3)客户端生成JKS文件

keytool -importcert -alias Cacert -file ca.crt -keystore truststoremysql.jks -storepass password123

(4)通过jdbc字符串配置SSL选项和JKS文件

verifyServerCertificate=true&useSSL=true&requireSSL=true&trustCertificateKeyStoreUrl=file:./truststoremysql.jks&trustCertificateKeyStorePassword=password123

5.3.2 MySQL的SSL双向认证

(1)服务端配置文件:ca.crt, server.crt, server.key, 其中server.crt由ca.crt签名生成。

(2)客户端配置文件:ca.crt, client.crt, client.key, 其中ca.crt与服务端的ca.crt相同, client.crt由ca.crt签名生成。

(3)客户端生成trustKeyStore文件

keytool -importcert -alias Cacert -file ca.crt -keystore truststore.jks -storepass password123

(4)客户端生成clientKeyStore文件

keytool -importcert -alias Cacert -file ca.crt -keystore clientstore.jks -storepass password45

(5)通过jdbc字符串配置SSL选项和JKS文件

verifyServerCertificate=true&useSSL=true&requireSSL=true&trustCertificateKeyStoreUrl=file:./truststore.jks&trustCertificateKeyStorePassword=password123&clientCertificateKeyStoreUrl=file:./clientstore.jks&clientCertificateKeyStorePassword=password45

关于MySQL的SSL认证更多细节可以参考:

附录A  不同格式的 ASN.1 编码

A.1 pkcs#1

A.1.1 公钥

RSAPublicKey ::= SEQUENCE {
modulus INTEGER , -- n
publicExponent INTEGER -- e
}

A.1.2 私钥
RSAPrivateKey ::= SEQUENCE {
version Version ,
modulus INTEGER , -- n
publicExponent INTEGER , -- e
privateExponent INTEGER , -- d
prime1 INTEGER , -- p
prime2 INTEGER , -- q
exponent1 INTEGER , -- d mod (p-1)
exponent2 INTEGER , -- d mod (q-1)
coefficient INTEGER , -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}

A.2 pkcs#8

A.2.1 pkcs#8 公钥

PublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier ,
PublicKey BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER ,
parameters ANY DEFINED BY algorithm OPTIONAL
}

A.2.2 pkcs#8 私钥

OneAsymmetricKey ::= SEQUENCE {
version Version ,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier ,
privateKey PrivateKey ,
attributes [0] Attributes OPTIONAL ,
...,
[[2: publicKey [1] PublicKey OPTIONAL ]],
...
}
PrivateKey ::= OCTET STRING
-- Content varies based on type of key. The
-- algorithm identifier dictates the format of
-- the key.

A.3 X.509

A.3.1 X.509 证书

Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate ,
signatureAlgorithm AlgorithmIdentifier ,
signatureValue BIT STRING
} TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber ,
signature AlgorithmIdentifier ,
issuer Name,
validity Validity ,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo ,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL ,
-- If present , version MUST be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL ,
-- If present , version MUST be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL
-- If present , version MUST be v3
} Version ::= INTEGER { v1(0), v2(1), v3(2) } CertificateSerialNumber ::= INTEGER Validity ::= SEQUENCE {
notBefore Time,
notAfter Time
} Time ::= CHOICE {
utcTime UTCTime ,
generalTime GeneralizedTime
} UniqueIdentifier ::= BIT STRING SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier ,
subjectPublicKey BIT STRING
} Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension Extension ::= SEQUENCE {
extnID OBJECT IDENTIFIER ,
critical BOOLEAN DEFAULT FALSE ,
extnValue OCTET STRING
-- contains the DER encoding of an ASN.1 value
-- corresponding to the extension type identified
-- by extnID
}
 

作者:Zhu Ran ,来自vivo互联网技术团队

深入剖析 RSA 密钥原理及实践的更多相关文章

  1. 轻松学习RSA加密算法原理

    转自:http://blog.csdn.net/sunmenggmail/article/details/11994013 http://blog.csdn.net/q376420785/articl ...

  2. 轻松学习RSA加密算法原理 (转)

    轻松学习RSA加密算法原理 (转) http://blog.csdn.net/q376420785/article/details/8557266 http://www.ruanyifeng.com/ ...

  3. SSH 的原理和实践

    最近自己在学习使用SSH,现将自己理解的SSH原理和实践SSH的操作写成一篇博客,以供日后查看. 一.SSH是什么?为什么会出现SSH? SSH英文全称是Secure Shell,即安全外壳.首先SS ...

  4. (转) RSA算法原理(一)

    最近用到了RSA加密算法,虽然有现成的,但是想看看它的原理,翻到此文,感觉写得很好,通俗易懂,转了.   作者: 阮一峰 日期: 2013年6月27日 如果你问我,哪一种算法最重要? 我可能会回答&q ...

  5. RSA加密算法原理及RES签名算法简介

    第一部分:RSA算法原理与加密解密 一.RSA加密过程简述 A和B进行加密通信时,B首先要生成一对密钥.一个是公钥,给A,B自己持有私钥.A使用B的公钥加密要加密发送的内容,然后B在通过自己的私钥解密 ...

  6. 阮一峰:RSA算法原理(一)

    今天看到一篇好文章,关于加密算法,收藏了觉得不过瘾,还是自己贴一遍,也能加深一下印象. 原文链接:http://www.ruanyifeng.com/blog/2013/06/rsa_algorith ...

  7. (转)RSA算法原理

    RSA算法原理(二)   作者: 阮一峰 日期: 2013年7月 4日 上一次,我介绍了一些数论知识. 有了这些知识,我们就可以看懂RSA算法.这是目前地球上最重要的加密算法. 六.密钥生成的步骤 我 ...

  8. RSA算法原理(一)

    如果你问我,哪一种算法最重要? 我可能会回答"公钥加密算法". 因为它是计算机通信安全的基石,保证了加密数据不会被破解.你可以想象一下,信用卡交易被破解的后果. 进入正题之前,我先 ...

  9. RSA算法原理——(3)RSA加解密过程及公式论证

    上期(RSA简介及基础数论知识)为大家介绍了:互质.欧拉函数.欧拉定理.模反元素 这四个数论的知识点,而这四个知识点是理解RSA加密算法的基石,忘了的同学可以快速的回顾一遍. 一.目前常见加密算法简介 ...

  10. RSA算法原理——(2)RSA简介及基础数论知识

    上期为大家介绍了目前常见加密算法,相信阅读过的同学们对目前的加密算法也算是有了一个大概的了解.如果你对这些解密算法概念及特点还不是很清晰的话,昌昌非常推荐大家可以看看HTTPS的加密通信原理,因为HT ...

随机推荐

  1. 前端解析excel表格

    需求如下: 前端拿到表格中的数据,对数据做以下判断,并将拿到的数据转换成以下json格式,传给后端. 具体实现: 下载npm包:npm install xlsx --save 在vue文件中引入依赖: ...

  2. 用友vs金蝶产品分析(云星空与YonSuite)

    产品定位 用友与金蝶二者面对的客户群体是相同的:都是为成长型企业提供一体化服务,由于金蝶云星空发展较早,在部分产品功能上具备一定的先发优势:在产品的架构上,由于YS采用目前最先进的云原生和微服务架构, ...

  3. PX4安装环境测试

    1.ROS环境测试 安装ROS版本:melodic roscore // 注意下面是打开一个新的终端,roscore一直在运行 rosrun turtlesim turtlesim_node // 再 ...

  4. linux-ELK安装配置

    前言:   ELK 是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch.Logstash 和 Kibana.    • Elasticsearch 是一个搜索和分析引擎.     ...

  5. [CF1748D] ConstructOR

    题目描述 You are given three integers $ a $ , $ b $ , and $ d $ . Your task is to find any integer $ x $ ...

  6. eclipse的问题

    在我使用eclipse的时候出现的一个问题 就是因为汉化之后出现的问题 问题的解决办法 点击帮助 关于 安装细节 选中Babel Language Pack for rt.rap in Chinese ...

  7. Tensorflow2.0使用Resnet18进行数据训练

    在今年的3月7号,谷歌在 Tensorflow Developer Summit 2019 大会上发布 TensorFlow 2.0 Alpha 版,随后又发布了Beta版本. Resnet18结构 ...

  8. 华企盾DSC防泄密软件:svn、git更新后有感叹号常见处理方法

    1.查看客户端日志检查TSVNcache.exe进程是否是legal:1 2.TSVNcache.exe进程是否允许访问未配置加密进程的后缀 3.svn服务器不是加密进程也未装网络驱动,或者加密类型未 ...

  9. 盘点前端的那些Ajax请求:从ES5到React

    说起前端开发,Ajax请求是绕不开的技术点.然而,程序语言更新换代越来越快,Ajax请求的方式也是各有不同. 在使用ES5开发的时候,我们还在使用最原始的XMLHttpRequest对象: // cr ...

  10. Javascript Ajax总结——其他跨域技术之Comet

    Comet指一种更高级的Ajax技术( 也称 "服务器推送" ),一种服务器向页面推送数据的技术.Comet能够让信息近乎实时地被推送到页面上,非常适合体育比赛的分数和股票报价.有 ...