RSA加密算法
2021/7/9 22:08:44
本文主要是介绍RSA加密算法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
RSA加密算法
RSA是非对称加密算法,非对称加密算法指的是加密和解密使用不同的密钥,除了加解密的作用,还有“签名”的作用。通常来说非对称加密比对称加密要耗时间。
- 加解密
用公钥加密,用私钥解密;这样可以确保数据不被破解,因为公钥加密后,只有私钥才能解密,所以可以保证数据不被破解。; - 签名
用私钥生成签名,用公钥验证签名;这样可以确定发送者的是不是目标身份。
生成密钥对
无论是加解密还是签名都需要使用密钥对。
public static KeyPair genKeyPair() throws NoSuchAlgorithmException { // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); // 初始化密钥对生成器,密钥大小为96-1024位 keyPairGen.initialize(1024,new SecureRandom()); // 生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); return keyPair; }
加解密例子
本例子的代码很大程度参考了RSA加密与解密(Java实现)
加解密
用公钥加密
public static String encrypt( String str, Key publicKey ) throws Exception{ //RSA加密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8"))); return outStr; }
用私钥解密
public static String decrypt(String str, Key privateKey) throws Exception{ //64位解码加密后的字符串 byte[] inputByte = Base64.getDecoder().decode(str.getBytes("UTF-8")); //RSA解密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); String outStr = new String(cipher.doFinal(inputByte)); return outStr; }
public static void main(String[] args) throws Exception { //加密字符串 String message = "df723820"; KeyPair keyPair = genKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); // 得到私钥 PublicKey publicKey = keyPair.getPublic(); // 得到公钥 String messageEn = encrypt(message,publicKey); log.info("加密前:{}",message); log.info("加密后:{}",messageEn); String messageDe = decrypt(messageEn,privateKey); log.info("还原后的字符串为:{}" , messageDe); }
签名例子
本例子主要参考Java 实现RSA签名和加密
私钥生成签名
public static String sign(String plainText, PrivateKey privateKey) throws Exception { Signature privateSignature = Signature.getInstance("SHA256withRSA"); privateSignature.initSign(privateKey); privateSignature.update(plainText.getBytes(StandardCharsets.UTF_8)); byte[] signature = privateSignature.sign(); return Base64.getEncoder().encodeToString(signature); }
公钥验证签名
public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception { Signature publicSignature = Signature.getInstance("SHA256withRSA"); publicSignature.initVerify(publicKey); publicSignature.update(plainText.getBytes(StandardCharsets.UTF_8)); byte[] signatureBytes = Base64.getDecoder().decode(signature); return publicSignature.verify(signatureBytes); }
完整代码
public static void main(String[] args) throws Exception { String sign = sign(message, keyPair.getPrivate()); boolean verify = verify(message,sign, keyPair.getPublic()); log.info("校验通过:{}",verify); }
可以看到,签名的步骤与加解密步骤很像。但这里用的算法是SHA256withRSA
,它包含SHA256和RSA。因为直接对数据做签名运算量太大,所以一般先根据数据生成信息摘要,然后对信息摘要做签名以减小运算量;SHA代表Secure Hash Algorithm,SHA256是个散列函数,它对数据做信息摘要,然后RSA对摘要做签名。
HMAC、MD5
通常我们会想到,RSA与HMAC、MD5、SHA有什么区别,其实区别还是很明显的
- HMAC
- HMAC是基于密钥和散列函数对数据进行信息摘要,通常通信双方共享密钥;可以选择指定的散列函数,比如MD5、SHA256,分别称为HMAC-MD5、HmacSHA256、;HMAC可以验证数据完整性校验、身份认证功能。
- MD5、SHA
- MD5、SHA仅是散列函数,实现了信息摘要作用,可以用于验证数据完整性,但无法证明身份。
常见问题
- 一般都是,公钥加密,私钥解密;那私钥加密,公钥解密,可以吗?
- 可以的,根据RSA的推导公式,公钥私钥是可以互相加密解密;上边的代码,互换一下key试一下就可以了,是可以的。
- 将私钥公开,公钥保密,可以吗?
- 不可以。这很容易被破解,因为私钥长、公钥短(在线生成器查看),hacker眼中“私钥”其实是“公钥”,公钥值短,很容易被穷举出来;这点可参考RSA的公钥和私钥到底哪个才是用来加密和哪个用来解密?
联系实际
如果以上都懂了,那么也就懂得了,微信支付文档中的这张图
商户请求微信时,用商户私钥产生签名,微信用商户公钥验证签名;响应信息中,用平台私钥产生签名,商户用平台公钥验证签名;
微信请求商户时,用微信私钥产生签名,商户用微信公钥验证签名;响应信息中,用商户私钥产生签名,平台用商户公钥验证签名;
上述私钥、公钥就是RSA的私钥、公钥。商户公钥、平台公钥分别存在商户证书、平台证书中。
注意这里的证书与https中的证书不是一回事,但相似,证书就是公钥的载体,证书上有证书签发机构的签名,可以防止中间人攻击,可以证明公钥的合法性。
APIV3 key就是AES算法的密钥,微信与商户共享;
这篇关于RSA加密算法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南