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 }
View Code

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、后端每次都会产生不同的公开秘钥,多用户同时登录是否会出错有待验证。

posted @ 2021-07-02 16:31  wwwzgy  阅读(551)  评论(0)    收藏  举报