● 算法特点
对于此类加密算法的实现有 RSA,ECC等,也就是说 对称加密,消息摘要以及非对称加密 是一些算法思想,基于思想才有的实现。那么非对称加密的算法实现就是RSA和ECC等。
在JDK中当然也为RSA等算法提供了实现
public class RSATest {
static {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
KeyPair keyPair = keyPairGenerator.generateKeyPair();//密钥对
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String pub = new String(Base64.getEncoder().encodeToString(publicKey.getEncoded()));
String pri = new String(Base64.getEncoder().encodeToString(privateKey.getEncoded()));
System.out.println("公钥:" + pub);
System.out.println("私钥:" + pri);
}catch (Exception e){
e.printStackTrace();
}
}
@Test
public void testKeyPari() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
System.out.println(Base64.getEncoder().encodeToString(publicKey.getEncoded()));
System.out.println("===");
System.out.println(Base64.getEncoder().encodeToString(privateKey.getEncoded()));
String source = "Ja";
System.out.println("加密后的密文:");
String miwen = rsaEncode(source, publicKey);
System.out.println(miwen);
System.out.println("解密后的明文:");
System.out.println(rsaDecode(miwen,privateKey));
}
private String rsaEncode(String source, Key key) throws Exception{
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(1,key);
byte[] bytes = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(bytes);
}
//RSA算法解密
private String rsaDecode(String source, Key key) throws Exception{
Cipher rsa = Cipher.getInstance("RSA");
rsa.init(2,key);
byte[] bytes = rsa.doFinal(Base64.getDecoder().decode(source.getBytes(StandardCharsets.UTF_8)));
return new String(bytes);
}
}
生成密钥对主要是 KeyPairGenerator 这个对象,可以生成RSA算法需要的公钥和私钥。最后还是需要Cipher 这个对象去实现加解密,同时还要注意,Cipher加解密的结果不一定是一堆完整的字符串,所以往往还需要结合Base64或者Base58等可读性算法来存储或者传输。
* 数字签名
public class DigestSign {
@Test
public void testSign() throws Exception {
//生成密钥对
KeyPairGenerator pairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = pairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic(); //公钥
PrivateKey privateKey = keyPair.getPrivate(); //私钥
String pub = Base64.encode(publicKey.getEncoded());
String pri = Base64.encode(privateKey.getEncoded());
System.out.println("公钥:" + pub);
System.out.println("私钥:" + pri);
String content = "南山老妖";
String hashRule = "sha256withrsa";//消息摘要算法
//获取签名
String sign = getSign(privateKey,content,hashRule);
System.out.println("消息的签名是:" + sign);
//接收方验证消息与签名是否匹配
boolean verify = verifySign(publicKey,content,hashRule,sign);
System.out.println("验证签名:" + verify);
}
private boolean verifySign(PublicKey publicKey, String content, String hashRule, String sign) throws Exception {
Signature signature = Signature.getInstance(hashRule);
signature.initVerify(publicKey);
signature.update(content.getBytes(StandardCharsets.UTF_8));
//对比签名
boolean verify = signature.verify(Base64.decode(sign));
return verify;
}
private String getSign(PrivateKey privateKey, String content, String hashRule) throws Exception {
//获取消息签名算法
Signature signature = Signature.getInstance(hashRule);
//设置公钥
signature.initSign(privateKey);
//设置消息摘要泛
signature.update(content.getBytes());
byte[] sign = signature.sign();
return Base64.encode(sign);
}
}
数字签名的过程和RSA的加密解密还有有些相似的,只不过就是在验证数字签名的时候这里要注意,一定是将原文和Base64转码后的签名字节数组去比较。