-
-
Save viksingh/34f612344ceadbafcc99b8728a6a0841 to your computer and use it in GitHub Desktop.
Java Keystore Private Key Extractor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2011 Andrew Kroh | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
import java.io.BufferedInputStream; | |
import java.io.Console; | |
import java.io.FileInputStream; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.security.KeyStore; | |
import java.security.cert.Certificate; | |
import java.security.interfaces.RSAPrivateKey; | |
import java.util.Arrays; | |
import java.util.Enumeration; | |
// import <Base64 encoder class of choice> | |
/** | |
* Exports the certificates and private keys from a keystore. | |
* | |
* <p> | |
* To generate a new keystore with self-signed certificate run | |
* the following command or something similar and complete | |
* the prompts it asks for: | |
* | |
* <pre> | |
* keytool -genkey -alias selfsigned -keyalg RSA -keysize 2048 \ | |
* -validity 3650 -keystore keystore.jks | |
* | |
* Enter keystore password: <enter password here> | |
* Re-enter new password: <enter password here> | |
* What is your first and last name? | |
* [Unknown]: | |
* What is the name of your organizational unit? | |
* [Unknown]: | |
* What is the name of your organization? | |
* [Unknown]: | |
* What is the name of your City or Locality? | |
* [Unknown]: | |
* What is the name of your State or Province? | |
* [Unknown]: | |
* What is the two-letter country code for this unit? | |
* [Unknown]: | |
* Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct? | |
* [no]: yes | |
* | |
* Enter key password for <selfsigned> | |
* (RETURN if same as keystore password): <use the same password> | |
* </pre> | |
* | |
* @author Andrew Kroh | |
*/ | |
public class KeyExtractor | |
{ | |
public static String toBase64KeyString(String label, byte[] bytes) | |
{ | |
String base64 = Base64.encodeToString(bytes, true); | |
StringBuilder sb = new StringBuilder(); | |
sb.append("-----BEGIN " + label + "-----\n"); | |
sb.append(base64 + "\n"); | |
sb.append("-----END " + label + "-----"); | |
return sb.toString(); | |
} | |
public static String toJavaVariableString(String variable, byte[] encoded) | |
{ | |
String base64 = Base64.encodeToString(encoded, true); | |
String[] lines = base64.split("\\n"); | |
StringBuilder sb = new StringBuilder(); | |
sb.append("private static final String " + variable + " = \n"); | |
if (lines.length > 1) | |
{ | |
int i = 0; | |
for (i = 0 ; i < lines.length - 1; i++) | |
{ | |
String line = lines[i]; | |
line = line.replaceAll("\\r", "").replaceAll("\\n", ""); | |
sb.append(" \"" + line + "\" +\n"); | |
} | |
sb.append(" \"" + lines[i] + "\";"); | |
} | |
return sb.toString(); | |
} | |
private static char[] readPassword() throws IOException | |
{ | |
char[] password = new char[1024]; | |
int charCounter = 0; | |
int input = 0; | |
while((input = System.in.read()) != -1) | |
{ | |
if (input == '\r' || input == '\n') | |
{ | |
break; | |
} | |
else | |
{ | |
password[charCounter++] = (char)input; | |
} | |
} | |
char[] rtn = new char[charCounter]; | |
System.arraycopy(password, 0, rtn, 0, charCounter); | |
Arrays.fill(password, ' '); | |
return rtn; | |
} | |
public static void main(String[] args) throws Exception | |
{ | |
if (args.length != 1) | |
{ | |
StringBuffer sb = new StringBuffer(); | |
sb.append("Usage: java class [keystore file]\n"); | |
System.out.println(sb.toString()); | |
System.exit(1); | |
} | |
// Read the keystore file: | |
InputStream inputStream = null; | |
try | |
{ | |
String filename = args[0]; | |
inputStream = new BufferedInputStream(new FileInputStream(filename)); | |
} | |
catch (FileNotFoundException e) | |
{ | |
System.out.println("Unable to open keystore."); | |
System.exit(1); | |
} | |
// Get the keystore password: | |
Console console = System.console(); | |
char[] password = null; | |
if (console != null) | |
{ | |
password = console.readPassword("%s", "Keystore Password: "); | |
} | |
else | |
{ | |
System.out.println("Warning: password will be echoed to display..."); | |
System.out.print("Keystore Password: "); | |
password = readPassword(); | |
} | |
// Load the keystore: | |
KeyStore keyStore = KeyStore.getInstance("JKS"); | |
keyStore.load(inputStream, password); | |
// Enumerate the certificates and output the certs and private keys: | |
Enumeration<String> aliases = keyStore.aliases(); | |
while(aliases.hasMoreElements()) | |
{ | |
String alias = aliases.nextElement(); | |
Certificate cert = keyStore.getCertificate(alias); | |
RSAPrivateKey privateKey = (RSAPrivateKey)keyStore.getKey(alias, password); | |
System.out.println("-----BEGIN ALIAS " + alias + "-----"); | |
// Certificate contents: | |
System.out.println(cert); | |
System.out.println(); | |
// Base 64 encoded certificate: | |
System.out.println(toBase64KeyString("CERTIFICATE", cert.getEncoded())); | |
System.out.println(); | |
// Base 64 encoded private key: | |
if (privateKey != null) | |
{ | |
byte[] privateKeyByteArray = privateKey.getEncoded(); | |
System.out.println(toBase64KeyString("PRIVATE KEY", privateKeyByteArray)); | |
System.out.println(); | |
byte[] privateKeyExponentByteArray = privateKey.getPrivateExponent().toByteArray(); | |
System.out.println(toBase64KeyString("PRIVATE EXPONENT", privateKeyExponentByteArray)); | |
System.out.println(); | |
} | |
// Base 64 encoded certificate: | |
System.out.println(toJavaVariableString("CERT", cert.getEncoded())); | |
System.out.println(); | |
// Base 64 encoded certificate: | |
if (privateKey != null) | |
{ | |
byte[] privateKeyByteArray = privateKey.getEncoded(); | |
System.out.println(toJavaVariableString("PRIVATE KEY", privateKeyByteArray)); | |
System.out.println(); | |
byte[] privateKeyExponentByteArray = privateKey.getPrivateExponent().toByteArray(); | |
System.out.println(toJavaVariableString("PRIVATE_EXPONENT", privateKeyExponentByteArray)); | |
System.out.println(); | |
} | |
System.out.println("-----END ALIAS " + alias + "-----"); | |
System.out.println(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment