RSA非对称加密
- RSA非对称加密作为一种密钥的保密方法.常被使用在Web项目中
- 基本运作流程:服务器初始化生成一把公钥和一把私钥,公钥仅用作加密,私钥仅用作解密(可解密出原文)
- 页面提交信息之前,向服务器请求公钥,随后用公钥加密字符为base64格式,使得数据传输过程即使被截取也无法还原出明文.
- 服务器接收到base64字符后,使用私钥解密出原文.
- 非对称加密比MD5等对称加密更安全的是,只要钥匙不同每次生成的密文也不同,就无法被截取并直接提交攻击.
1.Maven依赖
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.52</version>
</dependency>
2.生成公钥私钥的util
package com.deepblue.util;
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
public class RSAUtils {
private static final KeyPair keyPair = initKey();
//生成公钥私钥,公钥发回页面
private static KeyPair initKey() {
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
SecureRandom random = new SecureRandom();
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
generator.initialize(1024, random);
return generator.generateKeyPair();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取public key,调用此方法返回64进制公钥
*
* @return
*/
public static String getPublicKey() {
//获取随机生成的公钥私钥
PublicKey aPublic = keyPair.getPublic();
//转化公钥私钥为64位编码
return new BASE64Encoder().encode(aPublic.getEncoded());
}
/**
* 解密
*
* @param string
* @return
*/
public static String decryptBase64(String string) {
return new String(decrypt(Base64.decodeBase64(string)));
}
private static byte[] decrypt(byte[] string) {
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
RSAPrivateKey pbk = (RSAPrivateKey) keyPair.getPrivate();
cipher.init(Cipher.DECRYPT_MODE, pbk);
byte[] plainText = cipher.doFinal(string);
return plainText;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//测试加密解密
public static void main(String[] args) throws Exception {
//获取随机生成的公钥私钥
PublicKey aPublic = keyPair.getPublic();
PrivateKey aPrivate = keyPair.getPrivate();
//转化公钥私钥为64位编码
String encode = new BASE64Encoder().encode(aPublic.getEncoded());
String encode1 = new BASE64Encoder().encode(aPrivate.getEncoded());
System.out.println("公钥:" + encode);
System.out.println("私钥:" + encode1);
//把明文转为byte数组
byte[] s = "呵呵呵".getBytes();
Cipher cipher = Cipher.getInstance("RSA");
//加密
cipher.init(Cipher.ENCRYPT_MODE, aPublic);
byte[] enBytes = cipher.doFinal(s);
System.out.println("加密后的密文:" + new BASE64Encoder().encode(enBytes));
//解密
byte[] decrypt = decrypt(enBytes);
System.out.println("解密后的明文:"+new String(decrypt));
}
}
3.页面调用公钥加密(使用的js工具为jsencrypt.js)
//公钥要从服务器异步获取
var publicKey = "";
var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
// 加密
console.log(encrypt.encrypt("hello"));
4.使用方法
运行项目,从上述util中获取公钥,通过异步传输至页面端,页面端调用jsencrypt.js中的encrypt方法将字符加密成base64格式,提交至服务器
服务器调用上述util中的解密方法(自动调用私钥)来解密出原文.