Java密钥存储总是以空的别名结束。

问题描述 投票:3回答:1

我已经尝试了几天,但我无望地卡住了.为了充分理解java key store的工作原理,我一直在尝试创建自己的keystore,把一些东西放在里面,然后从另一个程序中检索它们。

这是我的keystore生成器。

{

    //generate a X509 certificate
    Security.addProvider(new BouncyCastleProvider());
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "BC");
    X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(new FileInputStream("certificate.cer"));

    LOGGER.debug("BouncyCastle provider & X509 certificate added.");

    //generate a private & a public key
    KeyPair keyPair = generateRSAKeyPair();
    RSAPrivateKey priv = (RSAPrivateKey) keyPair.getPrivate();
    RSAPublicKey pub = (RSAPublicKey) keyPair.getPublic();

    //generate a keystore
    KeyStore ks = KeyStore.getInstance("PKCS12");
    char[] keyStorePassword = "keystore_password".toCharArray();
    ks.load(null, keyStorePassword);
    try (FileOutputStream fos = new FileOutputStream("TestKeyStore.jks")) {
        ks.store(fos, keyStorePassword);
    }

    ks.load(new FileInputStream("TestKeyStore.jks"), keyStorePassword);

    //Symmetric key
    SecretKey secretKey = KeyGenerator.getInstance("AES").generateKey();
    KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry((secretKey));
    KeyStore.ProtectionParameter protectionParameter = new KeyStore.PasswordProtection(keyStorePassword);
    ks.setEntry("symmetric_key", secretKeyEntry, protectionParameter);

    //Asymmetric key
    X509Certificate[] x509Certificates = new X509Certificate[1];
    x509Certificates[0] = certificate;
    ks.setKeyEntry("asymmetric key", priv, keyStorePassword, x509Certificates);

    //certificate
    ks.setCertificateEntry("test_certif", certificate);

    Key key = ks.getKey("symmetric_key", keyStorePassword);
    System.out.println("I have this symmetric key : " + key);
    X509Certificate certificate1 = (X509Certificate) ks.getCertificate("test_certif");
    System.out.println("I have this certificate : " + certificate1);

    System.out.println(ks.aliases().nextElement());


    LOGGER.debug("all went well");
}

正如你可能注意到的,它并不是那么的完美:我的目标是让你的程序在你的电脑上运行。暂且 只是把一些东西放在keystore里面。但这里的重点是,从上一个 System.out.println(ks.aliases().nextElement());,就是想看看钥匙店里面确实有东西。而这个工作就很好,它回馈了 symmetric_key.

现在,从同一个文件夹中又多了一个类,它应该从那个keystore中读取。

注意:这个文件没有任何问题(我已经通过移动它的本地化进行了测试),所以不可能是这个问题。

KeyStore ks = KeyStore.getInstance("PKCS12");
        char[] keyStorePassword = "keystore_password".toCharArray();
        ks.load(new FileInputStream("TestKeyStore.jks"), keyStorePassword);
        System.out.println(ks.containsAlias("symmetric_key"));

这总是让我。false

如果我尝试这样做: System.out.println(ks.aliases());,它总是 null

如果我试试这个

if (!keystore.aliases().hasMoreElements()) {
    System.out.println("nothing inside the keystore");
}

它给我的回报是: nothing inside the keystore.

即使它不是在发电机的情况下。

有什么线索吗?谅谅

java keystore private-key public-key
1个回答
8
投票

问题是你是在写完keystore之后才设置条目的。

如果你把。

try (FileOutputStream fos = new FileOutputStream("TestKeyStore.jks")) {
    ks.store(fos, keyStorePassword);
}

直到这一行之后

ks.setCertificateEntry("test_certif", certificate);

一切都会好起来的

下面是一个工作示例,为了清晰起见,删除了一些代码。

public static void main(String[] args) throws Exception{

    final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
    keyGen.initialize(2048);
    final KeyPair keyPair = keyGen.genKeyPair();

    RSAPrivateKey priv = (RSAPrivateKey) keyPair.getPrivate();

    //generate a keystore
    KeyStore ks = KeyStore.getInstance("PKCS12");
    char[] keyStorePassword = PASSWORD;
    ks.load(null, keyStorePassword);

    X509Certificate[] chain = {generateCertificate("cn=Unknown", keyPair, 365, "SHA256withRSA")};

    // saving one keypair in keystore object
    ks.setKeyEntry("asymmetric key", keyPair.getPrivate(), keyStorePassword, chain);

    //Symmetric key
    SecretKey secretKey = KeyGenerator.getInstance("AES").generateKey();
    KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry((secretKey));
    KeyStore.ProtectionParameter protectionParameter = new KeyStore.PasswordProtection(keyStorePassword);
    // saving symmetric key in keystore object
    ks.setEntry("symmetric_key", secretKeyEntry, protectionParameter);

    // Saving our keystore object into the filesystem
    try (FileOutputStream fos = new FileOutputStream("TestKeyStore.p12")) {
        ks.store(fos, keyStorePassword);
    }

/其余的代码 }

之所以在保存keystore的方法中起作用,是因为改变后的keystore还在内存中,但不在文件系统中。另外,由于你正在创建一个 PKCS12 钥匙店,我会避免使用 .jks 延伸,并去做这样的事情 .pkcs12.

© www.soinside.com 2019 - 2024. All rights reserved.