模块 java.base

类 KeyStore

java.lang.Object
java.security.KeyStore

public class KeyStore extends Object
此类表示加密密钥和证书的存储设施。

KeyStore 管理不同类型的条目。每种类型的条目都实现了 KeyStore.Entry 接口。提供了三个基本的KeyStore.Entry实现:

  • KeyStore.PrivateKeyEntry

    这种类型的条目包含一个密码 PrivateKey ,它可以选择以受保护的格式存储以防止未经授权的访问。它还附有相应公钥的证书链。

    给定实体使用私钥和证书链进行自我认证。此身份验证的应用程序包括签署 JAR 文件作为发布和/或许可软件的一部分的软件分发组织。

  • KeyStore.SecretKeyEntry

    这种类型的条目包含一个密码 SecretKey ,它可以选择以受保护的格式存储以防止未经授权的访问。

  • KeyStore.TrustedCertificateEntry

    这种类型的条目包含属于另一方的单个公钥 Certificate。它被称为可信证书因为密钥库所有者相信证书中的公钥确实属于由主题(所有者)证书。

    这种类型的条目可用于验证其他方。

密钥库中的每个条目都由“别名”字符串标识。在私钥及其相关证书链的情况下,这些字符串区分实体可以验证自身的不同方式。例如,实体可以使用不同的证书颁发机构或使用不同的公钥算法来验证自己。

别名是否区分大小写取决于实现。为了避免出现问题,建议不要在 KeyStore 中使用仅大小写不同的别名。

密钥库是否是持久的,以及密钥库使用的机制(如果它是持久的)在这里没有指定。这允许使用各种技术来保护敏感(例如,私人或秘密)密钥。智能卡或其他集成加密引擎 (SafeKeyper) 是一种选择,也可以使用更简单的机制,例如文件(以各种格式)。

请求 KeyStore 对象的典型方法包括指定现有的密钥库文件、依赖默认类型并提供特定的密钥库类型。

  • 要指定现有的密钥库文件:
      // get keystore password
      char[] password = getPassword();
    
      // probe the keystore file and load the keystore entries
      KeyStore ks = KeyStore.getInstance(new File("keyStoreName"), password);
    
    系统将探测指定的文件以确定其密钥库类型并返回其条目已加载的密钥库实现。使用此方法时,无需调用密钥库的 load 方法。
  • 要依赖默认类型:
      KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
     
    系统将返回默认类型的密钥库实现。
  • 提供特定密钥库类型:
       KeyStore ks = KeyStore.getInstance("JKS");
     
    系统将返回环境中可用的指定密钥库类型的最优选实现。

在可以访问密钥库之前,它必须是 loaded (除非它已经在实例化期间加载)。

  KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

  // get user password and file input stream
  char[] password = getPassword();

  try (FileInputStream fis = new FileInputStream("keyStoreName")) {
    ks.load(fis, password);
  }
 
要使用上述 load 方法创建空密钥库,请将 null 作为 InputStream 参数传递。

加载密钥库后,可以从密钥库中读取现有条目,或将新条目写入密钥库:

  KeyStore.PasswordProtection protParam =
    new KeyStore.PasswordProtection(password);
  try (FileOutputStream fos = new FileOutputStream("newKeyStoreName")) {
    // get my private key
    KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
      ks.getEntry("privateKeyAlias", protParam);
    PrivateKey myPrivateKey = pkEntry.getPrivateKey();

    // save my secret key
    javax.crypto.SecretKey mySecretKey;
    KeyStore.SecretKeyEntry skEntry =
      new KeyStore.SecretKeyEntry(mySecretKey);
    ks.setEntry("secretKeyAlias", skEntry, protParam);

    // store away the keystore
    ks.store(fos, password);
  } finally {
    protParam.destroy();
  }
 
注意,虽然相同的密码可能用于加载密钥库、保护私钥条目、保护秘密密钥条目和存储密钥库(如上面的示例代码所示),不同的密码或其他保护也可以使用参数。

Java 平台的每个实现都需要支持以下标准 KeyStore 类型:

  • PKCS12
此类型在 Java 安全标准算法名称规范的密钥库部分中进行了描述。请查阅您的实施的发布文档以查看是否支持任何其他类型。
自从:
1.2
参见:
  • 构造方法详细信息

    • KeyStore

      protected KeyStore(KeyStoreSpi  keyStoreSpi, Provider  provider, String  type)
      创建给定类型的 KeyStore 对象,并将给定的提供程序实现(SPI 对象)封装在其中。
      参数:
      keyStoreSpi - 提供者实现。
      provider - 提供商。
      type - 密钥库类型。
  • 方法详情

    • getInstance

      public static KeyStore  getInstance(String  type) throws KeyStoreException
      返回指定类型的 KeyStore 对象。

      此方法遍历已注册安全提供程序的列表,从最首选的提供程序开始。返回一个新的 KeyStore 对象,该对象封装了支持指定类型的第一个提供程序的 KeyStoreSpi 实现。

      请注意,可以通过 Security.getProviders() 方法检索已注册提供商的列表。

      实现注意事项:
      JDK 参考实现还使用 jdk.security.provider.preferred Security 属性来确定指定算法的首选提供程序顺序。这可能与 Security.getProviders() 返回的提供商顺序不同。
      参数:
      type - 密钥库的类型。有关标准密钥库类型的信息,请参阅 Java 安全标准算法名称规范 中的密钥库部分。
      返回:
      指定类型的密钥库对象
      抛出:
      KeyStoreException - 如果没有提供者支持指定类型的 KeyStoreSpi 实现
      NullPointerException - 如果 typenull
      参见:
    • getInstance

      public static KeyStore  getInstance(String  type, String  provider) throws KeyStoreException , NoSuchProviderException
      返回指定类型的 KeyStore 对象。

      返回一个新的 KeyStore 对象,其中封装了来自指定提供程序的 KeyStoreSpi 实现。指定的提供者必须在安全提供者列表中注册。

      请注意,可以通过 Security.getProviders() 方法检索已注册提供商的列表。

      参数:
      type - 密钥库的类型。有关标准密钥库类型的信息,请参阅 Java 安全标准算法名称规范 中的密钥库部分。
      provider - 提供商的名称。
      返回:
      指定类型的密钥库对象
      抛出:
      IllegalArgumentException - 如果提供商名称为 null 或为空
      KeyStoreException - 如果指定类型的 KeyStoreSpi 实现无法从指定提供程序获得
      NoSuchProviderException - 如果指定的提供者没有在安全提供者列表中注册
      NullPointerException - 如果 typenull
      参见:
    • getInstance

      public static KeyStore  getInstance(String  type, Provider  provider) throws KeyStoreException
      返回指定类型的 KeyStore 对象。

      返回一个新的 KeyStore 对象,它封装了来自指定提供者对象的 KeyStoreSpi 实现。请注意,指定的提供者对象不必在提供者列表中注册。

      参数:
      type - 密钥库的类型。有关标准密钥库类型的信息,请参阅 Java 安全标准算法名称规范 中的密钥库部分。
      provider - 提供商。
      返回:
      指定类型的密钥库对象
      抛出:
      IllegalArgumentException - 如果指定的提供者是 null
      KeyStoreException - 如果无法从指定的 Provider 对象获得指定类型的 KeyStoreSpi 实现
      NullPointerException - 如果 typenull
      自从:
      1.4
      参见:
    • getDefaultType

      public static final String  getDefaultType()
      返回由 keystore.type 安全属性指定的默认密钥库类型,如果不存在此类属性,则返回字符串“jks”(“Java 密钥库”的首字母缩写词)。

      在调用 getInstance 方法之一时不想使用硬编码密钥库类型的应用程序可以使用默认密钥库类型,并希望在用户未指定其自己的情况下提供默认密钥库类型。

      可以通过将 keystore.type 安全属性的值设置为所需的密钥库类型来更改默认密钥库类型。

      返回:
      keystore.type 安全属性指定的默认密钥库类型,如果不存在此类属性,则为字符串“jks”。
      参见:
    • getProvider

      public final Provider  getProvider()
      返回此密钥库的提供者。
      返回:
      此密钥库的提供者。
    • getType

      public final String  getType()
      返回此密钥库的类型。
      返回:
      此密钥库的类型。
    • getAttributes

      public final Set <KeyStore.Entry.Attribute > getAttributes(String  alias) throws KeyStoreException
      检索与给定别名关联的属性。
      参数:
      alias - 别名
      返回:
      不可修改的 Set 属性。如果 KeyStoreSpi 实现没有覆盖 KeyStoreSpi.engineGetAttributes(String) ,或者给定别名不存在,或者没有与别名关联的属性,则此集合为空。对于包含受保护属性的 PrivateKeyEntrySecretKeyEntry 条目,该集合也可能为空,并且仅在提取条目后通过 KeyStore.Entry.getAttributes() 方法可用。
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
      NullPointerException - 如果 aliasnull
      自从:
      18
    • getKey

      public final Key  getKey(String  alias, char[] password) throws KeyStoreException , NoSuchAlgorithmException , UnrecoverableKeyException
      返回与给定别名关联的密钥,使用给定密码恢复它。密钥必须已通过调用 setKeyEntry 或使用 PrivateKeyEntrySecretKeyEntry 调用 setEntry 与别名相关联。
      参数:
      alias - 别名
      password - 恢复密钥的密码
      返回:
      请求的密钥,或 null 如果给定的别名不存在或未标识与密钥相关的条目。
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
      NoSuchAlgorithmException - 如果找不到恢复密钥的算法
      UnrecoverableKeyException - 如果密钥无法恢复(例如,给定的密码错误)。
    • getCertificateChain

      public final Certificate [] getCertificateChain(String  alias) throws KeyStoreException
      返回与给定别名关联的证书链。证书链必须已通过调用 setKeyEntry 或使用 PrivateKeyEntry 调用 setEntry 与别名相关联。
      参数:
      alias - 别名
      返回:
      证书链(首先是用户证书,然后是零个或多个证书颁发机构),如果给定的别名不存在或不包含证书链,则返回 null
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
    • getCertificate

      public final Certificate  getCertificate(String  alias) throws KeyStoreException
      返回与给定别名关联的证书。

      如果给定的别名标识了通过调用 setCertificateEntry 创建的条目,或者通过使用 TrustedCertificateEntry 调用 setEntry 创建的条目,则返回该条目中包含的可信证书。

      如果给定的别名标识了通过调用 setKeyEntry 创建的条目,或者通过使用 PrivateKeyEntry 调用 setEntry 创建的条目,则返回该条目中证书链的第一个元素。

      参数:
      alias - 别名
      返回:
      证书,或者 null 如果给定的别名不存在或不包含证书。
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
    • getCreationDate

      public final Date  getCreationDate(String  alias) throws KeyStoreException
      返回由给定别名标识的条目的创建日期。
      参数:
      alias - 别名
      返回:
      此条目的创建日期,如果给定的别名不存在,则为 null
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
    • setKeyEntry

      public final void setKeyEntry(String  alias, Key  key, char[] password, Certificate [] chain) throws KeyStoreException
      将给定的密钥分配给给定的别名,用给定的密码保护它。

      如果给定密钥的类型为 java.security.PrivateKey ,则它必须附有证明相应公钥的证书链。

      如果给定的别名已经存在,则与其关联的密钥库信息将被给定的密钥(可能还有证书链)重写。

      参数:
      alias - 别名
      key - 与别名关联的键
      password - 保护密钥的密码
      chain - 相应公钥的证书链(仅当给定密钥的类型为 java.security.PrivateKey 时才需要)。
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载),则无法保护给定的密钥,或者由于其他原因此操作失败
    • setKeyEntry

      public final void setKeyEntry(String  alias, byte[] key, Certificate [] chain) throws KeyStoreException
      将给定的密钥(已经受到保护)分配给给定的别名。

      如果受保护密钥的类型为 java.security.PrivateKey ,则它必须附有证明相应公钥的证书链。如果底层密钥库实现是 jks 类型,则 key 必须编码为 PKCS #8 标准中定义的 EncryptedPrivateKeyInfo

      如果给定的别名已经存在,则与其关联的密钥库信息将被给定的密钥(可能还有证书链)重写。

      参数:
      alias - 别名
      key - 与别名关联的密钥(受保护格式)
      chain - 相应公钥的证书链(仅当受保护密钥的类型为 java.security.PrivateKey 时才有用)。
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载),或者此操作因其他原因失败。
    • setCertificateEntry

      public final void setCertificateEntry(String  alias, Certificate  cert) throws KeyStoreException
      将给定的可信证书分配给给定的别名。

      如果给定的别名标识了通过调用 setCertificateEntry 创建的现有条目,或者通过使用 TrustedCertificateEntry 调用 setEntry 创建的现有条目,则现有条目中的受信任证书将被给定证书覆盖。

      参数:
      alias - 别名
      cert - 证书
      抛出:
      KeyStoreException - 如果密钥库尚未初始化,或者给定的别名已经存在并且未标识包含受信任证书的条目,或者此操作由于某些其他原因而失败。
    • deleteEntry

      public final void deleteEntry(String  alias) throws KeyStoreException
      从此密钥库中删除由给定别名标识的条目。
      参数:
      alias - 别名
      抛出:
      KeyStoreException - 如果密钥库尚未初始化,或者无法删除条目。
    • aliases

      public final Enumeration <String > aliases() throws KeyStoreException
      列出此密钥库的所有别名。
      返回:
      别名的枚举
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
    • containsAlias

      public final boolean containsAlias(String  alias) throws KeyStoreException
      检查此密钥库中是否存在给定的别名。
      参数:
      alias - 别名
      返回:
      true 如果别名存在,false 否则
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
    • size

      public final int size() throws KeyStoreException
      检索此密钥库中的条目数。
      返回:
      此密钥库中的条目数
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
    • isKeyEntry

      public final boolean isKeyEntry(String  alias) throws KeyStoreException
      如果由给定别名标识的条目是通过调用 setKeyEntry 创建的,或者是通过使用 PrivateKeyEntrySecretKeyEntry 调用 setEntry 创建的,则返回 true
      参数:
      alias - 要检查的密钥库条目的别名
      返回:
      true 如果给定别名标识的条目是与密钥相关的条目,false 否则。
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
    • isCertificateEntry

      public final boolean isCertificateEntry(String  alias) throws KeyStoreException
      如果给定别名标识的条目是通过调用 setCertificateEntry 创建的,或者是通过调用 setEntryTrustedCertificateEntry 创建的,则返回 true
      参数:
      alias - 要检查的密钥库条目的别名
      返回:
      true 如果给定别名标识的条目包含可信证书,false 否则。
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
    • getCertificateAlias

      public final String  getCertificateAlias(Certificate  cert) throws KeyStoreException
      返回其证书与给定证书匹配的第一个密钥库条目的(别名)名称。

      此方法尝试将给定的证书与每个密钥库条目进行匹配。如果正在考虑的条目是通过调用 setCertificateEntry 创建的,或者是通过使用 TrustedCertificateEntry 调用 setEntry 创建的,则将给定的证书与该条目的证书进行比较。

      如果正在考虑的条目是通过调用 setKeyEntry 创建的,或者是通过使用 PrivateKeyEntry 调用 setEntry 创建的,则将给定的证书与该条目的证书链的第一个元素进行比较。

      参数:
      cert - 要匹配的证书。
      返回:
      具有匹配证书的第一个条目的别名,如果此密钥库中不存在此类条目,则为 null
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
    • store

      public final void store(OutputStream  stream, char[] password) throws KeyStoreException , IOException , NoSuchAlgorithmException , CertificateException
      将此密钥库存储到给定的输出流,并使用给定的密码保护其完整性。
      参数:
      stream - 写入此密钥库的输出流。
      password - 生成密钥库完整性检查的密码。如果密钥库不支持或不需要完整性检查,则可能是 null
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
      IOException - 如果数据出现 I/O 问题
      NoSuchAlgorithmException - 如果找不到合适的数据完整性算法
      CertificateException - 如果无法存储密钥库数据中包含的任何证书
    • store

      使用给定的 LoadStoreParameter 存储此密钥库。
      参数:
      param - 指定如何存储密钥库的 LoadStoreParameter,可能是 null
      抛出:
      IllegalArgumentException - 如果给定的 LoadStoreParameter 输入未被识别
      KeyStoreException - 如果密钥库尚未初始化(加载)
      IOException - 如果数据出现 I/O 问题
      NoSuchAlgorithmException - 如果找不到合适的数据完整性算法
      CertificateException - 如果无法存储密钥库数据中包含的任何证书
      UnsupportedOperationException - 如果不支持此操作
      自从:
      1.5
    • load

      public final void load(InputStream  stream, char[] password) throws IOException , NoSuchAlgorithmException , CertificateException
      从给定的输入流加载此密钥库。

      可以给出密码来解锁密钥库(例如,密钥库驻留在硬件令牌设备上),或检查密钥库数据的完整性。如果没有为完整性检查提供密码,则不执行完整性检查。

      为了创建一个空的密钥库,或者如果无法从流中初始化密钥库,请将 null 作为 stream 参数传递。

      请注意,如果此密钥库已被加载,则会重新初始化并从给定的输入流中再次加载。

      参数:
      stream - 从中加载密钥库的输入流,或 null
      password - 用于检查密钥库完整性的密码,用于解锁密钥库的密码,或 null
      抛出:
      IOException - 如果密钥库数据存在 I/O 或格式问题,如果需要密码但没有给出,或者如果给定的密码不正确。如果错误是由于密码错误,IOExceptioncause 应该是UnrecoverableKeyException
      NoSuchAlgorithmException - 如果找不到用于检查密钥库完整性的算法
      CertificateException - 如果无法加载密钥库中的任何证书
    • load

      使用给定的 LoadStoreParameter 加载此密钥库。

      请注意,如果此 KeyStore 已被加载,则会重新初始化并从给定参数再次加载。

      参数:
      param - 指定如何加载密钥库的 LoadStoreParameter,可能是 null
      抛出:
      IllegalArgumentException - 如果给定的 LoadStoreParameter 输入未被识别
      IOException - 如果密钥库数据存在 I/O 或格式问题。如果错误是由于ProtectionParameter不正确(例如密码错误)引起的,则IOExceptioncause 应该是UnrecoverableKeyException
      NoSuchAlgorithmException - 如果找不到用于检查密钥库完整性的算法
      CertificateException - 如果无法加载密钥库中的任何证书
      自从:
      1.5
    • getEntry

      为具有指定保护参数的指定别名获取密钥库 Entry
      参数:
      alias - 获取此别名的密钥库 Entry
      protParam - ProtectionParameter 用于保护 Entry,可能是 null
      返回:
      指定别名的密钥库 Entry,如果没有这样的条目,则为 null
      抛出:
      NullPointerException - 如果 aliasnull
      NoSuchAlgorithmException - 如果找不到用于恢复条目的算法
      UnrecoverableEntryException - 如果指定的 protParam 不足或无效
      UnrecoverableKeyException - 如果条目是 PrivateKeyEntrySecretKeyEntry 并且指定的 protParam 不包含恢复密钥所需的信息(例如错误的密码)
      KeyStoreException - 如果密钥库尚未初始化(加载)。
      自从:
      1.5
      参见:
    • setEntry

      public final void setEntry(String  alias, KeyStore.Entry  entry, KeyStore.ProtectionParameter  protParam) throws KeyStoreException
      在指定的别名下保存一个密钥库 Entry。保护参数用于保护Entry

      如果指定别名的条目已存在,则将其重写。

      参数:
      alias - 将密钥库 Entry 保存在此别名下
      entry - 要保存的 Entry
      protParam - ProtectionParameter 用于保护 Entry,可能是 null
      抛出:
      NullPointerException - 如果 aliasentrynull
      KeyStoreException - 如果密钥库尚未初始化(加载),或者此操作因其他原因失败
      自从:
      1.5
      参见:
    • entryInstanceOf

      public final boolean entryInstanceOf(String  alias, Class <? extends KeyStore.Entry > entryClass) throws KeyStoreException
      确定指定 alias 的密钥库 Entry 是否是指定 entryClass 的实例或子类。
      参数:
      alias - 别名
      entryClass - 入门级
      返回:
      true 如果指定 alias 的密钥库 Entry 是指定 entryClass 的实例或子类,否则为 false
      抛出:
      NullPointerException - 如果 aliasentryClassnull
      KeyStoreException - 如果密钥库尚未初始化(加载)
      自从:
      1.5
    • getInstance

      public static final KeyStore  getInstance(File  file, char[] password) throws KeyStoreException , IOException , NoSuchAlgorithmException , CertificateException
      返回适当密钥库类型的已加载密钥库对象。首先,密钥库类型是通过探测指定文件来确定的。然后使用该文件中的数据实例化并加载密钥库对象。

      可以给出密码来解锁密钥库(例如,密钥库驻留在硬件令牌设备上),或检查密钥库数据的完整性。如果没有为完整性检查提供密码,则不执行完整性检查。

      此方法遍历已注册安全性 providers 的列表,从最首选的提供者开始。对于提供商支持的每个 KeyStoreSpi 实现,它调用 engineProbe 方法来确定它是否支持指定的密钥库。返回一个新的 KeyStore 对象,它封装了支持指定文件的第一个提供程序的 KeyStoreSpi 实现。

      请注意,可以通过 Security.getProviders() 方法检索已注册提供商的列表。

      参数:
      file - 密钥库文件
      password - 密钥库密码,可能是 null
      返回:
      加载了密钥库数据的密钥库对象
      抛出:
      KeyStoreException - 如果没有提供者支持指定密钥库文件的 KeyStoreSpi 实现。
      IOException - 如果密钥库数据存在 I/O 或格式问题,如果需要密码但没有给出,或者如果给定的密码不正确。如果错误是由于密码错误引起的,则 IOExceptioncause 应该是 UnrecoverableKeyException
      NoSuchAlgorithmException - 如果找不到用于检查密钥库完整性的算法。
      CertificateException - 如果无法加载密钥库中的任何证书。
      IllegalArgumentException - 如果文件不存在或不引用普通文件。
      NullPointerException - 如果文件是 null
      SecurityException - 如果安全管理器存在且其 SecurityManager.checkRead(java.io.FileDescriptor) 方法拒绝对指定文件的读取访问。
      自从:
      9
      参见:
    • getInstance

      返回适当密钥库类型的已加载密钥库对象。首先,密钥库类型是通过探测指定文件来确定的。然后使用该文件中的数据实例化并加载密钥库对象。可以提供 LoadStoreParameter 指定如何解锁密钥库数据或执行完整性检查。

      此方法遍历已注册安全性 providers 的列表,从最首选的提供者开始。对于提供商支持的每个 KeyStoreSpi 实现,它调用 engineProbe 方法来确定它是否支持指定的密钥库。返回一个新的 KeyStore 对象,它封装了支持指定文件的第一个提供程序的 KeyStoreSpi 实现。

      请注意,可以通过 Security.getProviders() 方法检索已注册提供商的列表。

      参数:
      file - 密钥库文件
      param - 指定如何加载密钥库的 LoadStoreParameter,可能是 null
      返回:
      加载了密钥库数据的密钥库对象
      抛出:
      KeyStoreException - 如果没有提供者支持指定密钥库文件的 KeyStoreSpi 实现。
      IOException - 如果密钥库数据存在 I/O 或格式问题。如果错误是由于不正确的ProtectionParameter(例如错误的密码)引起的,IOExceptioncause 应该是UnrecoverableKeyException
      NoSuchAlgorithmException - 如果找不到用于检查密钥库完整性的算法。
      CertificateException - 如果无法加载密钥库中的任何证书。
      IllegalArgumentException - 如果文件不存在或不引用普通文件,或者参数无法识别。
      NullPointerException - 如果文件是 null
      SecurityException - 如果安全管理器存在且其 SecurityManager.checkRead(java.io.FileDescriptor) 方法拒绝对指定文件的读取访问。
      自从:
      9
      参见: