JSEncrypt 实现登录密码(或其他请求参数)的前端加密及后台解密问题案例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HSH205572/article/details/86491682

前言:

JSEncrypt 是用于执行OpenSSL RSA加密,解密和密钥生成的Javascript库。

网站: http://www.travistidwell.com/jsencrypt

如何使用这个库?

这个库应该与openssl一起工作。话虽如此,这里是如何使用这个库。

  • 在终端(基于Unix的操作系统)中输入以下内容。
openssl genrsa -out rsa_1024_priv.pem 1024
  • 这会生成一个私钥,您可以通过执行以下操作查看...
cat rsa_1024_priv.pem
  • 然后,您可以将其复制并粘贴到index.html内的私钥部分。
  • 接下来,您可以通过执行以下命令获取公钥。
openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem
  • 您可以通过键入来查看公钥...
cat rsa_1024_pub.pem
  • 现在,您可以通过在代码中执行以下操作来转换加密文本和从加密文本转换。

上述说明参考地址:https://github.com/travist/jsencrypt

1. js代码片段如下:

var formParam = $('loginForm').serializeObject();
http.httpRequest({
    url:'/rsa/getRsaKeyPublic',
    dataType:'text',
    type:'get',
    success:function (data) {
        var jsentrypt = new JSEncrypt();
        jsentrypt.setPublicKey(data);
        formParam.password = jsentrypt.encrypt(formParam['password']);

        http.httpRequest({
            url: 'admin/login',
            type: 'post',
            data: formParam,
            success: function (data) {
                //...
            }
        });
    }
});

2. 获取公钥代码段如下:

@Controller
@RequestMapping("/rsa")
public class TestController {

    /**
     * 公钥文件
     */
    private final static String RSA_PUBLIC_KEY = "/certs/rsa_public_key.pem";    


    /**
     * 描述 获取公钥
     *
     * @param
     * @return String
     * @author ***
     */
    @RequestMapping("/getRsaKeyPublic")
    @ResponseBody
    public String getRsaKeyPublic() {
        return getRsaKeyResource(RSA_PUBLIC_KEY);
    }

    /**
     * 描述
     *
     * @param
     * @return String
     * @author ***
     */
    public static String getRsaKeyResource(String rsaKeyResource) {
        InputStream inputStream = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        StringBuffer sb = new StringBuffer();
        try {
            inputStream = TestController.class.getResourceAsStream(rsaKeyResource);
            isr = new InputStreamReader(inputStream);
            br = new BufferedReader(isr);
            String str;
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        return sb.toString();
    }

3. 调用解密方法代码片段如下:

// 解密密码
// 私钥文件在 classpath下的 路径 /certs/rsa_private_key.pem
String password = RsaUtil.decrypt(loginDto.getPassword(),
        RsaUtil.getPrivateKey(TestController.class.getResourceAsStream("/certs/rsa_private_key.pem")));

4. 解密工具类(可以根据业务自行修改,封装,下面仅供参考)如下:

package com.demoinfo.common.support.utils;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;


public class RsaUtil {

    public static final String PADDING = "RSA/ECB/PKCS1Padding";
    public static final String PROVIDER = "BC";
    public static final Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();

    static {
        Security.addProvider(provider);
    }

    /**
     * 解密数据
     *
     * @param encrypted
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String decrypt(String encrypted, RSAPrivateKey privateKey) throws Exception {
        Cipher cipher;
        try {
            try {
                cipher = Cipher.getInstance(PADDING);
            } catch (Exception e) {
                cipher = Cipher.getInstance(PADDING, PROVIDER);
            }
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
        } catch (GeneralSecurityException e) {
            throw new RuntimeException("RSA algorithm not supported", e);
        }
        String[] blocks = encrypted.split("\\s");
        StringBuffer result = new StringBuffer();

        try {
            for (int i = 0; i < blocks.length; i++) {
                byte[] data = Base64.decodeBase64(blocks[i].getBytes());
                byte[] finalBytes = cipher.doFinal(data);
                result.append(new String(finalBytes, "UTF-8"));
            }
        } catch (GeneralSecurityException e) {
            throw new RuntimeException("Decrypt error", e);
        }
        return result.toString();
    }

    /**
     * 通过私钥PEM文件流还原私钥
     *
     * @param inputStream
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws IOException
     */
    public static RSAPrivateKey getPrivateKey(InputStream inputStream) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
        StringBuffer publicKey = new StringBuffer();
        String s;
        while ((s = br.readLine()) != null) {
            if (s.charAt(0) != '-') {
                publicKey.append(s + "\r");
            }
        }
        byte[] keyBytes = Base64.decodeBase64(publicKey.toString().getBytes());

        return getPrivateKey(keyBytes);
    }

    /**
     * 通过私钥byte[]还原私钥
     *
     * @param keyBytes
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static RSAPrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return (RSAPrivateKey) privateKey;
    }
}

猜你喜欢

转载自blog.csdn.net/HSH205572/article/details/86491682
今日推荐