目录
9.3.5 服务器端脚本(server-side scripting)
第九章 应用设计与开发
9.1 应用程序和用户界面
一个典型的应用程序包括:一个处理用户界面的前端+一个和数据库通信的后端+一个包含业务逻辑的中间层:
客户端-服务器架构(胖客户端):应用程序在用户的机器上运行并访问中央数据库
- 缺点,升级比较困难,用户需要安装应用程序
基于web的应用程序:浏览器作为前端+应用程序作为后端
web浏览器已经成为通用前端,它通过互联网连接后端。
web浏览器使用一种标准的语法:超文本标记语言(HyperText Markup Language,HTML)标准,既支持信息的格式化显示,也支持基于表格的界面的创建。
9.2 web基础
9.2.1 统一资源定位符
统一资源定位符(Uniform Resource Locator, URL)是web上每个可访问文档在全球唯一的名字。
URL由三部分组成:
- 第一部分:表示文档如何被访问。http表示超文本传输协议(HyperText transfer protocol, HTTP),是一个传输HTML文档的协议
- 第二部分: www.acm.org,表示web服务器的机器名称/地址
- 第三部分:其余部分是文件在机器上的路径名,或者文档在机器中的唯一标识
9.2.2 超文本标记语言HTML
HTML有很多标签,<html><body><table><form>
HTML还支持样式表(stylesheet),它可以改变如何展示HTML格式化结构的默认定义,以及其他显示属性。
层叠样式表(Cascading Stylesheet, CSS)标准允许同一个样式表用于多个HTML文档,使得一个web站点上的所有页面具有独特而统一的样式。
HTTP定义了两种请求:get请求和post请求。
9.2.3 web服务器和会话
web服务器(web server)是运行于服务器上的程序,它接收来自web浏览器的请求,并以HTML文档的形式返回结果。浏览器和Web服务器通过HTTP通信。
通信协议:web服务器 --GGI协议-- 引用服务器 ---ODBC,JDBC协议-- 数据库服务器
- 公共网关接口CGI(Common Gateway Interface, CGI)标准:定义了Web服务器与应用程序服务器通信的协议。
- 应用程序通常通过ODBC, JDBC或者其他协议与数据服务器进行通信,以获取或存储数据
三层web应用体系结构 和 二层web应用体系结构:
- 三层结构:web服务器+应用服务器+数据库服务器。
- 缺点:增加了系统的开销;CGI接口为每个请求都开启一个新的进程为之服务,这导致更大的开销
- 两层结构:应用程序作为Web服务器本身的一部分+数据库服务器
对比客户端与web服务器的连接-与-数据库服务器连接的区别?
- 客户端与Web服务器的连接:它们之间不存在持续的连接,当web服务器接收到一个请求时,临时创建一个连接以发送请求并解释偶来自web服务器的响应。但是连接可能会关闭,且下一个请求可以生成一个新的连接。
- HTTP协议是无连接的(connectionless)。原因是:大多数计算机能同时接纳的连接数目有限,如果web中大量的站点对单台服务器建立连接,就会超过限制,拒绝后续的服务。而使用无连接协议,当满足请求时连接可以立刻断开,为其他请求留出空间。
- 会话:大多数的web应用需要会话信息,以允许有意义的用户交互。
- 例如:应用程序需要认证用户。每次会话应进行一次验证,会话中的交互不需要重新认证。
- 尽管连接会关闭,但是为了实现会话,可以在客户端存储额外的信息,并随着会话中每个请求返回;服务器使用这个信息来辨别出请求时用户会话的一部分。关于会话的额外信息也同样需要存储在服务器端维护。——这种额外信息以网络跟踪器(cookie)的方式存储在客户端。
- Cookie——一个cookie是一段包含关联信息的文本,并关联一个名字。一个域(站点)只能获取到它自己设置的cookie,而不能得到其他站点设置的cookie,而且cookie可以跨域复用。
- 例如:google.com可能设置一个名为prefs的cookie。
- 对于每一个请求,google.com都能从用户的浏览器中得到这个名为prefs的cookie,然后根据指定的偏好展示结果。
- 例如:google.com可能设置一个名为prefs的cookie。
- 为了跟踪用户会话的目的,应用程序可能会产生一个会话标识符(通常是一个当前没有用作会话标识符的随机数),然后发送给包含这个会话标识符的名为比如sessionid的cookie。该会话标识符也保存在服务器本地。
- 当请求进来时,应用服务器向客户端请求名为sessionid的cookie。
- 如果客户端没有该cookie,或者返回的值不是当前在服务器中记录的有效会话标识符,应用程序认为该请求不是当前会话的一部分。
- 如果cookie的值与一个存储的会话标识符匹配,则该请求就被识别为有一个进行中的会话的一部分。
- 当请求进来时,应用服务器向客户端请求名为sessionid的cookie。
- 如果一个用户需要安全的鉴别用户,则它只能对用户进行认证之后再设置cookie,例如:输入正确的账户和密码之后才通过认证。
- 对于高安全要求的应用,服务器可能会在有效期之后/或用户注销时使会话无效。
- 对于低安全要求的应用,cookie可能永久存储在浏览器和服务器中,它们识别出用户对同一网站的后续访问,而不需要输入任何验证。
- ODBC和JDBC与数据库服务器的连接:会创建一个会话,且会话信息保留在服务器和客户端,直到会话结束——信息包括该用户的用户标识符和用户已设置的会话参数等。
9.3 servlet和JSP
Java servlet规格说明定义了一种web服务器与应用服务器间通信的应用程序编程接口。
Java HTTPServlet是Servlet API的具体实现。
当服务器启动/服务器收到远程的HTTP请求指定访问某个特定的servlet时,servlet的代码被加载到Web服务器中。servlet的作用是处理这些请求,并生成HTML页面返回给客户端浏览器的请求。
9.3.1 一个servlet的例子
servlet对HTTP请求动态生成响应。
每次请求都会生成一个新的线程,在线程中执行调用,因此多个请求就可以并行处理。
请求和输出:HttpServletRequest,HttpServletResponse
9.3.2 servlet会话
浏览器和web服务器之间的交互是无状态的。
cookie可以用来识别一个请求是否与前一个请求来自同一个浏览器会话。
servlet API提供了跟踪会话和存储会话相关信息的方法。
HttpServletRequest.getSession(false)获取发出请求的浏览器session(设置为true表示请求时新请求时,必须创建新的会话对象)。
- 当getSession()被调用时,服务器会要求客户端返回具有指定名字的cookie;如果客户端没有该cookie,或者返回的cookie与任何进行中的会话都不匹配,则getSession()返回空值,并且servlet会将用户指引到一个登录页面。
- 登录成功后,servlet会执行getSession(true)返回一个新的会话对象。
- 为了创建一个新的会话,web服务器内部执行以下任务:
- 在客户端浏览器设置cookie,用会话标识作为它所关联的值。
- 在服务端创建一个新的会话对象,并将会话标识符的值与会话对象关联。
- 为了创建一个新的会话,web服务器内部执行以下任务:
9.3.3 servlet的生命周期
servlet的生命周期由web服务器控制。
当客户端请求特定的servlet --> 服务器检查是否存在该servlet实例
-->如果不存在,web服务器就将servlet类加载到JVM中,并创建servlet类的一个实例;并且Web服务器调用init()方法,初始化该实例。注意:每个servlet实例仅在加载的时候初始化一次
--> 确定servlet实例存在后,Web服务器调用servlet的service()方法,并以一个request和response对象作为参数。默认情况下,服务器启动一个新的线程执行service()方法。
--> 当不再需要servlet时,调用destroy()方法停止一个servlet。服务器可以设置当多长时间没有对某个servlet的请求,就自动停止它。
9.3.4 servlet支持
许多应用服务器都提供servlet的内嵌支持,如tomcat,jboss等。
除了servlet支持之外,应用服务器还提供许多其他的服务:
- 允许应用程序部署或者停止
- 提供监视应用服务器状态的功能
- 监测代码的变化,并透明的重新编译和加载servlet
- 支持多台服务器在多台机器上并行运行,以提高性能,并将请求分发至适当的机器上
- 有的还支持J2EE平台
9.3.5 服务器端脚本(server-side scripting)
服务器端脚本:可以嵌入到HTML文本中。
服务器在传送Web页面之前,先执行嵌入到HTML页面内容中的脚本(可能会修改页面),再讲脚本的源代码删除,因此客户端察觉不到这些脚本。
常见的服务器端脚本语言:
JSP - Java Server Pages:允许Java嵌入到HTML中。嵌入的部分允许动态的生成HTML。
- JSP脚本实际上转换为servlet代码进行编译,用<%....%>嵌入到HTML中
- JSP也支持标签库(tag library)的概念,允许使用标签,JSP的标准标签集定义了变量和控制流、以及基于JS的表达式语言,都在服务端解释。
PHP - <?...?>嵌入到HTML中。类似于JSP。
9.3.6 客户端脚本
客户端脚本语言(client-side scripting language): 用于客户端的web浏览器上执行的语言。例如:JavaScript语言
JavaScript:
- 可以用于输入验证
- 可以用于动态修改所显示的HTML代码
浏览器将HTML代码解析为内存中的一个树结构,它是由文档对象模型(Document Object Model,DOM)标准定义的。
JS代码可以修改该树结构。
虽然JS代码已经标准化,但是浏览器之间存在差别,特别是DOM模型的一些细节。也因此会存在JS兼容性的问题。
为了避免这种问题,最好使用一个JS库,该库可以独立于浏览器。例如:Yahoo的YUI库。
Ajax技术:可以使得客户端与web服务器异步通信,不阻断用户与浏览器的交互,并能够获得数据的显示。
9.4 应用架构
模型-视图-控制器(Model-view-Controller, MVC)架构:
- 模型:对应于下文的业务-逻辑层
- 视图:定义数据的展示
- 控制器:接受事件(用户操作),在模型上执行操作,并返回一个视图给用户
为了处理大型应用的复杂性,通常将它们分层:
- 展示层/用户界面层: 处理用户交互。单个应用程序可能有若干个不同版本的展示层,对应于不同类型的界面,例如:web浏览器以及手机用户界面
- 业务逻辑层:提供对数据和数据操作的高级视图
- 提供实体的抽象,以及对其的操作以保证业务规则(business rule)
- 业务逻辑包含工作流(workflow)
- 数据访问层:提供业务逻辑层和底层数据库间的接口。
- 如果底层数据库是关系数据库,可以使用面向对象语言编写业务逻辑层,并使用面向对象数据模型。这种情况下,数据访问层还提供从业务逻辑所用的面向对象数据模型到数据库所支持的关系模型的映射。
下图展示了处理web浏览器一条请求所采取的一系列步骤。
1. 应用服务器接收请求 -> 2. 控制器向模型发送请求 -> 3. 模型使用业务逻辑处理请求 -> 4. 模型处理请求时可能需要通过数据访问层和DB进行交互-> 5. 模型将结果返回给控制器 -> 6. 控制器调用视图对模型返回的结果生成HTML视图-> 7. 视图将生成的结果返回给控制器 -> 8. 控制器将视图返回给浏览器进行展示
9.4.1 业务逻辑层-略
9.4.2 数据访问层和对象-关系映射
业务逻辑层和数据库使用相同的数据模型,而数据访问层只是隐藏了由于数据库连接的抽象。
面向对象数据库(object-oriented database):存储对象和对象之间关系的数据库。
关系型数据库:
- 对象-关系映射(object-relational mapping): 将数据库的数据映射到内存中存储的对象,以及反向映射,从而将更新后的对象以关系的形式保存回数据库。
- Hibernate可以将Java对象映射到关系。
- 将Java类映射到数据库中的一个关系
- properties文件可以记录数据库的信息,如:地址、用户名和密码
- 支持将联系映射为关联对象集合的能力
- Microsoft业开发了一种数据模型,叫做实体数据模型(Entity Data Model)以及一个相关框架ADO.NET。
- 它能在实体数据模型和关系数据库间映射数据
9.4.3 Web服务
web服务(web service)的两种实现方法:
- 代表性状态传输(REpresentation State Transfer, REST): 通过在应用服务器对URL的标准HTTP请求执行web服务函数调用。应用程序执行该请求并返回结果。可接受和返回JSON或XML格式的对象。
- 有许多Rest风格的web服务器应用
- 大Web服务(更复杂):它对参数和结果使用XML编码,使用一种专门的语言正规定义Web API,并在HTTP协议上构建了一个协议层。
9.4.4 断连操作
应用支持当一个客户端从应用服务器段开时仍支持某些操作。例如:保存用户输入到一半的申请表。
这类应用需要在客户端机器中本地存储,最好是以数据库的形式。
Gears软件是一个浏览器插件,它提供一个数据库、一个本地web服务器,并支持在客户端并行执行JS。支持跨平台/浏览器操作。
Adobe的AIR软件也可以提供类似的功能。
9.5 快速应用开发
为了减少编写用户界面的工作量,有以下几种方法:
- 提供一个函数库,以最小的编程量生成用户界面元素
- 在IDE中提供拖放功能,允许将用户界面元素拖拽到页面的设计视图。
- 根据声明规范自动生成用户界面的代码
这些作为快速应用开发工具(Rapid Application Development,RAD)的一部分用于创建用户界面。
9.5.1 构建用户界面的工具
菜单可以通过数据库的数据生成。
输入的验证控件。
显示查询的结果集。
分页展示大的结果集。
JSF框架可以支持上述所有功能。
Microsoft的ASP以及ASP.NEt是JSP/JAVA的一种替代品。
9.5.2 Web应用架构
9.5.3 报表生成器
报表生成器是从数据库生成人们可读的概要报告的工具。它将生成格式化文本和概要图表由于查询数据库结合在一起。
需多厂商都提供报表生成工具:Crystal Report和Microsoft(SQL server reporting services)。
报表可以定制、重新执行和更新、以及生成交互式报表。
9.6 应用程序性能
应用程序开发人员可以利用缓存加快处理单个请求的速度,并通过使用多个应用服务器进行并行处理。
9.6.1 利用缓存减少开销
多种缓存技术可以充分利用事务之间的共性:
- 连接池(connection pooling):
- 解决痛点:创建一个新的JDBC或ODBC连接耗时很长,为每个请求创建一个新的连接不合适。
- 工作原理:
- 连接池管理器(应用服务器的一部分)创建一个打开的ODBC/JDBC连接的池并对其进行管理。
- 当一个新的请求过来,并向连接池申请一个连接,用完之后再将连接归还。
- 如果申请连接时,连接池内无空闲连接,那么打开一个新的连接(此时要注意不要超过数据库能支持的最大连接数)
- 如果打开的连接长时间未用,连接池管理器可以关闭一些打开的数据库连接。
- 许多应用服务器以及较新的ODBC/JDBC驱动程序提供内置的连接池管理器。
- 注意:程序员一定要记得关闭一个打开的JDBC连接(或者将其归还给连接池)。因为数据库可支持的连接数目有限,并且程序不会自动关闭或者归还JDBC连接,这样很容易导致超过数据库能够支持的连接上限。
- 通过缓存响应一个请求所发送的最终web页面/查询结果可以进一步减少开销
- 只要数据库的查询结果不变,就可以缓存之前的结果并重用他们。减少数据库通信的开销。
- 缓存的查询结果和缓存的web页面是物化视图的形式
- 如果底层数据库改动,缓存就需要被重新计算或增量更新
- 例如Microsoft SQL Server会为应用服务器提供一种注册查询,并在查询结果发生改变时从数据库得到通知(notification),以确保查询结果是最新的。
- 如果底层数据库改动,缓存就需要被重新计算或增量更新
9.6.2 并行处理
并行运行多个台服务器可以处理非常重的负载。
一个请求可以被web服务器/网络路由器路由到其中的一台应用服务器。来自特定客户端会话的请求必须送到同一台应用服务器进行处理,因为要维持客户端会话的状态。底层数据库被多台应用服务器共享。
- 瓶颈:数据库共享==> 可以尽可能缓存结果,减少数据库请求;使用并行数据库系统
9.7 用于程序安全性
本节介绍几种安全漏洞,安全认证和细粒度授权技术,以及审计追踪(帮助从未经授权的访问和错误更新中恢复)
9.7.1 SQL注入
SQL注入(injection):攻击者设法获取一个应用程序来执行攻击者生成的SQL查询。
解决方案:采用预备语句执行SQL,使得程序会自动转义特殊字符,
例如:
// SQL注入方式1:采用字符串拼接生成SQL ==> 可以使用预备语句执行SQL
String query = "select * from student where name like '%'"+name+"'%'";
// 若name = ";<some SQL statement>;--"
// 会导致第一个查询结束后,执行嵌入的第二个sql,而后面的百分号会被注释掉==》产生安全问题
// SQL注入方式2:==> 可以在拼接之前验证orderAttribute是否属于takes的属性
String query = "select * from takes order by" +orderAttribute';
9.7.2 跨站点脚本和请求伪造
跨站点脚本(Cross-Site scripting,XSS)攻击:
例如:一个网站允许用户输入评论或姓名的文本,将其保存后可以显示给其他用户看。
一个恶意用户并不输入一个有效的文本输入,而是输入如JS或Flash的客户端脚本语言编写的代码。
当另一个用户阅读输入的文本时,浏览器将会执行脚本,它可能会进行一些操作,如:将私人cookie发送给恶意用户。
若恰巧该脚本执行的时候用户登录了银行账户,该脚本可能将有关银行登录的账户信息的cookie发给恶意用户。
恶意用户使用这个cookie,可以连接到银行的web服务器,欺骗它相信连接的仍是原用户。
跨站点请求伪造(Cross-site Request Forgery,XSRF或CSRF):
事实上,上述例子中该脚本也可以被设计为设置适当参数并访问银行网站的适当网页执行转账。
假定URL接受了指定的参数,并进行转账,这种漏洞就是CSRF。
例如:
<img src="http://mybank.com/transfermoney?amount=1000&toaccount=14325"/>
预防措施:
- 防止你的网站被用来发动XSS或XSRF攻击
- 禁止用户输入的任何文本中的任何HTML标签。存在检查或去除这些标签的函数
- 缺点:要小心处理,否则可能会导致显示错误
- 防止你的站点被其他站点发动的XSS或XSRF攻击
- 为了避免用户已经登录你的网站,并访问了一个易受XSS攻击的网站,在该用户的浏览器上执行恶意代码来对你的站点进行操作。可以尝试一下几个步骤减少风险
- HTTP协议允许一个服务器检查访问页的引用页(referrer),即:用户为了初始化访问页而点击的链接所在的网页的URL。通过检查引用页是否有效,如:引用页URL是否是同一个网站的网页,源自用户访问的不同网页上的XSS共计可以防止。
- 除了使用cookie,还可以将会话限制在原始验证它的IP地址上。这样恶意用户得到cookie,也不可以从另一台计算机登录
- 坚决不用GET方法执行任何更新,这防止了<image src...>类的共计。
- 为了避免用户已经登录你的网站,并访问了一个易受XSS攻击的网站,在该用户的浏览器上执行恶意代码来对你的站点进行操作。可以尝试一下几个步骤减少风险
9.7.3 密码泄露
问题:不要在应用程序代码中明文保存密码。
解决方案:许多应用服务器提供用编码的方式保存密码的机制,在传送给数据库之前服务器对其解码。去除了在应用程序中将密码另存为明文的需要。当然,要保证密钥的安全。
数据库服务器应该限制能够访问它的请求的IP地址,为其添加白名单。从除了应用服务器端之外的其他网络地址企图连接数据库会被拒绝。
这样,除非非法用户登录了应用服务器,否则即使他们获得了数据库的账户和密码,数据库服务器也不会允许建立连接。
9.7.4 应用程序认证
认证:指验证连接到应用程序的人或者软件的身份。
认证的形式:
- 最简单的形式是由密码组成。
- 缺点:密码容易泄露
- 双因素认证(two-factor authentication):采用两个独立的因素(即信息或程序的片段)来识别用户。这两个因素不应该具有相同的弱点,例如:采用两个密码的方式,两个密码可能以相同的方式泄露出去。
- 第一个因素:密码
- 常用的第二个因素:
- 通过USB接口连接的智能卡或其他加密设备,可基于加密技术进行认证。一次性密码设备,每分钟生成一个新的随机数。
- 给用户一个设备,为了验证,用户需要输入设备生成的数字和密码
- 每个设备生成不同的伪随机数序列。
- 应用服务器能够生成与用户设备相同的伪随机数序列,在认证时在将显示的数字处停下来,并验证是否匹配。
- 该方案要求设备中与服务器端的时钟始终是合理紧密的同步。
- 当用户想登陆时,给用户的注册手机发送一条包含一次性密码的短信。
- 通过USB接口连接的智能卡或其他加密设备,可基于加密技术进行认证。一次性密码设备,每分钟生成一个新的随机数。
- 缺点:仍然会受到中间人(man-in-the-middle)攻击。
-
- 这种攻击中,一个试图连接应用的用户被转向一个虚假网站,它接受用户的密码,包括第二因素密码,并立即你用该密码到原始应用中认证。
-
当用户访问多个网站时,需要分别在每个网站上做认证而感到不快。所以系统可以允许用户向一个中央认证服务进行认证,并且其它网站和应用也可以通过中央认证服务器进行认证,于是相同的密码可以用于访问多个站点。
- LDAP协议:广泛的用于这种中央认证点;一些机构实现了包含用户名和密码信息的LDAP服务器,并且应用程序使用LDAP服务器对用户进行认证。
单点登录(single sign-on):系统允许用户只验证一次,且通过一个认证服务对用户的身份进行验证的多个应用都不需要再次认证。
- 安全断言标记语言(Security Assertion Markup Language, SAML):是一个在不同安全域间交换认证和授权信息的标准,已提供跨机构单点登录。例如:一个应用需要提供对一所特定学校(如耶鲁)的所有学生的访问权限,该学校可以建立一个基于web的服务实施认证。假设一个连接到该应用的用户具有用户名joe@yale.edu。则该应用将该用户转向耶鲁大学的认证服务对其认证,而不直接对其认真,并告诉该用户是谁且可能提供一些额外的信息。该用户的密码以及其他认证因素不会显示给应用,并且用户也不需要应用程序显示的注册。不过当认证用户时,应用程序必须信任学习的认证服务。
- OpenID标注:是另一种跨机构单点登录的标准。许多流行的站点,如google是OpenID认证提供方。任何作为OpenID客户端的应用程序可以使用这些提供方中的任意一个来认证用户。
9.7.5 应用级授权
SQL授权模型的不足:
SQL授权模型对用户授权的管理是非常有限的。例如:限制所有学生只能看到自己的成绩。
这样的授权无法再SQL中表示,因为:
- 缺乏最终用户信息。
- 数据库范根主要来自web应用服务器,最终影虎在数据库本身上通常没有个人用户标识
- 缺乏细粒度的授权
- 授权在单挑元组的级别在目前的SQL标准中是不可能的。SQL标准只允许在整个视图、关系或指定属性授权。
- 方法1:理论上可以通过建立该学生成绩的视图,绕过限制,但是实现起来非常繁琐和不切实际。
- 方法2:令create view studentTakes as select * from takes where takes.ID = syscontext.user_id()、但是这种方法只适用于学生,老师需要不同的视图。开发和维护更复杂。
应用程序级别的授权:
目前,授权的任务全部由应用程序执行,绕过SQL限制。
在应用级别,授权用户访问特定接口,并可能进一步被限制只能查看或更新的某些数据项。
虽然很灵活,但是也有缺点:
- 授权代码和应用程序的其它代码混合在一起
- 可能会存在漏洞,因为应用程序具有一个非常大的”表面积“,保护起来很艰难;而SQL级别的授权表面积会很小。
Oracle提供了细粒度的授权机制,例如oracle的虚拟私有数据库(Virtual Private Database, VPD)。
它允许系统管理员将一个函数关联一个关系,该函数返回一个谓词,该谓词必须加入到任何一个使用该关系的查询中。例如:谓词ID = sys_context.user_id()需要加到takes的查询的where子句中。
===> 进而提供了行级授权(row-leve authorization)
缺点:输出可能并不是我们想要的结果。如果查询的目的是查找班级成绩的平均值,那么该用户最后得到的职能制自己的平均成绩。
9.7.6 审计追踪
审计追踪(audit trail)是关于应用程序数据的所有更改的日志,以及一些信息,如:那个用户执行了更改和什么时候执行的更改。其作用包括:
- 可以在程序安全性被破坏或者发生错误更新时,(a)帮助确定发生的动作以及操作执行人,并且(b)帮助修复安全漏斗或错误更新所带来的损失。
- 用于探查安全漏洞
数据库内置的审计追踪通常对于应用程序来说是不够的,因为它们无法追踪应用程序的最终用户。它只能追踪低级别记录的更新(即关系中的元组),而无法在较高级别(如业务逻辑级别)进行追踪。
===>因此,应用程序也要创建一个较高级别的审计追踪器。
9.7.7 隐私
数据隐私非常重要!已经有法律来保护隐私数据。
聚集的隐私数据的价值很重要。例如:检查药物副作用。
web站点如何保护收集到的个人信息 - 很重要!
9.8 加密及其应用
数据库方面,加密可以可用来以一种安全的方式存储数据,从而即使数据被一个未经授权的用户获取,如果没有揭秘秘钥的话数据也无法被访问。
许多数据库都会对客户敏感信息进行加密。许多法律也要求数据库必须对敏感信息进行加密存储。
9.8.1 加密技术
一个好的加密技术具有的特性:
- 对于授权用户,加密数据和解密数据相对简单
- 加密模式不应依赖于算法的保密,而应该依赖于被称作加密密钥的算法参数,该密钥用于加密数据。
- 在对称密钥(symmetric-key)加密技术中,加密密钥也用于解密数据。
- 在公钥加密(public-key)(也称作非对称密钥(asymmetric key)加密技术)中,存在公钥和私钥,分别用于加解密数据。
- 对入侵者来说,即使他已经获得加密数据的访问权限,确定解密密钥仍是机器困难的。在非对称密钥加密的情况中,即使有公钥,推断出私钥也是极其困难的、
扩展机密标准(Advanced Encryption Standard,AES)是一种对称密钥加密算法
- 该标准基于Rijindael算法-每次对一个128位的数据库操作,密钥的长度可能是128.192或256位
对称加密算法的缺点:
- 对于任意对称密钥加密模式的使用,授权用户通过一个安全机制得到加密密钥。这是其一打弱点,因为模式的安全不高于加密密钥传输机制的安全。
公钥加密算法:存在一个public key和一个private key,公钥是公开的,私钥是只由拥有它的用户知道。使用公钥进行加密,私钥进行解密。
9.8.2 数据库的加密支持
数据库加密的不同级别:
- 较低级别:对存储数据库数据的磁盘块进行加密
- 可以抵御能访问磁盘内容但不能访问密钥的攻击者
- 当从磁盘上获取一个磁盘块时,先解密再以平常的方式使用
- 较高级别:对指定属性进行加密。
- 不同的属性可以使用不同的密钥。
- 数据库通常不允许加密主码、外码、属性上的索引的加密。
- 此外,还要使用额外的随机数防止字典攻击
为了访问数据,还需要解密密钥。
-
- 单个主加密密钥可以用于所有的加密数据
- 不同属性的解密密钥存在一个文件或关系中(称为钱夹),它本身也用主密钥加密。
一个需要访问加密属性的数据库的连接必须提供主密钥,除非提供了主密钥,否则该连接将无法访问加密数据。主密钥保存在应用程序中,或者由数据库用户记住,并在用户连接到数据库时提供。
数据库级别加密的优点:时空开销相对较小,对应用程序的修改较小。
应用级别的加密:
数据发送到数据库之前由应用程序加密,数据取回时应用程序对其解密。
缺点:应用程序的代码需要做大量修改。
9.8.3 加密和认证
基于密码的认证容易被窃听。
一个较为安全的机制包括询问-回答(challengE-Response)系统。
其过程为:
- 数据库发送一个询问字符串给用户 --- 该字符串经过公钥加密
- 用户用一个密码作为加密密钥对询问字符串进行加密,然后返回结果
- 数据库系统用同样的密码把字符串解密,并检查解密结果是否与发送的询问字符串一致 来验证用户的身份。
优点:确保没有密码在网络上传输
公钥系统也可以用于询问-回答(challengE-Response)系统。
其过程为:
- 数据库系统使用用户的公钥加密询问字符串,并把其发给用户
- 用户用他的私钥对字符串解密,并把结果返回给数据库系统
- 数据库系统验证该结果是否与发送的询问字符串一致,来进行验证
优势:不在可能被系统管理员看到的数据库中存储密码
用户的私钥存储在计算机上是有风险的,如果该计算机收到攻击,私钥可能会暴露。
==>智能卡(smart card):解决这一问题。密码可以存储在一块嵌入的芯片中;智能卡的OS保证该密码绝不会被读取,但是允许数据被发送到卡上进行加密或者解密。
9.8.3.1 数字签名
公钥机密的另一个应用 —— 数字签名(digital signature):用来验证数据的真实性。
私钥对数据”签名“(加密),且签名后的数据可以公开。
所有人都可以用公钥对签名进行解密,来验证签名。===>认证(authenticate)该数据是由声称创建该数据的人创建;
9.8.3.2 数字证书
通常认证是一个双向的过程,交互实体要互相向对方认证自己的身份。防止恶意站点冒充合法站点。==> 数字证书(digital certificate)。
用户与Web站点A交互,需要获取到A的公钥;站点B可以伪装成站点A,提供B的公钥。那么如何判断A公钥和B公钥哪个是真实的呢?
==> 引入 数字证书(digital certificate):
- 公钥由一个公开的认证机构签名。例如:根认证机构的公钥保存在标准的web浏览器中,它们签署的证书可以使用保存的公钥来验证。
- 两级系统 会给跟认证机构带来创建证书这一巨大负担 ==> 采用多级系统取而代之。
- 采用多个根认证机构,每个根认证机构下有一颗认证机构树。每个机构(除根机构)都有其父机构签署的一个数字证书。
认证机构A签署的证书包括:
- 公钥KA
- 一个可以用公钥KA解密的加密文本E
- 证书签发给的机构及它的公钥KC
- 若A不是根验证机构,还包括其父认证机构签发给A的数字证书,这个证书认证了密钥KA本身
验证一个证书?
- 加密文本E通过KA解密,从而获得团体名称;
- 如果A不是根验证机构,其公钥KA会递归的使用E中包含的数字证书进行验证,直至抵达根机构签发的证书
HTTPS中应用数字证书:
- 站点向浏览器提供它的证书,浏览器将证书显示给用户,如果用户接受该证书,浏览器则使用提供的公钥进行加密。
- 恶意站点可以对数据进行加密,但是无法解密;只有拥有相应私钥的站点才能解密浏览器发送的数据。
- 由于公钥/私钥加密算法代价远高于对称加密,为了减少呆极爱,HTTPS实际是在认证之后创建一个一次性的对称密钥,在随后的会话中采用这个密钥对数据加密。
总结
- 目前,大多数应用程序都使用Web浏览器作为它们的前端,数据库作为后端,以及一个应用服务器介于中间
- HTML提供了定义超链接和表单功能结合的界面的能力。Web浏览器通过HTTP协议和web服务器通信、web服务器可以将请求传递给应用程序,并将结果返回浏览器。
- web服务器执行应用程序以实现所需的功能。servlet是一个使用广泛的机制;另外还有服务器端脚本语言。
- 客户端脚本语言 - JS使用最为广泛——在浏览器端提供更丰富的用户交互
- 复杂的应用程序通常具有多层架构:
- 实现业务逻辑的模型、控制器以及用户显示结果的查看机制
- 它们还包括一个实现了对象-关系映射的数据访问层
- 目前已经有很多工具用于快速应用开发,特别是减少构建用户界面所需的工作
- 多种形式的缓存(连接池和查询结果缓存)+并行处理技术 ==> 用来提高应用程序性能
- 应用程序要注意安全性问题,以防止受到攻击:SQL注入攻击、跨站点脚本攻击等
- SQL授权机制是粗粒度的,对处理大量用户的应用具有有限的价值。目前,应用程序在数据库系统之外实现了细粒度的、元组级别的授权,以处理大量应用程序用户。提供元组级别的空值和处理大量应用程序用户的数据库已经开发出,但是还没有成为标准
- 保护数据的隐私 - 非常重要。有法律保护隐私数据
- 加密:在保护信息以及认证用户和web站点中版一样了关键角色。对称秘钥加密和公钥加密是两种相对但广泛应用的加密方法。许多法律规定对敏感数据加密是必须的。
- 加密还在为应用程序认证用户,为用户认证web站点以及数字签名中扮演了关键角色、