【问题标题】:KeyStore EOFException after getting entry进入后 KeyStore EOFException
【发布时间】:2018-01-02 02:09:55
【问题描述】:

我创建了一个KeyStore 来在 Web 服务器中保存一组私钥。创建KeyStore.jks 文件后,我成功添加了一个私钥并从密钥库中检索它。但是,当我尝试添加一个新密钥时,我在 KeyStore.load(...) 中得到一个 EOFException

public void setPrivateKey(String deviceSerialNumber, PrivateKey priv) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, InvalidKeySpecException, NotSupportedException {
    File privateKeyFile = getFile(Constants.JKS_PRIVATE_FILE_NAME);//Get the KeyStore.jks file
    synchronized (privateKeyFile) {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(new FileInputStream(privateKeyFile), Constants.JKS_PRIVATE_FILE_PASSWORD); //This is where the error happens 
        FileOutputStream file = null;
        try {
            file = new FileOutputStream(privateKeyFile);//Get the JKS file with the private keys


            //Write the private key to the file
            KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(Constants.JKS_PRIVATE_FILE_PASSWORD);
            KeyStore.PrivateKeyEntry pke = new KeyStore.PrivateKeyEntry(priv, new Certificate[] { createCertificate() });
            keyStore.setEntry(deviceSerialNumber, pke, protParam);

            //Save changes to key store file
            keyStore.store(file, Constants.JKS_PRIVATE_FILE_PASSWORD);

        } finally {
            file.close();//Close the private key file output stream
        }

    }
}

public PrivateKey getPrivateKey(String deviceSerialNumber) throws NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, KeyStoreException, InvalidKeySpecException, NotSupportedException, UnrecoverableEntryException {
    PrivateKey key = null;
    File privateKeyFile = getFile(Constants.JKS_PRIVATE_FILE_NAME);//Get the keyStore.jks file
    synchronized (privateKeyFile) {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(new FileInputStream(privateKeyFile), Constants.JKS_PRIVATE_FILE_PASSWORD);
        FileOutputStream file = null;
        try {
            file = new FileOutputStream(privateKeyFile);//Get the JKS file with the private keys


            //Write the private key to the jks file
            boolean isKeyEntry = keyStore.isKeyEntry(deviceSerialNumber);//Check if there is a key with the alias deviceSerialnumber
            if (isKeyEntry) {//If the key does exist
                System.err.println("Key does exist!!!!1");
                KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(Constants.JKS_PRIVATE_FILE_PASSWORD);
                KeyStore.PrivateKeyEntry pke =  (PrivateKeyEntry) keyStore.getEntry(deviceSerialNumber, protParam);
                key = pke.getPrivateKey();
            } else {//If the key does not exist
                System.err.println("No key!!!!!!!!");
                //HANDLE THIS
                return null;
            }

        } finally {
            file.close();//Close the private key file output stream
        }
    }
    return key;
}

private Certificate createCertificate() throws CertificateException, IOException {
    FileInputStream fis = new FileInputStream(getFile(Constants.CERTIFICATE_FILE));


    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    Collection<? extends Certificate> c = cf.generateCertificates(fis);
    Iterator<? extends Certificate> i = c.iterator();

    if (i.hasNext())
        return (Certificate) i.next();
    else 
        return null;
}

错误发生在setPrivateKey(...) keyStore.load(...) 第二次调用该方法以向密钥库添加额外的私钥。

我使用 keytool 生成KeyStore.jks 文件和server.cer 文件

keytool -genkey -alias keyAlias -keyalg RSA  -keystore KeyStore.jks -keypass password -storepass password
keytool -export -alias keyAlias -file server.cer -keystore KeyStore.jks -storepass password

我在从密钥库存储和检索私钥的方式上做错了吗?如何阻止 EOFException 发生?

【问题讨论】:

  • 尝试去掉这行getPrivateKey:file = new FileOutputStream(privateKeyFile);并关闭你之前创建的FileInputStream,而不是输出流
  • 确实有效。谢谢

标签: java security keystore private-key


【解决方案1】:

去掉getPrivateKey这一行

file = new FileOutputStream(privateKeyFile);

它没有被使用并关闭你之前创建的 FileInputStream,而不是输出流。您在同一个文件上有两个打开的流

 keyStore.load(new FileInputStream(privateKeyFile), Constants.JKS_PRIVATE_FILE_PASSWORD);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 2011-10-27
    相关资源
    最近更新 更多