上一篇中主要讲解了加密的理论知识,这篇来上代码。
签名和验签
通过信息摘要算法和非对称加密,可以实现信息的防伪造,防篡改,通过我们的私钥来签名消息,接收方就能通过我们的公钥来校验该消息是否是我们发送的。
/**
* 获取证书库
*/
public static KeyStore getKeyStore(InputStream keyStoreInputStream, String keyStorePassword, String keyStoreType) throws Exception {
return getKeyStore(keyStoreInputStream, keyStorePassword, keyStoreType);
}
public static KeyStore getKeyStore(InputStream keyStoreInputStream, String keyStorePassword, String keyStoreType, String provider) throws Exception {
KeyStore keyStore;
if (StringUtils.isNotBlank(provider)) {
keyStore = KeyStore.getInstance(keyStoreType, provider);
} else {
keyStore = KeyStore.getInstance(keyStoreType);
}
keyStore.load(keyStoreInputStream, keyStorePassword.toCharArray());
IoUtil.close(keyStoreInputStream);
return keyStore;
}
/**
* 从证书库中获取公钥
*/
public static PublicKey getPublicKeyFromKeyStore(KeyStore keyStore, String alias) throws Exception {
Certificate certificate = keyStore.getCertificate(alias);
return certificate.getPublicKey();
}
/**
* 从证书库获取私钥
*/
public static PrivateKey getPrivateKeyFromKeyStore(KeyStore keyStore, String alias, String password) throws Exception {
return (PrivateKey) keyStore.getKey(alias, password.toCharArray());
}
/**
* 签名
*/
public static byte[] sign(byte[] message, PrivateKey privateKey, String algorithm) throws Exception {
Signature signature;
signature = Signature.getInstance(algorithm);
signature.initSign(privateKey);
signature.update(message);
return signature.sign();
}
/**
* 验签
*/
public static boolean verify(byte[] message, byte[] signMessage, PublicKey publicKey, String algorithm) throws Exception {
Signature signature;
boolean verifyResult;
signature = Signature.getInstance(algorithm);
signature.initVerify(publicKey);
signature.update(message);
verifyResult = signature.verify(signMessage);
return verifyResult;
}
然后写个单元测试来验证下
@Test
public void testVerify() throws Exception {
FileInputStream fis = new FileInputStream(new File("d:/keys/testkeystore.keystore"));
//获取证书库
KeyStore keyStore = getKeyStore(fis, "mypassword", "JKS");
//获取私钥
PrivateKey privateKey = getPrivateKeyFromKeyStore(keyStore, "mykeystore", "mypassword");
//摘要算法用SHA1,非对称加密算法用RSA进行签名
byte[] signMessage = sign(CONTENT.getBytes(), privateKey, "SHA1withRSA");
//获取公钥
PublicKey publicKey = getPublicKeyFromKeyStore(keyStore, "mykeystore");
//进行验签
boolean verify = verify(CONTENT.getBytes(), signMessage, publicKey, "SHA1withRSA");
System.out.println(verify);
}
加密和解密
/**
* 使用私钥加密
*/
public static byte[] encodeByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception {
// 对数据加密,加密算法由创建秘钥时指定,也可以自己指定,一般用RSA
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 使用公钥解密
*/
public static byte[] decodeByPublicKey(byte[] data, PublicKey publicKey)
throws Exception {
// 对数据加密
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 公钥加密
*/
public static byte[] encodeByPublicKey(byte[] data, PublicKey publicKey)
throws Exception {
// 对数据加密
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 私钥解密
*/
public static byte[] decodeByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception {
// 对数据加密
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
单元测试
public static String CONTENT = "寥落古行宫,宫花寂寞红。白头宫女在,闲坐说玄宗";
@Test
public void testDecode() throws Exception {
FileInputStream fis = new FileInputStream(new File("d:/keys/testkeystore.keystore"));
KeyStore keyStore = getKeyStore(fis, "mypassword", "JKS");
PrivateKey privateKey = getPrivateKeyFromKeyStore(keyStore, "mykeystore", "mypassword");
PublicKey publicKey = getPublicKeyFromKeyStore(keyStore, "mykeystore");
//加密
byte[] encode = encodeByPrivateKey(CONTENT.getBytes(), privateKey);
//解密
byte[] message = decodeByPublicKey(encode, publicKey);
System.out.println(new String(message));
}
|