Java安全性本教程是关于什么方面的?第1页(共5页)恐怕没有什么软件工程主题的重要性比应用程序安全性更紧迫了。无论是来自内部或外部的攻击都会带来巨大损失,某些攻击会使软件公司对造成的损失承担赔偿责任。随着计算机(尤其是因特网)技术的发展,安全性攻击正在变得越来越成熟和频繁。利用各种最新技术和工具是应用程序安全性的一个关键;另一个关键是由经过考验的技术(如数据加密、认证和授权)构筑的牢固的基础。Java平台的基本语言和库扩展都提供了用于编写安全应用程序的极佳基础。本教程讨论了密码术基础知识与如何用Java编程语言实现密码术,并提供了样本代码来说明这些概念。在这个两部分教程的第一部分中,我们讨论库扩展(现在是JDK1.4库的一部分)中的内容,这些库扩展被称为Java密码术扩展(JavaCryptographyExtension(JCE))和Java安全套接字扩展(JavaSecureSocketsExtension(JSSE))。此外,本教程还介绍了CertPathAPI,这是JDK1.4中新增加的特性。在本教程第二部分(请参阅参考资料)中,我们将把讨论范围扩大到由Java平台中Java认证和授权服务(JavaAuthenticationandAuthorizationService(JAAS))管理的访问控制。我应该学习本教程吗?第2页(共5页)这是一篇中级教程;它假设您知道如何阅读和编写基本的Java程序,包括应用程序和applet。如果您已经是Java程序员并且对密码术(关于诸如私钥和公钥加密、RSA、SSL、证书之类的主题)以及支持它们的Java库(JCE、JSSE)感到好奇,那么本教程就是为您准备的。本教程不要求您已经具有任何密码术、JCE或JSSE等方面的知识背景。本教程介绍了基本密码构件概念。每个概念都附有Java实现考虑事项、代码示例和示例执行的结果。工具、代码样本和安装需求第3页(共5页)您将需要以下几项以完成本教程中的编程练习:JDK1.4,标准版本教程源代码和类,以便您能够随着我们的进度理解示例用于RSA示例的BouncyCastleCrypto库支持Java1.4插件的浏览器您可以使用JDK1.3.x,但必须自行安装JCE和JSSE。关于代码示例的说明第4页(共5页)代码示例直接将已加密的数据显示到屏幕上。大多数情况下,这会产生奇形怪状的控制字符,其中的一些偶尔可能会引起屏幕格式化问题。这不是良好的编程实践(将它们转换成可显示的ASCII字符或十进制表示会更好),但我们这样做是为了保持代码示例及其输出的简洁。在示例执行章节的大多数情况下,我们修改了实际字符串以便与本教程中的字符集需求兼容。还有,我们在大多数示例中查询和显示了用于给定算法的实际安全性提供程序库。这样做是为了让用户更好地了解哪个功能是调用哪个库实现的。为什么这样做呢?因为,在大多数安装中都安装了许多这样的提供程序。关于作者第5页(共5页)BradRubin是BradRubin&AssociatesInc.的负责人,该公司是一家专门从事无线网络和Java应用程序安全性和教育的计算机安全性咨询公司。Brad在IBM(位于明尼苏达州的Rochester)工作了14年,他从AS/400的第一个发行版就开始从事其所有方面的硬件和软件开发。他是促使IBM转而支持Java平台的关键人物,并且是IBM最大的Java应用程序―称为SanFrancisco(现在是WebSphere的一部分)的商业应用程序框架产品―的首席架构设计师。他还是ImationCorp.数据存储部门的首席技术官,以及该公司研发组织的领导。Brad拥有计算机和电子工程学位,以及威斯康星大学麦迪逊分校计算机科学博士头衔。他目前在明尼苏达大学教授电子和计算机工程高级设计课程,并将于2002年秋季开设和教授该大学的计算机安全性课程。可通过BradRubin@BradRubin.com与Brad联系。Java安全性编程概念Java平台是如何使安全编程更方便的第1页(共5页)Java编程语言和环境有许多特性使安全编程更方便:无指针,这意味着Java程序不能对地址空间中的任意内存位置寻址。字节码验证器,在编译成.class文件之后运行,在执行之前检查安全性问题。例如,访问超出数组大小的数组元素的尝试将被拒绝。因为缓冲区溢出攻击是造成大多数系统漏洞的主要原因,所以这是一种重要的安全性特性。对资源访问的细颗粒度控制,用于applet和应用程序。例如,可以限制applet对磁盘空间的读或写,或者可以授权它仅从特定目录读数据。可以根据对代码签名的人(请参阅代码签名的概念)以及代码来源处的http地址来进行授权。这些设置都出现在java.policy文件中。大量库函数,这些函数用于主要密码构件和SSL(本教程的主题)以及认证和授权(在本系列的第二篇教程中讨论)。此外,有众多的第三方库可用于额外的算法。什么是安全编程技术?第2页(共5页)简单地说,有多种编程风格和技术可以帮助确保应用程序更安全。考虑下列两个一般示例:存储/删除密码。如果密码是存储在JavaString对象中的,则直到对它进行垃圾收集或进程终止之前,密码会一直驻留在内存中。即使进行了垃圾收集,它仍会存在于空闲内存堆中,直到重用该内存空间为止。密码String在内存中驻留得越久,遭到窃听的危险性就越大。更糟的是,如果实际内存减少,则操作系统会将这个密码String换页调度到磁盘的交换空间,因此容易遭受磁盘块窃听攻击。为了将这种泄密的可能性降至最低(但不是消除),您应该将密码存储在char数组中,并在使用后对其置零。(String是不可变的,所以无法对其置零。)智能序列化。当为存储器或传输任何私有字段而序列化对象时,缺省情况下,这些对象都呈现在流中。因此,敏感数据很容易被窃听。可以使用transient关键字来标记属性,这样在流中将忽略该属性。当在本教程中需要用到这些技术以及其它技术时,我们将更详细地讨论它们。JDK1.4中集成了安全性第3页(共5页)在JDK1.4之前,许多安全性功能必须作为扩展添加到基本Java代码分发版中。严格的美国出口限制要求这种功能的分离。现在,新的宽松法规使安全性特性和基本语言更紧密的集成成为可能。下列软件包(在1.4发行版之前作为扩展使用)现在集成到了JDK1.4中:JCE(Java密码术扩展)JSSE(Java安全套接字扩展)JAAS(Java认证和授权服务)JDK1.4还引入了两种新功能:JGSS(Java通用安全性服务(JavaGeneralSecurityService))CertPathAPI(Java证书路径API(JavaCertificationPathAPI))JCE、JSSE和CertPathAPI是本教程讨论的主题。在本系列的下一篇教程中,我们将重点介绍JAAS。这两篇教程都不讨论JGSS(它提供一般框架以在两个应用程序之间安全地交换消息)。第三方库充实了安全性第4页(共5页)我们可以用第三方库(也称为提供程序)来增强当前Java语言中已经很丰富的功能集。提供程序添加了额外的安全性算法。作为库示例,我们将使用BouncyCastle提供程序(请参阅参考资料)。BouncyCastle库提供了其它密码算法,包括本教程什么是公钥密码术?和什么是数字签名?中讨论的流行的RSA算法。尽管您的目录名和java.security文件可能有一点不同,但仍可用以下模板安装BouncyCastle提供程序。要安装这个库,请下载bcprov-jdk14-112.jar文件并将它放到j2sdk1.4.0\jre\lib\ext和ProgramFiles\Java\J2re1.4.0\lib\ext目录中。在两个java.security文件(他们位于上述相同的目录下,但位于“security”子目录而不是“ext”)中,将下面的行:security.provider.6=org.bouncycastle.jce.provider.BouncyCastleProvider添加至这些行的末尾:security.provider.1=sun.security.provider.Sunsecurity.provider.2=com.sun.net.ssl.internal.ssl.Providersecurity.provider.3=com.sun.rsajca.Providersecurity.provider.4=com.sun.crypto.provider.SunJCEsecurity.provider.5=sun.security.jgss.SunProvidersecurity.provider.6=org.bouncycastle.jce.provider.BouncyCastleProvider展望第5页(共5页)在本章中,我们已经介绍了Java语言提供的有助于确保编程保持安全的特性(无论是完全集成的还是基于扩展的)。我们提供了一些安全编程技术的通用示例以帮助您熟悉这个概念。我们介绍了过去是作为扩展的但现在集成到版本1.4发行版中的安全性技术;我们也注意到两种新的安全性技术。我们还说明了了第三方库通过提供新技术能够增强安全性程序。在本教程余下的部分,我们将让您熟悉这些旨在提供安全的消息传递的概念(因为它们应用于Java编程):消息摘要。这是一种与消息认证码结合使用以确保消息完整性的技术。私钥加密。被设计用来确保消息机密性的技术。公钥加密。允许通信双方不必事先协商秘钥即可共享秘密消息的技术。数字签名。证明另一方的消息确定来自正确通信方的位模式。数字证书。通过让第三方认证机构认证消息,向数字签名添加另一级别安全性的技术。代码签名。由可信的实体将签名嵌入被传递的代码中的概念。SSL/TLS。在客户机和服务器之间建立安全通信通道的协议。传输层安全性(TransportLayerSecurity(TLS))是安全套接字层(SecureSocketsLayer(SSL))的替代品。当我们讨论上述每个主题时,都将提供示例和样本代码。确保消息的完整性概述第1页(共7页)我们将在本章中了解消息摘要,它获取消息中的数据并生成一个被设计用来表示该消息“指纹”的位块。我们还将讨论JDK1.4支持的与消息摘要相关的算法、类和方法,并为消息摘要和消息认证特性提供代码示例和样本的执行代码。什么是消息摘要?第2页(共7页)消息摘要是一种确保消息完整性的功能。消息摘要获取消息作为输入并生成位块(通常是几百位长),该位块表示消息的指纹。消息中很小的更改(比如说,由闯入者和窃听者造成的更改)将引起指纹发生显著更改。消息摘要函数是单向函数。从消息生成指纹是很简单的事情,但生成与给定指纹匹配的消息却很难。消息摘要可强可弱。校验和(消息的所有字节异或运算的结果)是弱消息摘要函数的一个示例。很容易修改一个字节以生成任何期望的校验和指纹。大多数强函数使用散列法。消息中1位更改将引起指纹中巨大的更改(理想的比例是更改指纹中50%的位)。算法、类和方法第3页(共7页)JDK1.4支持下列消息摘要算法:MD2和MD5,它们都是128位算法SHA-1是160位算法SHA-256、SHA-383和SHA-512提供更长的指纹,大小分别是256位、383位和512位MD5和SHA-1是最常用的算法。MessageDigest类操作消息摘要。消息摘要代码示例中使用下列方法:MessageDigest.getInstance(MD5):创建消息摘要。.update(plaintext):用明文字符串计算消息摘要。.digest():读取消息摘要。如果密钥被用作消息摘要生成过程的一部分,则将该算法称为消息认证码。JDK1.4支持HMAC/SHA-1和HMAC/MD5消息认证码算法。Mac类使用由KeyGenerator类产生的密钥操作消息认证码。消息认证码示例中使用了下列方法:KeyGenerator.