Java 从密钥库中的文件中读取公钥
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26711731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read public key from file in keystore
提问by iCode
Hi I want to extract public key from KeyStore using Java code
嗨,我想使用 Java 代码从 KeyStore 中提取公钥
I am creating a keystore
我正在创建一个密钥库
keytool -genkey -alias mykeystore -keyalg RSA -keystore mykeystore.jks -keysize 2048
And exporting the public into another file
并将公众导出到另一个文件中
keytool -export -alias mykeystore -keystore mykeystore.jks -rfc -file publickey.cert
How can I get the Public Key String from keystore or the publickey.cert file using the Java code?
如何使用 Java 代码从密钥库或 publickey.cert 文件中获取公钥字符串?
Thanks.
谢谢。
UPDATE
更新
public static void main(String[] args) {
try {
FileInputStream is = new FileInputStream("/home/myuser/my-keystore/mykeystore.jks");
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
String password = "myuserpass";
char[] passwd = password.toCharArray();
keystore.load(is, passwd);
String alias = "mykeystore";
Key key = keystore.getKey(alias, passwd);
if (key instanceof PrivateKey) {
// Get certificate of public key
Certificate cert = keystore.getCertificate(alias);
// Get public key
PublicKey publicKey = cert.getPublicKey();
String publicKeyString = Base64.encodeBase64String(publicKey
.getEncoded());
System.out.println(publicKeyString);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Then it is giving like
然后它就像
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiG2FjSuXrraYuh0TyRNiUvVCyaFlb7VY9AFIMSDdcY0JgNF0c4YVQxYxUCbYzmkLZD/rrYMe/8nxkWV0TMz2Y7GnvichjtWHL1ui58uC0+RtFMkYJ+ftwt9qBy9hvb/rVFTsvT5/b6CQXD8a6bFveMUluQZISLCV7i11XYzp81+w6M7+2fJAwezIJnIrgwv1K9YDjWaToaNXe7hnzzy0s8AdkjTk197+hg8dRfbvkr8XAddNsEMPeUA5iY+5VEpRNI925ZT/dxnaABA0z6i4JbVjeLl8r7ySG9R/2w/j2G+/YSRQc9BmRHPa0tBgH7wvQM+WRwD9WmST+5qeBIfH3QIDAQAB
When I do cat publickey.cert
, it shows this
当我这样做时cat publickey.cert
,它显示了这一点
-----BEGIN CERTIFICATE-----
MIIDgTCCAmmgAwIBAgIEf7XoMDANBgkqhkiG9w0BAQsFADBxMQswCQYDVQQGEwJJTjESMBAGA1UE
CBMJS2FybmF0YWthMRIwEAYDVQQHEwlCYW5nYWxvcmUxEjAQBgNVBAoTCU5ldHNjaXR1czESMBAG
A1UECxMJTmV0c2NpdHVzMRIwEAYDVQQDEwlOZXRzY2l0dXMwHhcNMTQxMTAzMDkyNTM3WhcNMTUw
MjAxMDkyNTM3WjBxMQswCQYDVQQGEwJJTjESMBAGA1UECBMJS2FybmF0YWthMRIwEAYDVQQHEwlC
YW5nYWxvcmUxEjAQBgNVBAoTCU5ldHNjaXR1czESMBAGA1UECxMJTmV0c2NpdHVzMRIwEAYDVQQD
EwlOZXRzY2l0dXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCIbYWNK5eutpi6HRPJ
E2JS9ULJoWVvtVj0AUgxIN1xjQmA0XRzhhVDFjFQJtjOaQtkP+utgx7/yfGRZXRMzPZjsae+JyGO
1YcvW6Lny4LT5G0UyRgn5+3C32oHL2G9v+tUVOy9Pn9voJBcPxrpsW94xSW5BkhIsJXuLXVdjOnz
X7Dozv7Z8kDB7MgmciuDC/Ur1gONZpOho1d7uGfPPLSzwB2SNOTX3v6GDx1F9u+SvxcB102wQw95
QDmJj7lUSlE0j3bllP93GdoAEDTPqLgltWN4uXyvvJIb1H/bD+PYb79hJFBz0GZEc9rS0GAfvC9A
z5ZHAP1aZJP7mp4Eh8fdAgMBAAGjITAfMB0GA1UdDgQWBBSvgDYtI/NGP8Y0EvsCHASjmr/PmzAN
BgkqhkiG9w0BAQsFAAOCAQEACefje/dhmzEkBoA6OV934WtGXcBQNcb+9/qBGevUBG1cNJIyJddi
dea2gFUB1rx/WffTrJyiOCApV8wXG+zmGm6YJenKnGG9sIQtOTibhs3ll7UN4S0n9xsD+1y7YD1c
DNm9lI/3aFn1WUwPc3T4+RXE6XqkDB3geIvLUXaFUi+Y59XiLPHvk61kcopCGeoweX5yWVZ2Njp/
UUJIxQ6Ni3GvfPlxCxWtRe1MDAkhfT6/aAUr37lxtupHibzm9EAJdUEmAFHMhxkNCJiRDsasAiQ8
7V5uBI3ucdSwh+gPaW8KoWlJpv5SGlAkwzq0lSrxyq2ukkC6ciPeKhUvWtHaPg==
-----END CERTIFICATE-----
They keys are different, even in length. Why?
它们的键不同,甚至长度不同。为什么?
回答by L.Butz
You can find a solution by just googleling for your question.
您可以通过 googleling 找到您的问题的解决方案。
Example from java2s.com:
来自 java2s.com 的示例:
import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
public class Main {
public static void main(String[] argv) throws Exception {
FileInputStream is = new FileInputStream("your.keystore");
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(is, "my-keystore-password".toCharArray());
String alias = "myalias";
Key key = keystore.getKey(alias, "password".toCharArray());
if (key instanceof PrivateKey) {
// Get certificate of public key
Certificate cert = keystore.getCertificate(alias);
// Get public key
PublicKey publicKey = cert.getPublicKey();
// Return a key pair
new KeyPair(publicKey, (PrivateKey) key);
}
}
}
See also:
也可以看看:
- http://www.java2s.com/Code/Java/Security/RetrievingaKeyPairfromaKeyStore.htm
- How to retrieve my public and private key from the keystore we created
UPDATE:
更新:
See comments for additional information to the problem.
有关问题的其他信息,请参阅注释。
回答by Santhosh
Once you have successfully exported , you can get it from the key store,
成功导出后,您可以从密钥库中获取它,
through KeyPair(publicKey, (PrivateKey) key)
通过 KeyPair(publicKey, (PrivateKey) key)
An example ,
一个例子 ,
FileInputStream is = new FileInputStream("publickey.cert");
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(is, "my-keystore-password".toCharArray());
String alias = "myalias";
Key key = keystore.getKey(alias, "password".toCharArray());
if (key instanceof PrivateKey) {
// Get certificate of public key
Certificate cert = keystore.getCertificate(alias);
// Get public key
PublicKey publicKey = cert.getPublicKey();
// Return a key pair
new KeyPair(publicKey, (PrivateKey) key);
}
}
will return the new key,valuepair.
将返回新的键值对。
Also read the similar thread here Get Private Key from Keystore
另请阅读此处的类似主题从密钥库获取私钥
回答by RealSkeptic
If it's just the public key string that you want, it's easier to get the publickey.cert
file, as it is a plain text file. Assuming that you have the full path of the file (like "/home/users/iprogrammer/publickey.cert" or "D:\MyDocuments\publickey.cert" ) you do something like:
如果它只是您想要的公钥字符串,那么获取publickey.cert
文件会更容易,因为它是纯文本文件。假设您拥有文件的完整路径(如 "/home/users/iprogrammer/publickey.cert" 或 "D:\MyDocuments\publickey.cert" ),您可以执行以下操作:
public String getPublicKeyString( Path path ) throws IOException {
byte[] fileBytes = Files.readAllBytes(Paths.get(path));
return new String( fileBytes, "US-ASCII" );
}
This will give you the whole file, including the -----BEGIN CERTIFICATE-----
and -----END CERTIFICATE-----
.
这将为您提供整个文件,包括-----BEGIN CERTIFICATE-----
和-----END CERTIFICATE-----
。
Once you have the whole file, you can use the BouncyCastle library to open it:
获得整个文件后,您可以使用 BouncyCastle 库打开它:
PEMParser pemParser = new PEMParser(new StringReader(certPEMData));
Object parsedObj = pemParser.readObject();
System.out.println("PemParser returned: " + parsedObj);
if (parsedObj instanceof X509CertificateHolder)
{
X509CertificateHolder x509CertificateHolder = (X509CertificateHolder) parsedObj;
return x509CertificateHolder.getSubjectPublicKeyInfo().getPublicKeyData().getString();
}
else
{
throw new RuntimeException("The parsed object was not an X509CertificateHolder.");
}
回答by Thomas Stubbe
If you would like the string version of the PublicKey:
如果您想要 PublicKey 的字符串版本:
String publicKeyString value = "-----BEGIN PUBLIC KEY-----\n"
+ new String(Base64.encode(publicKey.getEncoded()))
+ "\n-----END PUBLIC KEY-----";
String publicKeyString value = "-----BEGIN PUBLIC KEY-----\n"
+ new String(Base64.encode(publicKey.getEncoded()))
+ "\n-----END PUBLIC KEY-----";
回答by FkJ
The first base 64 contains only the key
第一个基数 64 只包含密钥
Base64.encodeBase64String(publicKey.getEncoded())
The second base 64 contains the whole public certificate
第二个基数 64 包含整个公共证书
Base64.encodeBase64String(cert.getEncoded())
回答by vsantari
Try this:
尝试这个:
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Enumeration;
import java.security.PublicKey;
import java.util.Base64;
//=====================
try {
File file = new File("C:\Program Files (x86)\keyStoreFilehere.kstr");
FileInputStream is = new FileInputStream(file);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
String password = "password";
keystore.load(is, password.toCharArray());
Enumeration enumeration = keystore.aliases();
while(enumeration.hasMoreElements()) {
String alias = (String)enumeration.nextElement();
Certificate certificate = keystore.getCertificate(alias);
PublicKey publicKey = keystore.getCertificate(alias).getPublicKey();
byte[] encodedCertKey = certificate.getEncoded();
byte[] encodedPublicKey = publicKey.getEncoded();
String b64PublicKey = Base64.getMimeEncoder().encodeToString(encodedPublicKey);
String b64CertKey = Base64.getMimeEncoder().encodeToString(encodedCertKey);
String publicKeyString = "-----BEGIN CERTIFICATE-----\n"
+ b64PublicKey
+ "\n-----END CERTIFICATE-----";
String certKeyString = "-----BEGIN CERTIFICATE-----\n"
+ b64CertKey
+ "\n-----END CERTIFICATE-----";
System.out.println(publicKeyString);
System.out.println(certKeyString);
}
} catch (CertificateException | NoSuchAlgorithmException | KeyStoreException | IOException e) {
e.printStackTrace();
}
回答by Adam Winter
Once you have the KeyStore loaded, it's one simple line to get the PublicKey.
加载 KeyStore 后,只需简单的一行即可获取 PublicKey。
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
PublicKey publicKey = ks.getCertificate("aliasYouChose").getPublicKey();
The PublicKey is located 'inside' the Certificate, the Certficate is not just the PublicKey.
公钥位于证书的“内部”,证书不仅仅是公钥。
Also, it's important to note that a properly formatted PEM key expects a "\n" after every 64 characters. So, simply putting "\n-----END PUBLIC KEY-----" at the end (and respective beginning) might not work if you're trying to then use it with openSSL in PHP, for example.
此外,请务必注意,格式正确的 PEM 密钥在每 64 个字符后需要一个“\n”。因此,例如,如果您尝试在 PHP 中将它与 openSSL 一起使用,那么简单地将“\n-----END PUBLIC KEY-----”放在末尾(和相应的开头)可能不起作用。