<commit_before>---
layout   : post
title    : "【译】Java安全概述"
date     : 2017-07-15 13:53:00
author   : fxleyu
tags:
    - Java
    - 安全
---
Java安全概述
> **注意** - 这篇文章是在Java1.5基础上书写的。

# 一、介绍
Java平台在安全上进行着重的设计。Java本身是类型安全的，它还提供了
自动垃圾收集，用于增强应用代码的稳健性。一个安全的类（class）加载
和认证机制确保仅有合法的Java代码可以被执行。    

最初的Java平台版本创建了一个安全的环境用于执行潜在不可信的代码，
例如在公共网络下载的Java applet。伴随着平台升级以及广泛的部署，
Java安全架构也相应的进化用于支持正在扩展的服务集合。现在，这个架
构包含了一个巨大的集合。集合中包含应用程序接口（APIs），工具；还
包含通用安全算法、机制和协议的实现。这个安全架构提供给开发者一个
综合的安全框架用于开发应用程序，它还提供给用户或管理员一套可以安
全管理应用的工具。    

Java安全APIs横跨广泛的应用区域。加密和公钥基础设施（PKI）的接口
为开发安全应用提供了潜在的基础。执行认证和访问控制的接口使应用程
序可以防范受保护资源的未授权访问。

这些APIs允许多个可操作的算法和其它安全服务的实现。服务使
用`providers`实现。`providers`通过标准接口嵌入到Java平台中。这
些标准接口可以使应用程序容易地获取安全服务，而无需关心他们具体的
实现。这些APIs允许开发者如何整合安全到他们的应用中，而不是如何实
现复杂的安全机制。

Java平台包含了一些供应商（provider），这些供应商实现了安全服务
的基础版。平台也允许安装额外的定制供应商。这可以使开发者在平台上
扩展新的安全机制。

这篇文章是Java平台安全的概述。其内容从语言安全特性到安全APIs、工具以及一些内置的组件。这些组件包含服务、显著的关键包和类。

# 二、Java的语言安全和字节码验证
Java语言被设计为类型安全和容易使用。它提供了自动内存管理、垃圾收集、以及数组的范围检查。这些措施降低了开发者的整体编程负担，从而促使更少的编程错误，更安全、更健壮的代码。

此外，Java语言定义了不同的访问修饰符。这些修饰符可以用来修饰Java
类、方法、以及成员变量。这使开发人员能够限制他们的类实现适当的访
问。具体来说，语言定义了四个不同的访问级别：`private`,
`protected`， `public`，如果未指定，`package`。最开放的访问修
饰符是 `public`，允许任何人访问。最限制性修饰语是`private`，私
有成员(一个方法或者成员变量)不允许类外访问。`protected`修饰符允
许任何子类,或者同一个包内的其它类访问。包级别访问只允许同一包内
的类访问。

编译器将Java程序翻译为一种独立于机器的字节码表示。被调用字节码验证器去确保只有合法的字节码才能在Java运行时中执行。它依照Java语言规范检查字节码，确保没违反Java语言规则或命名空间的限制。验证器也检查内存管理违规，栈下溢或溢出和非法数据类型转换。一旦字节码验证,Java运行时准备执行。

# 三、基础安全架构
Java平台定义了一个APIs集合。该集合包含主要的安全区域，其中又加密、PKI、认证、安全通信和访问控制。这些APIs允许开发者很容易把安全整合到应用代码种。这些APIs依据如下原则设计：
- 1、实现的独立性
> 应用无需实现安全组件。这些应用只需请求Java平台的安全服务即可。Providers实现这些安全服务。他们通过标准接口嵌入到Java平台中。为了安全功能，一个应用也许会依赖多个独立的providers。

- 2、实现的互用性
> 在应用之间，Providers具有互用性。特别地，一个应用不会绑定到一个特定的Provider，一个Provider也不会绑定到一个特定的应用。

- 3、可扩展的算法
> Java平台包含一些内置的Provider。这些Porvider实现了安全服务 基础内容。在今天，这些安全服务被广泛使用。但是，一些应用也许依赖新兴的标准，而不是依据被实现的。Java平台支持为实现这些服务而定制的Provider去安装。

## 3.1 安全Provider
在Java平台中，`java.security.Provider`类封装了安全Provider的概念。它指明Provider的名字，并列出被实现的安全服务。也许许多Provider被同时配置，并按特定偏好顺序被列出。当安全服务被请求，实现服务的高优先级的Provider被选择。


应用依赖相关的`getInstance`方法来获取来自潜在Provider的安全服务。举个例子，信息摘要的创建可以描述为Provider提供的一种类型的服务。（第四章讨论信息摘要和其它密码服务。）一个应用调用`java.security.MessageDigest`类的`getInstance`方法去获取一种特定的信息摘要算法的实现，例如MD5。
```java
MessageDigest md = MessageDigest.getInstance("MD5");
```
程序也许可以通过指定Provider名字来指定选择一种特定Provider的实现。
```java
MessageDigest md = MessageDigest.getInstance("MD5", "ProviderC");
```
图1和图2阐明请求一个MD5信息摘要的实现设置。两幅图均显式了三个实现信息摘要算法的Provider。三个Providr从左到右（1到3）按偏好进行排序。在图1中，应用没有指定Provider名字进行请求一个MD5算法实现。这些Provider按照优先序列继续搜索，第一个实现该算法的Provider，ProviderB，被返回。在图2中，应用请求一个被ProviderC实现的MD5算法实现。这时，虽然有较高优先序列的ProviderB也提供一个MD5实现，但是ProviderC也会被返回。

![Test](http://wx3.sinaimg.cn/large/5f4b7840ly1fhn75e1p6ej212m0lptc2.jpg)

Sun公司实现的Java平台中包含很多预先配置的默认Provider。这些Provider提供了可以被应用使用的安全服务的基础集合。注意，其它Java平台供应商也许会包含不同的，封装特定安全服务集合的Provider集合。本文提及的默认内置的Provider，其均是指Sun公司实现的。

以下章节里包含在不同安全区域（加密、认证等）的相关安全服务的描述。这些服务被默认的Provider提供。附录C表中简要说明了所有的默认Provider。

## 3.2 文件位置
Java安全的某一方面可以使用设置安全属性来定制。这些方面在本文中被提及过，包含配置Provider。也许你静态的在安全属性文件中配置安全属性。安全属性文件默认是在被安装的Java运行环境（JRE）目录的 *lib/security* 目录下的 *java.security* 文件。安全属性可以通过调用`java.security.Security`类的适当方法来动态配置。

本文中提及的工具和命令均在`~jre/bin`目录下。`~jre`表示JRE的安装目录。第五章提及的`cacert`文件在`···`目录下。<commit_msg>UPDATE PKI部分内容<commit_after>---
layout   : post
title    : "【译】Java安全概述"
date     : 2017-07-15 13:53:00
author   : fxleyu
tags:
    - Java
    - 安全
---
> **注意** - 这篇文章是在Java1.5基础上书写的。

# 一、介绍
Java平台在安全上进行着重的设计。Java本身是类型安全的，它还提供了自动垃圾收集，用于增强应用代码的稳健性。一个安全的类（class）加载和认证机制确保仅有合法的Java代码可以被执行。    

最初的Java平台版本创建了一个安全的环境用于执行潜在不可信的代码，例如在公共网络下载的Java applet。伴随着平台升级以及广泛的部署，Java安全架构也相应的进化用于支持正在扩展的服务集合。现在，这个架构包含了一个巨大的集合。集合中包含应用程序接口（APIs），工具；还包含通用安全算法、机制和协议的实现。这个安全架构提供给开发者一个综合的安全框架用于开发应用程序，它还提供给用户或管理员一套可以安全管理应用的工具。    

Java安全APIs横跨广泛的应用区域。加密和公钥基础设施（PKI）的接口为开发安全应用提供了潜在的基础。执行认证和访问控制的接口使应用程序可以防范受保护资源的未授权访问。

这些APIs允许多个可操作的算法和其它安全服务的实现。服务使用`providers`实现。`providers`通过标准接口嵌入到Java平台中。这些标准接口可以使应用程序容易地获取安全服务，而无需关心他们具体的实现。这些APIs允许开发者如何整合安全到他们的应用中，而不是如何实现复杂的安全机制。

Java平台包含了一些供应商（provider），这些供应商实现了安全服务的基础版。平台也允许安装额外的定制供应商。这可以使开发者在平台上扩展新的安全机制。

这篇文章是Java平台安全的概述。其内容从语言安全特性到安全APIs、工具以及一些内置的组件。这些组件包含服务、显著的关键包和类。

# 二、Java的语言安全和字节码验证
Java语言被设计为类型安全和容易使用。它提供了自动内存管理、垃圾收集、以及数组的范围检查。这些措施降低了开发者的整体编程负担，从而促使更少的编程错误更安全、更健壮的代码。

此外，Java语言定义了不同的访问修饰符。这些修饰符可以用来修饰Java类、方法、以及成员变量。这使开发人员能够限制他们的类实现适当的访问。具体来说，语言定义了四个不同的访问级别：`private`,`protected`， `public`，如果未指定，`package`。最开放的访问修饰符是 `public`，允许任何人访问。最限制性修饰语是`private`，私有成员(一个方法或者成员变量)不允许类外访问。`protected`修饰符允许任何子类,或者同一个包内的其它类访问。包级别访问只允许同一包内的类访问。

编译器将Java程序翻译为一种独立于机器的字节码表示。被调用字节码验证器去确保只有合法的字节码才能在Java运行时中执行。它依照Java语言规范检查字节码，确保没违反Java语言规则或命名空间的限制。验证器也检查内存管理违规，栈下溢或溢出和非法数据类型转换。一旦字节码验证,Java运行时准备执行。

# 三、基础安全架构
Java平台定义了一个APIs集合。该集合包含主要的安全区域，其中又加密、PKI、认证、安全通信和访问控制。这些APIs允许开发者很容易把安全整合到应用代码种。这些APIs依据如下原则设计：

1、实现的独立性    
    应用无需实现安全组件。这些应用只需请求Java平台的安全服务即可。Providers实现这些安全服务。他们通过标准接口嵌入到Java平台中。为了安全功能，一个应用也许会依赖多个独立的providers。

2、实现的互用性    
    在应用之间，Providers具有互用性。特别地，一个应用不会绑定到一个特定的Provider，一个Provider也不会绑定到一个特定的应用。

3、可扩展的算法
    Java平台包含一些内置的Provider。这些Porvider实现了安全服务 基础内容。在今天，这些安全服务被广泛使用。但是，一些应用也许依赖新兴的标准，而不是依据被实现的。Java平台支持为实现这些服务而定制的Provider去安装。

## 3.1 安全Provider
在Java平台中，`java.security.Provider`类封装了安全Provider的概念。它指明Provider的名字，并列出被实现的安全服务。也许许多Provider被同时配置，并按特定偏好顺序被列出。当安全服务被请求，实现服务的高优先级的Provider被选择。


应用依赖相关的`getInstance`方法来获取来自潜在Provider的安全服务。举个例子，信息摘要的创建可以描述为Provider提供的一种类型的服务。（第四章讨论信息摘要和其它密码服务。）一个应用调用`java.security.MessageDigest`类的`getInstance`方法去获取一种特定的信息摘要算法的实现，例如MD5。
```java
MessageDigest md = MessageDigest.getInstance("MD5");
```
程序也许可以通过指定Provider名字来指定选择一种特定Provider的实现。
```java
MessageDigest md = MessageDigest.getInstance("MD5", "ProviderC");
```
图1和图2阐明请求一个MD5信息摘要的实现设置。两幅图均显式了三个实现信息摘要算法的Provider。三个Providr从左到右（1到3）按偏好进行排序。在图1中，应用没有指定Provider名字进行请求一个MD5算法实现。这些Provider按照优先序列继续搜索，第一个实现该算法的Provider，ProviderB，被返回。在图2中，应用请求一个被ProviderC实现的MD5算法实现。这时，虽然有较高优先序列的ProviderB也提供一个MD5实现，但是ProviderC也会被返回。

![Test](http://wx3.sinaimg.cn/large/5f4b7840ly1fhn75e1p6ej212m0lptc2.jpg)

Sun公司实现的Java平台中包含很多预先配置的默认Provider。这些Provider提供了可以被应用使用的安全服务的基础集合。注意，其它Java平台供应商也许会包含不同的，封装特定安全服务集合的Provider集合。本文提及的默认内置的Provider，其均是指Sun公司实现的。

以下章节里包含在不同安全区域（加密、认证等）的相关安全服务的描述。这些服务被默认的Provider提供。附录C表中简要说明了所有的默认Provider。

## 3.2 文件位置
Java安全的某一方面可以使用设置安全属性来定制。这些方面在本文中被提及过，包含配置Provider。也许你静态的在安全属性文件中配置安全属性。安全属性文件默认是在被安装的Java运行环境（JRE）目录的 *lib/security* 目录下的 *java.security* 文件。安全属性可以通过调用`java.security.Security`类的适当方法来动态配置。

本文中提及的工具和命令均在`~jre/bin`目录下。`~jre`表示JRE的安装目录。第五章提及的`cacert`文件在`~jre/lib/security`目录下。

# 五、公钥基础设施（PKI）
公钥基础设施(PKI)是一个用于支持基于公钥加密的信息安全交换的框架术语。它允许(人员、组织等的)身份被绑定到数字证书，并提供一种验证证书的真实性的方法。PKI包含密钥、证书、公钥加密，以及生成和数字签署证书的受信任的认证机构(CAs)。Java平台包含了对X.509数字证书和证书撤销列表（CRLs）支持的API和Provider，其也支持兼容PKIX的认证路径构建和验证。和PKI相关的类位于`java.security`和`java.security.cert`包中。

## 5.1 密钥和证书存储
Java平台通过密钥和证书存储提供了对密钥和证书的长期持久存储。具体来说，`java.security.KeyStore`类代表一个密钥库（key store），它是一个加密密钥或者（和）可信任证书（例如，在认证路径验证期间使用）的安全存储库；`java.security.cert.CertStore`类代表一个证书存储区（certificate store），它是一个公共的、潜在的巨大的存储库，该存储库用于存储不相关且通常不受信任的证书。`CertStore`也存储CRLs。

用类型来区分`KeyStore`和`CertStore`的实现。Java平台包括标准的PKCS11和PKCS12密钥存储类型，这些类型实现必须与RSA安全性的PKCS规范兼容。它还包含一个专有的基于文件的被称为JKS（Java Key Store）的密钥存储类型，称为JKS(它代表“Java密钥存储”)，以及一个称为DKS（Domain Key Store）的类型，该类型是作为单个逻辑密钥库的密钥库集合。

Java平台包含了一个特殊的内置JKS密钥存储库（也就是*cacerts*文件），它包含了一些著名的、受信任的CA的证书。keytool实用工具可以列出在*cacerts*中包含的证书(参见第10章中的安全特性文档链接)。

{'fraction_non_alphanumeric': 0.09835390946502058, 'fraction_numerical': 0.016049382716049384, 'mean_word_length': 16.870098039215687, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7139324', 'n_tokens_mistral': 5695, 'n_tokens_neox': 6643, 'n_words': 165}