js加密与java解密的RSA(公钥/私钥)算法

发布时间 2023-06-20 17:33:12作者: lanwf

前言:

  公司用的加密算法是对称密钥加密算法,服务器上的公钥与客户端的私钥都是相同的,如果不小心泄露或者通过反编译软件把客户端重新编译就会泄露密钥,这样加密后的数据就不安全了。

商量使用非对称密钥RSA来解决这种问题,非对称密钥分为公钥和私钥,公钥可以公开给客户端分发给所有人,私钥放在服务器 有切仅有一份,公钥负责加密,私钥负责解密,这样就算获取到公钥也解不出数据。

私钥包含一些公钥全部信息,私钥可以推算出公钥,公钥只拥有部分信息 无论如何是推不出私钥的。所以站在公钥私钥上的角度来讲是绝对安全的。

 

RSA算法之公钥私钥

RSA算法属于非对称加密算法,非对称加密算法需要两个秘钥:公开密钥(publickey)和私有秘钥(privatekey)。公开密钥和私有秘钥是一对
如果公开密钥对数据进行加密,只有用对应的私有秘钥才能解密。如果私有秘钥对数据进行加密那么只有用对应的公开密钥才能解密。因为加密解密使用的是两个不同的秘钥
所以这种算法叫做非对称加密算法。简单的说就是公钥加密私钥解密,私钥加密公钥解密。

 

1.  首先打开在线生成公私钥网站:http://web.chacuo.net/netrsakeypair

 

 1.1 将公钥和私钥复制到notepad中 去除换行符

 

2. 点击下载js中的算法工具类: jsencrypt.min.js

 页面引入该js文件,将公钥密钥拿过来测试开是否可行

 谷歌浏览器运行发现

 注:在开发中,我们仅使用加密功能就可以了,不可暴漏私钥

 

3. java 端代码

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

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSAUtil {
    private static String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvcm08/QoRqgxxu+BPOLce/1lCMsicZbTqbTvzvi7YwhXrFNDqSN84jjehxzBKqEbW02myQ6hf5TpjSiQLC09ugwaC/VuVW1RaR7GbXiOGTTp/L869o/1IaXdaW2nrZa7mQ1nOQstNPvG7HjL+mmkLn7iWF1g5YtW0Ciexfbvuxz/eSeiGDqh6WF1lACdcm89w6mAAJK3vX0tOA/w/oDyjhbKD5j4YZOlXQbhNAr5Z8C+k+ppOA4DZlBcD69oVZGJD+BiU2/RWaE5rH3AetdeghHTikkzQ1KAlA8NvgtATkwr1KVs0VqolbLz2KGqhenAB2sKtaQ43P9FUUSsxoR5iQIDAQAB";

    private static String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC9ybTz9ChGqDHG74E84tx7/WUIyyJxltOptO/O+LtjCFesU0OpI3ziON6HHMEqoRtbTabJDqF/lOmNKJAsLT26DBoL9W5VbVFpHsZteI4ZNOn8vzr2j/Uhpd1pbaetlruZDWc5Cy00+8bseMv6aaQufuJYXWDli1bQKJ7F9u+7HP95J6IYOqHpYXWUAJ1ybz3DqYAAkre9fS04D/D+gPKOFsoPmPhhk6VdBuE0CvlnwL6T6mk4DgNmUFwPr2hVkYkP4GJTb9FZoTmsfcB6116CEdOKSTNDUoCUDw2+C0BOTCvUpWzRWqiVsvPYoaqF6cAHawq1pDjc/0VRRKzGhHmJAgMBAAECggEAEZHBua/JprjdWtBDQ5Kw3J2Zo9XCS4et8pD4fk2Sc1mLXD2dDuRlJEAlgZaM31howuwOW6CKHNh5QoMVzbEmfLmwE5lV7HyhQ70Am5PEe9rlKmu9lqO/Cq1jMOZg1nYUydduzd4WAkiooq2QHI95DoDajVmfpcBfege4oxT4Hnco7m5tuglHbSeV9M5hf+wRq8NNYrO5nWXJGDVPefRSK7OTg+FGu6CvQpdOw2zRqe9sTOy9xFeNMf8BbX5GINfHOobcX3AfMQq70EXzi2M2l8zQiwDw1QqzgpTtPpf2DbhhXqsBfploTf2yG0i5NJhXeCy8LnD5BEyDaubaCgWBzQKBgQDjiz9eEIBMVjrXMmK21cycQjLdWadvAYFHNvIydzQqCZHCwUtYrl/Qs1uaIQkC+L6ENcFdQJwgaTOQSFDrWDIxHp5Nre21ychVhHsvz0rQpFNkW9weAsi7NZlwvcJyRu1GZXdjND2Nc6ML1Z6Rwji8qwKyjvEUzuYrnnrmpdw3AwKBgQDVhbYhfqJunuF0oili3WGf85pz+8/NLkZPfksIhzleOe2/o4Ez+p8uRjuHbwLt66aG+uowQE2TbVgQEn1ZXy99pv2EaOUHjejOFnd0TOovz9gouPnFCgqSDB4bcGOdIz5cFgFC48DJTJhcxHxNv54bWTEuCFrObdE2FBRgx4RxgwKBgFpK6UxUU/T2ysaWMeHHmTfwdOqtJum/uSMfRKCN+N8tiO+1cEaye0b/xTu2HDNXrZIdGqv8dXfPBy0b5TBegRxIwBynBgr7FUoKFi/0nAWLD6RlZ0VpaWoQbOD2C/D5ADLNFMEC++HjnzGVBSVl4snLOnjMjBHrwB5S9wYLjwUtAoGAQ2IBCiz2gcZuC+qo+OQ4TMwJsBSFjZDO64NFlplmB1BssQ+eVJMA7Q+I9cKYwBCf6vUANt30HVRieB/9otihGhw64TBhJrMoBvGcHP2w4gnLg35shDwY/eIJFkuvhAV9Rn5DQ6KwUlZztsLjH34bHTJWjNpiHccWQOSxUaFlMJUCgYBnHLp4oXA/zw2l/QzeFcGQR0J+VF2lKyQIiHLWVZ4lpI3tFi5WjAaHP5nNbDnTwqBcnKeqwc+j4odzugTqFwDxmWvCSRuaa0K1SMUCEOdQh6InOFI5c5HW1IhRUae+c8s8T2RWy3Z+GLE3ko8A+/mqTSswlyCdKsPX3OBCjlcF7g==";


    public static void main(String[] args) throws Exception {
        String message = "Hello World!!!";
        String messageEn = encrypt(message, publicKey);
        System.out.println("加密:" + messageEn);
        String messageDe = decrypt(messageEn, privateKey);
        System.out.println("解密:" + messageDe);

        //genKeyPair();
    }

    /**
     * 该方法 可生成公钥与私钥
     * 如果不想用在线网站生成的公钥私钥,用这个生成的也可以
     *
     * @throws NoSuchAlgorithmException
     */
    public static void genKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        // 初始化密钥对生成器,密钥大小为96-1024位
        keyPairGen.initialize(1024, new SecureRandom());
        // 生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        // 得到私钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        // 得到公钥
        String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
        // 得到私钥字符串
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
        // 将公钥和私钥打印出来直接粘贴出来用即可
        System.out.println("公钥:"+publicKeyString);
        System.out.println("----------------------------------------------------------------");
        System.out.println("私钥: "+privateKeyString);
    }

    /**
     * 加密
     * @param str
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static String encrypt(String str, String publicKey) throws Exception {
        // base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
        // RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
    }

    /**
     * 解密
     * @param str
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String decrypt(String str, String privateKey) throws Exception {
        // 64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
        // base64编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
        // RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        return new String(cipher.doFinal(inputByte));
    }
}

运行结果

 

现在将页面的加密密文 复制到java中 ,成功解密