jks证书处理
需要先将jks证书转为pem在进行导入
1.查询jks证书别名
keytool -list -keystore ***.jks
其中alias-cert为证书别名
2.导出pem证书
keytool -exportcert -alias <别名> -keystore ***.jks -rfc -file ***.pem
3.到jar目录下完成证书导入
cd $JAVA_HOME/jre/lib/security/
# 导入证书 密码默认为 changeit
keytool -import -alias <别名> -file ***.pem -keystore cacerts
# 查看证书库中的证书
keytool -list -keystore cacerts
证书库替换法
可以直接将jks证书改名为cacerts 替换 $JAVA_HOME/jre/lib/security/下的 cacerts
!注意
需要注意执行时候的keytool是否与当前版本jdk一致,最好执行的keytool从当前要改的jdk路径获取,否则可能出现以下两个问题;
高版本keytool 访问低版本cacerts keytool error: gnu.javax.crypto.keyring.MalformedKeyringException: incorrect magic
低版本keytool 访问高版本cacerts keytool error: java.io.IOException: Invalid keystore format
cacerts密码为空处理
如果cacerts的密码不巧是null 或者"" 则可能陷入死循环中
修改密码会要求输入密码,所以实际上无法进行密码输入
目前发现一种解决办法是通过java代码对证书库密码进行调整
附 java1.6可用的版本代码
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TrustStorePasswordChanger {
private static final String CACERTIFICATES_PATH = "/lib/security/cacerts";
private static final String DEFAULT_CACERTIFICATES_PASSWORD = null;
private static final String NEW_CACERTIFICATES_PASSWORD = "changeit";
private static final String TRUST_STORE_FILE_PATH =
System.getProperty("java.home")
+ CACERTIFICATES_PATH.replace('/', File.separatorChar);
private static final String OUTPUT_FILE_PATH = TRUST_STORE_FILE_PATH;
/**
* Main method for entry point.
*
* @param args
*/
public static void main(String[] args) {
InputStream fileInputStream =
getInputStreamFromFilePath(TRUST_STORE_FILE_PATH);
byte[] keyBytes;
try {
keyBytes = updateTrustStorePass(fileInputStream,
DEFAULT_CACERTIFICATES_PASSWORD,
NEW_CACERTIFICATES_PASSWORD);
ByteArrayInputStream byteArrayInputStream =
new ByteArrayInputStream(keyBytes);
System.out.println(OUTPUT_FILE_PATH + File.pathSeparator);
FileOutputStream output = new FileOutputStream(new File(OUTPUT_FILE_PATH + File.pathSeparator + "cards"));
int in = byteArrayInputStream.read();
while (in != -1) {
output.write(in);
in = byteArrayInputStream.read();
}
} catch (FileNotFoundException e) {
Logger.getLogger(TrustStorePasswordChanger.class.getName())
.log(Level.WARNING, null, e);
} catch (IOException e) {
Logger.getLogger(TrustStorePasswordChanger.class.getName())
.log(Level.WARNING, null, e);
System.out.println(
"Expected java.security.UnrecoverableKeyException:"
+ " Password verification failed.");
}
}
/**
* This method takes cacerts input and updates trustore password
*
* @param oldPassword
* @param newPassword
* @return trust store object in bytes * @throws Exception
*/
private static byte[] updateTrustStorePass(
InputStream certificateInputStream,
String oldPassword,
String newPassword) throws FileNotFoundException {
byte[] trustStore = new byte[1024];
KeyStore inboundCertificate;
try {
inboundCertificate = KeyStore.getInstance(KeyStore.getDefaultType());
char[] oldPasswordPhrase = null;
if(oldPassword != null){
oldPasswordPhrase = oldPassword.toCharArray();
}
char[] newPasswordhrase = newPassword.toCharArray();
//主要是这一句,需要调整,因为代码可能是空字符串 也可能是null
inboundCertificate.load(certificateInputStream, oldPasswordPhrase);
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(inboundCertificate.size());
inboundCertificate.store(
byteArrayOutputStream, newPasswordhrase);
trustStore = byteArrayOutputStream.toByteArray();
} catch (KeyStoreException e) {
Logger.getLogger(TrustStorePasswordChanger.class.getName())
.log(Level.WARNING, null, e);
} catch (CertificateException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
return trustStore;
}
private static InputStream getInputStreamFromFilePath(String filePath) {
InputStream trustStoreInputStream = null;
try {
trustStoreInputStream = new FileInputStream(new File(filePath));
} catch (FileNotFoundException e) {
Logger.getLogger(TrustStorePasswordChanger.class.getName())
.log(Level.WARNING, null, e);
}
return trustStoreInputStream;
}
}