Module java.base
Package java.security

Class 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。它被称为受信任的证书,因为密钥库所有者相信证书中的公钥确实属于由证书的主体(所有者)标识的身份。

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

密钥库中的每个条目都由一个“别名”字符串标识。对于私钥及其关联的证书链,这些字符串区分实体可能进行自我认证的不同方式。例如,实体可以使用不同的证书颁发机构进行自我认证,或者使用不同的公钥算法。

别名是否区分大小写取决于实现。为避免问题,建议不要在只有大小写不同的密钥库中使用别名。

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

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

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

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

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

    // 获取用户密码和文件输入流
    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")) {
        // 获取我的私钥
        KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
            ks.getEntry("privateKeyAlias", protParam);
        PrivateKey myPrivateKey = pkEntry.getPrivateKey();

        // 保存我的秘密密钥
        javax.crypto.SecretKey mySecretKey;
        KeyStore.SecretKeyEntry skEntry =
            new KeyStore.SecretKeyEntry(mySecretKey);
        ks.setEntry("secretKeyAlias", skEntry, protParam);

        // 存储密钥库
        ks.store(fos, password);
    } finally {
        protParam.destroy();
    }
 
请注意,尽管可以使用相同的密码加载密钥库,保护私钥条目,保护秘密密钥条目以及存储密钥库(如上面的示例代码所示),但也可以使用不同的密码或其他保护参数。

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

  • PKCS12
此类型在Java安全标准算法名称规范的密钥库部分中有描述。请查阅您的实现的发布文档,以查看是否支持其他类型。
自版本:
1.2
参见:
  • Constructor Details

    • KeyStore

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

    • getInstance

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

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

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

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

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

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

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

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

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

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

      参数:
      type - 密钥库的类型。有关标准密钥库类型的信息,请参阅Java安全标准算法名称规范中的KeyStore部分。
      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),或给定别名不存在,或给定别名没有关联的属性,则此集合为空。对于仅在提取条目后通过KeyStore.Entry.getAttributes()方法可用的PrivateKeyEntrySecretKeyEntry条目,此集合也可能为空。
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(已加载)。
      NullPointerException - 如果aliasnull
      自版本:
      18
    • getKey

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

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

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

      如果给定别名标识通过调用setCertificateEntry创建的条目,或通过调用setEntryTrustedCertificateEntry创建的条目,则返回该条目中包含的受信任证书。

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

      参数:
      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创建的现有条目,或由调用setEntry创建的TrustedCertificateEntry,则现有条目中的受信任证书将被给定证书覆盖。

      参数:
      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创建的,或由调用setEntry创建的PrivateKeyEntrySecretKeyEntry,则返回true
      参数:
      alias - 要检查的密钥库条目的别名
      返回:
      如果由给定别名标识的条目是与密钥相关的条目,则返回true,否则返回false
      抛出:
      KeyStoreException - 如果密钥库尚未初始化(加载)。
    • isCertificateEntry

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

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

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

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

      参数:
      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起:
      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 - 如果密钥库中的任何证书无法加载
      自 JDK 版本:
      1.5
    • getEntry

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

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

      如果指定别名已存在条目,则会被覆盖。

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

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

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

      可以提供密码以解锁密钥库(例如,密钥库位于硬件令牌设备上)或检查密钥库数据的完整性。如果未提供密码进行完整性检查,则不执行完整性检查。

      此方法遍历已注册的安全提供者列表,从最优先的提供者开始。对于每个提供者支持的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)方法拒绝对指定文件的读取访问。
      自 JDK 版本:
      9
      参见:
    • getInstance

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

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

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

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