java.security.UnrecoverableKeyException:执行KeyManagerFactory.init()时无法恢复密钥

时间:2013-12-26 16:07:04

标签: java keystore

我有以下代码尝试使用SHA-256哈希作为密码初始化KeyManagerFactory。

public static KeyManager[] getKeystoreManagers()
    throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, NoSuchProviderException {
    KeyStore keystore = getKeyStore();

    if (keystore == null) {
        return null;
    }

    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());        
    kmf.init(keystore, getMachinePassword(SHA_256).toCharArray());

    return kmf.getKeyManagers();
}

getKeyStore()返回我的应用程序密钥库。 getMachinePassword()使用SHA-256,64位密码长度返回密码。
问题是我在调用init()时得到异常:

java.security.UnrecoverableKeyException: Cannot recover key

如果我传递较小的密码长度,可以说,初始化成功的50位数。
这里似乎有什么问题?

1 个答案:

答案 0 :(得分:1)

我已经解决了我的问题。密钥库是使用具有特定别名的setEntry创建的。
因此,在我的转换函数中,我必须使用旧密码获取条目,并使用新密码再次使用相同的别名设置相同的条目。现在,使用此更新的密钥库,KeyManagerFactory.init()成功运行。请参阅以下代码:

static void convertPasswordAlgorithm(String keystorePath, String fromAlgorithm, String toAlgorithm) throws Exceptionc {
    FileInputStream fileInStream = null;
    String keystoreFullPath = keystorePath + ISiteConstants.c_FILE_SEPERATOR + KEYSTORE_FILE_NAME;
    KeyStore keyStore;

    try {
        String alias = getCertificateAlias();
        keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        fileInStream = new FileInputStream(keystoreFullPath);

        // Try to load the keystore with fromAlgorithm password hash.
        char[] machineOldAlgPassword = getMachinePassword(fromAlgorithm).toCharArray();
        keyStore.load(fileInStream, machineOldAlgPassword);

        // Save the entry to update
        KeyStore.Entry entry = keyStore.getEntry(alias, new KeyStore.PasswordProtection(machineOldAlgPassword));
        HandleFiles.close(fileInStream);

        // If succeeded, recalculate password using toAlgorithm hash and save.
        String machineNewAlgPassword = getMachinePassword(toAlgorithm);
        keyStore.setEntry(alias, entry, new KeyStore.PasswordProtection(machineNewAlgPassword.toCharArray()));

        FileOutputStream fileOutputStream = new FileOutputStream(keystoreFullPath);
        keyStore.store(fileOutputStream, machineNewAlgPassword.toCharArray());
        HandleFiles.close(fileOutputStream);
    } finally {
        HandleFiles.close(fileInStream);
    }
}