Angular前端表单RSA加密,后端java解密
一、后端用Itelij IDEA
1、下载bcprov-jdk15on-1.56.jar这个文件,在项目根目录下新建文件夹lib,把下载的文件复制到lib文件夹中。该jar用于生成秘钥对。
2、在Itelij IDEA的菜单File-->Project Structure,然后选择Libraries,点击+号,再选择Java,如下图,将对应的bcprov-jdk15on-1.56.jar选入。


3、编写RSAUtils类,如下。
1 import java.security.*; 2 import java.security.interfaces.RSAPublicKey; 3 import javax.crypto.Cipher; 4 import org.apache.tomcat.util.codec.binary.Base64; 5 import org.springframework.stereotype.Service; 6 7 @Service 8 public class RSAUtils { 9 private static final KeyPair keyPair = initKey(); 10 private static KeyPair initKey() { 11 try { 12 Provider provider =new org.bouncycastle.jce.provider.BouncyCastleProvider(); 13 Security.addProvider(provider); 14 SecureRandom random = new SecureRandom(); 15 KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", provider); 16 generator.initialize(1024,random); 17 return generator.generateKeyPair(); 18 } catch(Exception e) { 19 throw new RuntimeException(e); 20 } 21 } 22 public static String generateBase64PublicKey() { 23 PublicKey publicKey = (RSAPublicKey)keyPair.getPublic(); 24 return new String(Base64.encodeBase64(publicKey.getEncoded())); 25 } 26 public static String decryptBase64(String string) { 27 return new String(decrypt(Base64.decodeBase64(string.getBytes()))); 28 29 } 30 private static byte[] decrypt(byte[] byteArray) { 31 try { 32 Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider(); 33 Security.addProvider(provider); 34 Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider); 35 PrivateKey privateKey = keyPair.getPrivate(); 36 cipher.init(Cipher.DECRYPT_MODE, privateKey); 37 byte[] plainText = cipher.doFinal(byteArray); 38 return plainText; 39 } catch(Exception e) { 40 throw new RuntimeException(e); 41 } 42 } 43 44 }
4、提供前端获取公钥的接口/getkey,代码如下:
@RequestMapping(value={"/getkey"},method = RequestMethod.GET)
public JSONObject getKey(HttpServletRequest request){
// 生成一个公钥
String publicKey = RSAUtils.generateBase64PublicKey();
JSONObject json=new JSONObject();
json.put("publickey",publicKey);
return json;
}
5、接收前端发送来的密文,并解密:
@RequestMapping(value = {"/login2"}, method = RequestMethod.PUT, produces = "application/json;charset=UTF-8")
public void login(@RequestBody Map<String,Object> user,HttpServletRequest request,HttpServletResponse response) throws Exception{
String username=(String) user.get("username");
String password=(String) user.get("password");
username=RSAUtils.decryptBase64(username);
password=RSAUtils.decryptBase64(password);
System.out.println(username);
}
二、前端Angular处理:
1、安装jsencrypt,命令行里输入npm install --save jsencrypt。
2、在ts文件中引入jsencrypt: import * as JsEncryptModule from 'jsencrypt'。
3、编写获取公钥和提交数据的方法,代码如下:
getkey():void{ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; this.http.get("/api/getkey",httpOptions).subscribe(res=>{ let key=res["publickey"]; let encrypt = new JsEncryptModule.JSEncrypt({}); //此处要加{},网上很多都没有写这个大括号,新版的jsencrypt会报错 encrypt.setPublicKey(key); // 公钥 var usn = encrypt.encrypt(this.validateForm.value.username); // 加密 var psw = encrypt.encrypt(this.validateForm.value.password); // 加密 var formdata={"username": usn,"password": psw}; this.submit(formdata); }) } submit(data:any): void{ const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; this.http.put("/api/login2",data,httpOptions).subscribe(response => { //写入其他代码 }); }
三、其他注意问题:
1、如果前端的用户名或密码为空,会导致后端报错,报的错误是不支持put方法,或不支持post方法等等。
2、在pom.xml里添加下面的依赖不起作用,无法自动下载依赖,原因暂时不明。
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.56</version>
<scope>provided</scope>
</dependency>
3、后端每次都会产生不同的公开秘钥,多用户同时登录是否会出错有待验证。
浙公网安备 33010602011771号