MyException - 我的异常网
当前位置:我的异常网» 编程 » Java Security 大纲

Java Security 大纲

www.MyException.Cn  网友分享于:2015-08-26  浏览:9次
Java Security 总纲

导读:

  • 这是一篇介绍Java Security能做什么的文章。很遗憾,它不会告诉你怎么去做。
  • 本文相关的JDK版本是JDK7,当然,仍适用于JDK6。

 

Java平台(Java运行时环境,即JVM + Java API) 在多个层面上提供了security机制。

 

Java Language Security and Bytecode Verification

Java语言层面和字节码验证层面的安全机制

 

从语言层面来说,Java是类型安全的。它提供了自动的内存管理和GC机制,这些语言特性增强了代码的鲁棒性,减少了安全隐患。

 

类加载和校验机制确保了只有合法的Java代码才会被执行。

 

JVM 写道
类加载器是JVM在安全性和网络移动性上发挥重要作用的一个方面。被加载的类只能看到自身类加载器装载的其他类,而无法访问其他类加载器装载的类(除非应用程序显式地允许这么做)。从不同源文件中装载的类可以分隔在不同的命名空间内。通过这种方法,能够使类加载器机制控制任何从不同源文件中装载的代码之间的互相影响,特别是能够阻止恶意代码获取访问和破坏善意代码的权限。

  

此外,Java语言提供了4种不同的访问权限:private, public, protected, package。这些访问权限可以指派给类,方法和属性,使得程序员可以限制对这些类型的访问。

 

众所周知,Java编译器会把Java代码编译成字节码。字节码校验器会在字节码执行之前检查它是否符合Java的规则:语言规则、命名空间 、内存管理、栈溢出、类型转换等...在代码执行之前屏蔽一些隐患。

JVM 写道
校验器用于保证装载的class文件内容有正确的内部结构,并且这些class文件互相间协调一致。JVM并不知道某个特定的Class文件是如何创建的。因为class文件实质上只是一个字节序列。JVM无法分辨class文件是由编译器生成的,还是黑客特制的...而校验器可以确保这些定义的类型可以安全地使用。一般来说校验器会进行4次独立的扫描来完成它的工作。第一次在类被装载时,检查的是class文件的内部结构(保证可以被安全地编译)。第二次和第三次在连接的过程中执行,检查类型数据是否遵从Java(本文单独使用Java这个词,代表Java编程语言,下文不再赘述)的语义。第四次在进行动态连接时解析符号引用时进行,确认被引用的类、属性以及方法确实存在。

  

以上罗列的是Java core 和JVM提供的一些security相关机制。不得不提的是,除此之外,Java还提供了一整套功能强大的Security API。这套API覆盖了密码相关的功能、PKI (public key infrastructure)、认证(authentication)、安全通信(secure conmmunication)、访问控制(access control)等方方面面。接下来我们将重点介绍这部分的内容。

 

 

Basic Security Architecture

Security 基础架构

 

 Java Security API提供了可互操作的算法和安全服务的实现。服务以provider的形式实现,可以以插件的形式植入应用程序中。程序员可以透明地使用这些服务,如此使得程序员可以集中精力在如何把安全组件集成到自己的应用程序中,而不是去实现这些安全功能。此外,除了Java提供的安全服务外,用户可以编写自定义的security provider,按需扩展Java的security平台。

 

Security Provider

java.security.Provider抽象了Java security provider。它指定了provider的名字,罗列了它实现的安全服务。多个provider可能同时被配置,他们会以优先级排列。当一个安全服务收到请求,这个服务的最高优先级的provider提供服务。

 

应用通过相关的getInstance方法来获得安全服务,比如:调用java.security.MessageDigest的getInstance方法来获得一个message digest 算法(MD5)。[例子源于Java官网]

 

MessageDigest md = MessageDigest.getInstance("MD5");

 

如下图:

diagram showing an application requesting an MD5 algorithem without specifying a provider name 

程序可能通过provider的名字随意地请求一个指定provider的实现:

 

MessageDigest md = 
    MessageDigest.getInstance("MD5", "ProviderC");

 

 如下图:

diagram showing an application requesting an MD5 algorithem from a specific provider

 

 提供一个Oracle Provider的清单(JDK7)。

 

一些相关的文件

某些provider的配置可能需要用户自定义安全属性。你可以在~jre/lib/security目录下找到这些配置文件,当然,有些配置也可以通过API设置。关于这块的说明会在其他文章里提及,本文只是个overview。

 

 

Cryptography Arthitecture (JCA)

密码架构

 

 Java的Cryptography架构是一个提供访问和开发密码功能的框架。它提供了许多cryptographic服务:

 

  • Message digest algorithms 【信息摘要算法, 如:MD5】
  • Digital signature algorithms 【数字签名算法,DSA】
  • Symmetric bulk encryption  【对称块加密, 如:DES】
  • Symmetric stream encryption 【对称流加密, 如:RC4】
  • Asymmetric encryption 【非对称加密, 如:RSA】
  • Password-based encryption (PBE) 【密码加密】
  • Elliptic Curve Cryptography (ECC) 【椭圆曲线加密】
  • Key agreement algorithms 【key协议算法】
  • Key generators 【key生成器】
  • Message Authentication Codes (MACs) 【消息认证码】
  • (Pseudo-)random number generators 【伪随机数生成器】

因为历史原因,Cryptography API位于两个独立的包内: java.security(Signature, MessageDigest)和javax.crypto(Cipher, KeyAgreement)。

 

Java内置的Provider提供了许多通用的密码算法,比如:RSA, DSA, ECDSA等签名算法、DES, AES, ARCFOUR等加密算法、MD5, SHA-1, SHA-256等信息摘要算法、还有Diffie-Hellman和ECDH这样的密钥协商算法。

 

此外,还有一些特殊的provider。

 

比如SunPKCS11, 它允许Java代码无缝地使用PKCS#11的compliant tokens。

 

在Windows平台上,Java还提供了一些native的Provider去连接本地的 Microsoft CryptoAPI。这个provider的名字叫MSCAPI。它允许Java应用无缝地使用Windows平台的cryptographic service。

 

 

Public Key Infrastructure

公钥基础构件

 

PKI是一个术语,主要用于描述一类基于公钥的安全信息交互框架。它允许identity,比如人或者组织,绑定在数字证书上,并且提供一种验证证书的方法。PKI包括了密钥、证书、公钥加密和可信的证书颁发机构(CAs,用于生成和签署证书)。

 

Java平台提供API和provider支持X.509、CRLs、PKIX证书路径的构建和验证。PKI相关的类可以在java.security和java.security.cert包下获取。

 

密钥和证书的仓库

Java提供了长期持久化密钥和证书的功能。它通过key store和certificate store来实现。java.security.KeyStore这个类代表了一个key store,一个安全的,用于存储密码和可信证书的仓库。java.security.cert.CertStore类代表了一个certificate store,用于存储不相关的,不受信的证书。同样它可以存储CRLs。

 

Java平台包含标准的PKCS#11和PKCS#12 key store类型,此外还有一个基于文件的key store类型,叫做JKS(Java Key Store)。Java平台内置了一个名叫cacerts的特殊JKS,它为CA证书提供一个默认的密钥库。

 

SunPKCS11(之前在密码架构小节有提过哦)包含了一个PKCS#11的key store实现。这意味着安全硬件(比如:smartcard)的密钥和证书可以被Java应用所使用。

 

此外,Java平台提供了LDAP的certificate store类型用于访问存放在LDAP中的证书。还有一个certificate type用于访问存放在java.util.Collection中的证书。

 

PKI Tools

Java提供了两个内置的工具帮助用户使用密钥,证书和Key store:keytooljarsigner

 

keytool用于创建和管理key store。它可以

  • 创建公钥私钥对
  • 显示,导入、导出X.509 v1, v2, v3的证书
  • 创建自签名证书
  • 基于证书请求创建证书
  • 导入证书回复(certificate reply)【在外部CA颁发证书之后,会受到一个回复,该回复通常是一个PKCS7编码的证书】
  • 指定公钥证书为可信

jarsigner用于给JAR文件签名或者验证已经签名的JAR包。

 

 

Authentication

认证

 

Authentication是确认用户身份的过程。在Java运行时环境的上下文中,指认证执行Java程序用户的过程。在这种情况下,这个过程依赖于在Cryptography小节描述到的一些服务。

 

Java平台提供API,用户可以通过插件式的登录模块为应用提供用户认证功能。应用调用LoginContext类(在javax.security.auth.login包内),它依赖于配置。该配置指定了哪个登录模块(所有登录模块必须实现javax.security.auth.spi.LoginModule接口)为应用提供实际的认证功能。

 

应用只使用标准的LoginContext API, 所以能保持对于底层插件模块的独立性。新的模块可以被无缝地添加到应用中,不需要修改任何的应用代码。如下图:

 

diagram illustrating the independence between applications and login modules

 必须提醒的是,虽说登录模块是插件式的组件,它能够以配置的形式增加到Java平台中,但是他们并没有注册为security provider,所以,他们也不会被Provider的查询模块查到(Security Provider小节的图很能说明问题)。此外,请注意,各登录模块是由各自独立的配置所管理。

 

Java平台提供了一些内置的登录模块,所有模块都可以再com.sun.security.auth.module包下找到:

  • Krb5LoginModule 【Kerberos认证】
  • JndiLoginModule 【使用LDAP/NIS的用户名/密码认证】
  • KeyStoreLoginModule 【基于Key store的认证】

 

当然,认证也可以在建立双方之间的安全通讯通道上的过程中完成。Java平台提供了许多标准通信协议的实现(下文将会介绍)。

 

 

Secure Communication

数据走网络,总会通过一些不需要接收该信息的用户。当数据包含一些私人信息时(比如密码,信用卡号等),我们必须采取措施使这些信息不落入未经授权者之手。我们也需要确保数据在传输过程中不被他人篡改。

 

Cryptography(请见Cryptography小节)是安全通讯的基础。Java平台提供了很多API来支持和实现许多标准的安全通讯协议。

 

SSL/TLS

对于这部分协议的实现包含了数据加密、数据完整性、服务器认证和客户端认证(可选)功能。用户的应用可以使用SSL/TLS来为两端提供安全的数据通路。它支持任何应用协议,比如:HTTP。

 

javax.net.ssl.SSLSocket,这个socket类基于普通的stream socket(java.net.Socket),并封装了SSL/TLS协议功能。此外,你的应用可能需要像New-I/O这样的交替式数据传输功能。javax.net.ssl.SSLEngine类可以帮你生成和解读SSL/TLS数据包。

 

Java平台还提供API支持插件式(基于Provider)的key manager和trust manager。Key Manager封装在javax.net.ssl.KeyManager内,它管理用于认证的密钥。trust manager封装在javax.net.ssl.TrustManager类中,由它来决断哪个用户是受信的,这基于它自身管理的Key store中的证书。

 

Java平台包含了一个内置的实现了SSL/TLS协议的Provider,它支持如下协议:

  • SSLv3
  • TLSv1
  • TLSv1.1
  • TLSv1.2

 SASL

Simple Authentication and Security Layer, SASL定义了认证数据如何被交换,但是它本身并没有指定认证数据的内容。SASL框架可以适用于任何SASL支持的认证机制。目前有很多 标准的SASL机制用于不同的安全级别和部署场景。

 

用户的应用使用Java的SASL API并不需要强制绑定任何特定的SASL机制,应用可以选择使用自己需要的机制。API支持客户端应用和服务端应用。用户可以使用javax.security.sasl.Sasl类创建SaslClient和SaslServer对象。

 

SASL机制的实现可以从provider包下找到。每个provider可能提供一个或多个SASL机制。这些provider已经注册到标准的provider架构中,用户可以很方便地使用它们。下面罗列Java平台提供的SASL provider:

  • DRAM-MD5,DIGEST-MD5,EXTERNAL,GSSAPI,NTLM,PLAIN client machanisms 【协议相关的说明】
  • DRAM-MD5,DIGEST-MD5,GSSAPI,NTLM server machanisms 【协议相关的说明】

 GSS-API and Kerberos

GSS-API, Generic Security Service Application Programming Interface。GSS-API提供应用开发者基于大量底层安全机制的统一安全服务入口。目前,Java的GSS-API需要使用Kerberos v5,而Java已经包含了内置的Kerberos实现。注意,之前介绍的Krb5LoginModule可以结合GSS Kerberos使用。此外,Java平台还有内置的SPNEGO(Simple and Protected GSS API Negotiation Mechanism)的实现。

 

在两个应用使用Java GSS-API安全通信之前,它们必须建立一个共同的安全上下文。上下文封装了共享的状态信息, 比如:密钥。这两个应用都需要创建并使用org.ietf.jgss.GSSContext对象去建立和维护这些共享信息。

 

Java GSS API放在org.ietf.jgss包下。Java平台也定义了基础的Kerberos类,比如KerberosPrinciple,KerberosTicket,KerberosKey和KeyTab。这些类都在javax.security.auth.kerberos包下。

 

Access Control

 

XML Signature

to be continued...

 

 

参考文档:

1. http://docs.oracle.com/javase/7/docs/technotes/guides/security/overview

2. http://docs.oracle.com/javase/7/docs/api/index.html

3. 《Inside the Java Virtual Machine》by Bill Venners 

 

 

 

 

 

文章评论

什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
代码女神横空出世
代码女神横空出世
程序员必看的十大电影
程序员必看的十大电影
那些争议最大的编程观点
那些争议最大的编程观点
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
程序员和编码员之间的区别
程序员和编码员之间的区别
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员都该阅读的书
程序员都该阅读的书
Java程序员必看电影
Java程序员必看电影
鲜为人知的编程真相
鲜为人知的编程真相
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
我的丈夫是个程序员
我的丈夫是个程序员
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
如何成为一名黑客
如何成为一名黑客
10个调试和排错的小建议
10个调试和排错的小建议
编程语言是女人
编程语言是女人
老程序员的下场
老程序员的下场
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
程序员应该关注的一些事儿
程序员应该关注的一些事儿
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
每天工作4小时的程序员
每天工作4小时的程序员
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
我是如何打败拖延症的
我是如何打败拖延症的
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
一个程序员的时间管理
一个程序员的时间管理
中美印日四国程序员比较
中美印日四国程序员比较
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
总结2014中国互联网十大段子
总结2014中国互联网十大段子
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有