1、公钥加密,私钥解密
2、私钥加密,公钥解密
3、私钥签名,公钥验证签名
http://www.oschina.net/code/snippet_121944_15275
package com.apdplat.platform.util;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author ysc
*/
public class PKIUtils {
private static final Logger log = LoggerFactory.getLogger(PKIUtils.class);
private PKIUtils(){}
/**
*
* 用证书的私钥签名
* @param in 证书库
* @param storePassword 证书库密码
* @param keyPassword 证书密码
* @param key 钥别名
* @param data 待签名数据
* @return 签名
*/
public static byte[] signature(InputStream in, String storePassword, String keyPassword, String key, byte[] data) {
try {
// 获取证书私钥
PrivateKey privateKey = getPrivateKey(in, storePassword, keyPassword, key);
Signature signet = Signature.getInstance("MD5withRSA");
signet.initSign(privateKey);
signet.update(data);
byte[] signed = signet.sign(); // 对信息的数字签名
return signed;
} catch (Exception ex) {
log.error("签名失败",ex);
}
return null;
}
/**
* 用证书的公钥验证签名
* @param in 证书
* @param data 原始数据
* @param signatureData 对原始数据的签名
* @return
*/
public static boolean verifySignature(InputStream in, byte[] data, byte[] signatureData){
try {
// 获取证书公钥
PublicKey key = getPublicKey(in);
Signature signet = Signature.getInstance("MD5withRSA");
signet.initVerify(key);
signet.update(data);
boolean result=signet.verify(signatureData);
return result;
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException ex) {
log.error("验证签名失败",ex);
}
return false;
}
/**
* 获取证书公钥
* @param in 证书
* @return 公钥
*/
private static PublicKey getPublicKey(InputStream in) {
try {
// 用证书的公钥加密
CertificateFactory factory = CertificateFactory.getInstance("X.509");
Certificate cert = factory.generateCertificate(in);
// 得到证书文件携带的公钥
PublicKey key = cert.getPublicKey();
return key;
} catch (CertificateException ex) {
log.error("获取证书公钥失败",ex);
}
return null;
}
/**
* 加密数据
* @param key 公钥或私钥
* @param data 待加密数据
* @return
*/
public static byte[] encrypt(Key key, byte[] data) {
try {
// 定义算法:RSA
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
// 正式执行加密操作
byte encryptedData[] = cipher.doFinal(data);
return encryptedData;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
log.error("加密数据失败",ex);
}
return null;
}
/**
* 用证书的公钥加密
* @param in 证书
* @param data 待加密数据
* @return 密文
*/
public static byte[] encryptWithPublicKey(InputStream in, byte[] data) {
try {
// 获取证书公钥
PublicKey key = getPublicKey(in);
byte encryptedData[] = encrypt(key,data);
return encryptedData;
} catch (Exception ex) {
log.error("用证书的公钥加密失败",ex);
}
return null;
}
/**
* 用证书的私钥加密
* @param in 证书库
* @param storePassword 证书库密码
* @param keyPassword 证书密码
* @param key 钥别名
* @param data 待加密数据
* @return 密文
*/
public static byte[] encryptWithPrivateKey(InputStream in, String storePassword, String keyPassword, String key, byte[] data) {
try {
// 获取证书私钥
PrivateKey privateKey = getPrivateKey(in, storePassword, keyPassword, key);
byte encryptedData[] = encrypt(privateKey,data);
return encryptedData;
} catch (Exception ex) {
log.error("用证书的私钥加密失败",ex);
}
return null;
}
/**
* 获取证书私钥
* @param in 证书库
* @param storePassword 证书库密码
* @param keyPassword 证书密码
* @param key 钥别名
* @return 私钥
*/
private static PrivateKey getPrivateKey(InputStream in, String storePassword, String keyPassword, String key) {
try {
// 加载证书库
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(in, storePassword.toCharArray());
// 获取证书私钥
PrivateKey privateKey = (PrivateKey) ks.getKey(key, keyPassword.toCharArray());
return privateKey;
} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException ex) {
log.error("获取证书私钥失败",ex);
}
return null;
}
/**
* 解密数据
* @param key 公钥或私钥
* @param data 待解密数据
* @return 明文
*/
public static byte[] decrypt(Key key, byte[] data) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
// 解密后的数据
byte[] result = cipher.doFinal(data);
return result;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
log.error("解密数据失败",ex);
}
return null;
}
/**
*
* 用证书的私钥解密
* @param in 证书库
* @param storePassword 证书库密码
* @param keyPassword 证书密码
* @param key 钥别名
* @param data 待解密数据
* @return 明文
*/
public static byte[] decryptWithPrivateKey(InputStream in, String storePassword, String keyPassword, String key, byte[] data) {
try {
// 获取证书私钥
PrivateKey privateKey = getPrivateKey(in, storePassword, keyPassword, key);
// 解密后的数据
byte[] result = decrypt(privateKey,data);
return result;
} catch (Exception ex) {
log.error("用证书的私钥解密失败",ex);
}
return null;
}
/**
*
* 用证书的公钥解密
* @param in 证书
* @param data 待解密数据
* @return 明文
*/
public static byte[] decryptWithPublicKey(InputStream in, byte[] data) {
try {
// 获取证书公钥
PublicKey key = getPublicKey(in);
// 解密后的数据
byte[] result = decrypt(key,data);
return result;
} catch (Exception ex) {
log.error("用证书的公钥解密失败",ex);
}
return null;
}
}
package com.apdplat.platform.util;
import junit.framework.Assert;
import org.junit.Test;
/**
*
* @author ysc
*/
public class PKIUtilsTest {
//private String cert = "/com/apdplat/module/security/pki/apdplat_public.crt";
private String cert = "/com/apdplat/module/security/pki/apdplat.crt";
private String store = "/com/apdplat/module/security/pki/apdplat.keystore";
private String plainText = "apdplat应用级开发平台(杨尚川)";
@Test
public void testEncryptAndDecrypt1() {
//公钥加密
byte[] result = PKIUtils.encryptWithPublicKey(PKIUtilsTest.class.getResourceAsStream(cert), plainText.getBytes());
//私钥解密
result = PKIUtils.decryptWithPrivateKey(PKIUtilsTest.class.getResourceAsStream(store), "apdplat_core_module", "apdplat_core_module", "apdplat", result);
Assert.assertEquals(plainText, new String(result));
}
@Test
public void testEncryptAndDecrypt2() {
//私钥加密
byte[] result = PKIUtils.encryptWithPrivateKey(PKIUtilsTest.class.getResourceAsStream(store), "apdplat_core_module", "apdplat_core_module", "apdplat", plainText.getBytes());
//公钥解密
result = PKIUtils.decryptWithPublicKey(PKIUtilsTest.class.getResourceAsStream(cert), result);
Assert.assertEquals(plainText, new String(result));
}
@Test
public void testSignatureAndVerifySignature() {
//私钥签名
byte[] signature = PKIUtils.signature(PKIUtilsTest.class.getResourceAsStream(store), "apdplat_core_module", "apdplat_core_module", "apdplat", plainText.getBytes());
//公钥验证签名
boolean correct=PKIUtils.verifySignature(PKIUtilsTest.class.getResourceAsStream(cert),plainText.getBytes(),signature);
Assert.assertTrue(correct);
}
}