1.RAS简介
RSA加密是非对称加密,由一对秘钥进行完成加密解密,分别称为公钥和私钥,公钥加密,私钥解密,RSA可以完成加密和签名;
2.加密与签名的区别
加密是为了防止信息被泄露,签名是为了防止信息被篡改;
3.RSA加密过程
假如B要发消息给A,首先A在本地生产一对秘钥,公钥和私钥,并将公钥发送给B,B使用公钥对消息进行加密,然后传输给A,A接收到消息后在本地使用私钥解密;
缺点:这种加密过程保证了消息不被泄露,但是避免不了消息被篡改,假如B发送给A的消息被黑客劫持,他通过公钥,自己伪造一条消息,通过公钥加密,发送给A,这样A收到的消息就不是B发送给A的了;
4.RSA签名过程
A发送消息给B的时候,用私钥对消息进行加签,将加签后的消息与消息本体发给B,B使用公钥进行验签,如果验签出来的内容和消息本身一致,证明消息才是A回复的;
这样也会有一个问题,当黑客获取到消息后,可以使用公钥验签,来查看消息,并不能防止消息泄露;
总结:公钥加密、私钥解密、私钥签名、公钥验签。
5.RSA签名/验签实例
@Test
void contextLoads() throws Exception {
/**
* 1、生成一对RSA密钥。
* */
// 随机生成一对 RAS 密钥(包含公钥和私钥)
KeyPair keyPair = generateKeyPair();
// 获取 公钥 和 私钥
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
/**
* 2.生成原始数据
* */
//原始数据 JSON字符串
String data = "{" +
"\"notifyTime\": \"20210519155300\", " +
"\"notifyType\": \"TEST\", " +
"\"version\": \"1.0.0TEST\"" +
"}";
/**
* 3.私钥签名:对数据进行签名,计算签名结果。
* */
// 根据指定算法获取签名工具
Signature sign = Signature.getInstance("Sha1WithRSA");
// 用私钥初始化签名工具
sign.initSign(privateKey);
// 添加要签名的数据
sign.update(data.getBytes());
//计算签名结果(签名信息)
byte[] signInfo = sign.sign();
// 输出签名结果的 Base64 字符串
System.out.println(new BASE64Encoder().encode(signInfo));
/**
* 4.公钥验签:用公钥校验数据是否被改变
* */
// 根据指定算法获取签名工具
sign = Signature.getInstance("Sha1WithRSA");
// 用公钥初始化签名工具
sign.initVerify(publicKey);
// 添加要校验的数据
sign.update(data.getBytes());
// 校验数据的签名信息是否正确,
// 如果返回 true, 说明该数据的签名信息来自该公钥对应的私钥,
// 同一个私钥的签名, 数据和签名信息一一对应, 只要其中有一点修改, 则用公钥无法校验通过,
// 因此可以用私钥签名, 然后用公钥来校验数据的完整性与签名者(所有者)
boolean verify = sign.verify(signInfo);
System.out.println(verify);
/**
* 测试数据被修改后的验签是否还有效
* */
data = "{" +
"\"notifyTime\": \"20210519155300\", " +
"\"notifyType\": \"TEST11\", " +
"\"version\": \"1.0.0TESTTTT\"" +
"}";
sign = Signature.getInstance("Sha1WithRSA");
sign.initVerify(publicKey);
sign.update(data.getBytes());
verify = sign.verify(signInfo);
System.out.println(verify);
}
/**
* 随机生成 RSA 密钥对(包含公钥和私钥)
*/
private static KeyPair generateKeyPair() throws Exception {
// 获取指定算法的密钥对生成器
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器(指定密钥长度, 使用默认的安全随机数源)
gen.initialize(2048);
// 随机生成一对密钥(包含公钥和私钥)
return gen.generateKeyPair();
}
过程中如果有小伙伴遇到问题或者有好的见解可以及时联系