Java加密-密钥的保存与获取
2020-08-08 本文已影响0人
张明学
密钥一般存放在密钥文件中,常见的密钥文件有:jks、pfx、cer。jks是Java的keytools证书工具支持的证书私钥格式,pfx是微软支持的私钥格式,cer是证书的公钥。
从cer文件中获取公钥
/**
* 从cer文件中获取公钥
*
*/
@Test
public PublicKey getPublicKey(String certPath) throws CertificateException, IOException {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Certificate certificate = certificateFactory.generateCertificate(new FileInputStream(certPath));
return certificate.getPublicKey();
}
pfx文件中提取私钥
/**
* 从pfx文件中提取私钥
*
*/
public PrivateKey getPrivateKey(String argPfxFilePath, String argPfxPassword) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream(argPfxFilePath);
keyStore.load(fis, argPfxPassword.toCharArray());
fis.close();
Enumeration<String> enumeration = keyStore.aliases();
String keyAlias = null;
if (enumeration.hasMoreElements()) {
keyAlias = enumeration.nextElement();
}
return (PrivateKey) keyStore.getKey(keyAlias, argPfxPassword.toCharArray());
}
自己通过文件保存公私钥
将公私钥byte直接保存在文件中
/**
* 提取公钥的比特编码经过Base64转换后保存到文件,注意公钥的比特编码是X.509格式
*
* @param publicKey
* @param outPutFile
*/
public void savePublicKey2File(PublicKey publicKey, File outPutFile) throws Exception {
byte[] pbks = Base64.getEncoder().encode(publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream(outPutFile);
fos.write(pbks);
fos.flush();
fos.close();
}
/**
* 提取私钥的比特编码经过Base64转换后保存到文件,注意私钥的比特编码是pkcs8格式
*
* @param privateKey
* @param outPutFile
*/
public void savePrivateKey2File(PrivateKey privateKey, File outPutFile) throws Exception {
byte[] prks = Base64.getEncoder().encode(privateKey.getEncoded());
FileOutputStream fos = new FileOutputStream(outPutFile);
fos.write(prks);
fos.flush();
fos.close();
}
从文件读取公私钥
/**
* 从文件中获取公钥(公钥的比特编码是X.509格式)
*
* @param certPath
* @return
* @throws Exception
*/
public PublicKey getPublicKeyByFile(String certPath) throws Exception {
FileInputStream fis = new FileInputStream(certPath);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
byte[] pbks = Base64.getDecoder().decode(bos.toByteArray());
X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(pbks);
PublicKey newPbk = KeyFactory.getInstance("RSA").generatePublic(encodedKeySpec);
return newPbk;
}
/**
* 从文件中获取公钥(私钥的比特编码是pkcs8格式)
*
* @param keyPath
* @return
* @throws Exception
*/
public PrivateKey getPrivateKeyByFile(String keyPath) throws Exception {
FileInputStream fis = new FileInputStream(keyPath);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
byte[] prks = Base64.getDecoder().decode(bos.toByteArray());
/**/
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(prks);
PrivateKey newPrk = KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec);
return newPrk;
}
测试
@Test
public void testSaveKeyPair() throws Exception {
/**
* 随机生成秘钥对
*/
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
/**
* 使用原始私钥加密,重新生成的公钥解密
*/
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] bytes = cipher.doFinal("helloworld".getBytes());
System.out.println("原始公钥加密=" + Base64.getEncoder().encodeToString(bytes));
cipher.init(Cipher.DECRYPT_MODE, privateKey);
bytes = cipher.doFinal(bytes);
System.out.println("原始私钥解密=" + new String(bytes));
/**
* 从文件中提取公钥比特编码并恢复成公钥
*/
File privateKeyFile = new File("private_key");
this.savePrivateKey2File(privateKey, privateKeyFile);
File publicKeyFile = new File("public.key");
this.savePublicKey2File(publicKey, publicKeyFile);
cipher.init(Cipher.ENCRYPT_MODE, this.getPublicKeyByFile(publicKeyFile.getPath()));
bytes = cipher.doFinal("helloworld".getBytes());
System.out.println("从文件中获取公钥加密: " + Base64.getEncoder().encodeToString(bytes));
cipher.init(Cipher.DECRYPT_MODE, this.getPrivateKeyByFile(privateKeyFile.getPath()));
bytes = cipher.doFinal(bytes);
System.out.println("从文件中获取私钥解密: " + new String(bytes));
}
Java-加密篇
Java加解-RSA加解密
Java加密-Signature数据签名
Java加密-AES加解密
Java加密-密钥的保存与获取