从密钥库中的文件读取公钥

时间:2014-11-03 09:57:27

标签: java keystore public-key

您好我想使用Java代码从KeyStore中提取公钥

我正在创建一个密钥库

keytool -genkey -alias mykeystore -keyalg RSA -keystore mykeystore.jks -keysize 2048

将公众导出到另一个文件

keytool -export -alias mykeystore -keystore mykeystore.jks -rfc -file publickey.cert

如何使用Java代码从keystore或publickey.cert文件获取公钥字符串?

感谢。

更新

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();
    }
}

然后就像

一样
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiG2FjSuXrraYuh0TyRNiUvVCyaFlb7VY9AFIMSDdcY0JgNF0c4YVQxYxUCbYzmkLZD/rrYMe/8nxkWV0TMz2Y7GnvichjtWHL1ui58uC0+RtFMkYJ+ftwt9qBy9hvb/rVFTsvT5/b6CQXD8a6bFveMUluQZISLCV7i11XYzp81+w6M7+2fJAwezIJnIrgwv1K9YDjWaToaNXe7hnzzy0s8AdkjTk197+hg8dRfbvkr8XAddNsEMPeUA5iY+5VEpRNI925ZT/dxnaABA0z6i4JbVjeLl8r7ySG9R/2w/j2G+/YSRQc9BmRHPa0tBgH7wvQM+WRwD9WmST+5qeBIfH3QIDAQAB

当我执行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-----

它们的键是不同的,即使长度也是如此。为什么呢?

7 个答案:

答案 0 :(得分:13)

只需谷歌搜索您的问题即可找到解决方案。

来自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);
    }
  }
}

另见:

<强>更新

有关问题的其他信息,请参阅注释。

答案 1 :(得分:4)

如果它只是您想要的公钥字符串,则更容易获取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" );
}

这将为您提供整个文件,包括-----BEGIN CERTIFICATE----------END CERTIFICATE-----

获得整个文件后,可以使用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.");
    }

答案 2 :(得分:2)

试试这个:

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();
 }

答案 3 :(得分:1)

第一个基础64仅包含密钥

Base64.encodeBase64String(publicKey.getEncoded())

第二个基础64包含整个公共证书

Base64.encodeBase64String(cert.getEncoded())

答案 4 :(得分:0)

成功导出后,您可以从密钥库中获取

通过KeyPair(publicKey, (PrivateKey) key)

一个例子,

   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);
    }
  } 

将返回新的键,值对。

另请阅读此处的类似帖子Get Private Key from Keystore

答案 5 :(得分:0)

如果您想要PublicKey的字符串版本:

String publicKeyString value = "-----BEGIN PUBLIC KEY-----\n" + new String(Base64.encode(publicKey.getEncoded())) + "\n-----END PUBLIC KEY-----";

答案 6 :(得分:0)

一旦加载了KeyStore,这是获取PublicKey的简单行。

    KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
    ks.load(null);          
    PublicKey publicKey = ks.getCertificate("aliasYouChose").getPublicKey();

公钥位于证书的“内部”,证书不仅仅是公钥。

此外,请务必注意,格式正确的PEM密钥每64个字符后应有一个“ \ n”。因此,例如,如果您试图在PHP的openSSL中使用“ \ n ----- END PUBLIC KEY -----”末尾(以及相应的开头),则可能不起作用。 / p>