我已经尝试了几天,但我无望地卡住了.为了充分理解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
.
即使它不是在发电机的情况下。
有什么线索吗?谅谅
问题是你是在写完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
.