美文网首页java
基于RSA的前后端登陆密码加密JAVA实现

基于RSA的前后端登陆密码加密JAVA实现

作者: singlezero | 来源:发表于2019-04-04 10:42 被阅读0次

    之前一直在做公司内网项目,对与加密基本没有考虑,最近看到加密的方法,在此做一个笔记,以便后面使用,

    RSA加密算法简介

    SA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到目前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。

    RSA加密的java实现

    实现的思路,由RSA随机生成一对公钥和私钥,公钥方到客户端,私钥放到服务端,发送数据的时候由公钥对传输数据进行加密,然后发送给服务端,服务端用私钥才能对数据进行解密.下面是代码实现的例子

    package com.yihur.demo
    
    import org.apache.commons.codec.binary.Base64;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import java.nio.charset.StandardCharsets;
    import java.security.*;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author yihur
     * @description RSA加密
     * @date 2019/4/3
     */
    public class MyRSAencryptionMethod {
    
        private static Logger logger = LoggerFactory.getLogger(MyRSAencryptionMethod .class);
    
    
        /**
         * 用于封装随机产生的公钥与私钥
         *
         * @author yihur
         * @date 2019/4/4
         * @param
         * @return
         */
        private static Map<Integer, String> keyMap = new HashMap<>();
    
    
        /**
         * 测试方法
         *
         * @param args
         * @return void
         * <p>
         * <p>
         * 前端用crypto-js进行加密,
         * npm i jsencrypt,
         * 然后页面头引入import JSEncrypt from 'jsencrypt';
         * const encrypt = new JSEncrypt();
         * encrypt.setPublicKey('你的公钥');
         * password = encrypt.encrypt(‘你的密码’);// 加密后的字符串
         * @author yihur
         * @date 2019/4/4
         */
        public static void main(String[] args) {
            //生成公钥和私钥
            genKeyPair();
            //加密字符串
            String message = "df723820";
            System.out.println("随机生成的公钥为:" + keyMap.get(0));
            System.out.println("随机生成的私钥为:" + keyMap.get(1));
            String messageEn = encrypt(message, keyMap.get(0));
            System.out.println("加密后的字符串为:" + messageEn);
            String messageDe = decrypt(messageEn, keyMap.get(1));
            System.out.println("还原后的字符串为:" + messageDe);
        }
    
        /**
         * 随机生成密钥对
         *
         * @param
         * @return void
         * @author yihur
         * @date 2019/4/4
         */
        public static void genKeyPair() {
            // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
            KeyPairGenerator keyPairGen = null;
            try {
                keyPairGen = KeyPairGenerator.getInstance("RSA");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                logger.info(e.getMessage());
            }
            // 初始化密钥对生成器,密钥大小为96-1024位
            assert keyPairGen != null;
            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())));
            // 将公钥和私钥保存到Map
            keyMap.put(0, publicKeyString);  //0表示公钥
            keyMap.put(1, privateKeyString);  //1表示私钥
        }
    
        /**
         * RSA公钥加密
         *
         * @param str       加密字符串
         * @param publicKey 公钥
         * @return 密文
         */
        public static String encrypt(String str, String publicKey) {
            //base64编码的公钥
            byte[] decoded = Base64.decodeBase64(publicKey);
            RSAPublicKey pubKey = null;
            String outStr = null;
            try {
                pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.ENCRYPT_MODE, pubKey);
                outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
            } catch (InvalidKeySpecException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException e) {
                e.printStackTrace();
                logger.info(e.getMessage());
            }
            //RSA加密
            return outStr;
        }
    
        /**
         * RSA私钥解密
         *
         * @param str        加密字符串
         * @param privateKey 私钥
         * @return 铭文
         */
        public static String decrypt(String str, String privateKey) {
            //64位解码加密后的字符串
            byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
            //base64编码的私钥
            byte[] decoded = Base64.decodeBase64(privateKey);
            RSAPrivateKey priKey = null;
            //RSA解密
            Cipher cipher = null;
            String outStr = null;
            try {
                priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
                cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.DECRYPT_MODE, priKey);
                outStr = new String(cipher.doFinal(inputByte));
            } catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e) {
                e.printStackTrace();
                logger.info(e.getMessage());
            }
            return outStr;
        }
    
    }
    
    

    RSA加密的前端用法

    前端用crypto-js进行加密,
    npm i jsencrypt,
    然后页面头引入import JSEncrypt from 'jsencrypt';
    const encrypt = new JSEncrypt();
    encrypt.setPublicKey('你的公钥');
    password = encrypt.encrypt(‘你的密码’);// 加密后的字符串
    

    后续

    在实际应用中RSA加密也还是远远不够,一般还会加入MD5加密的方式,以及加密验证,token等等方式作为请求连接的校验,比如后端加密一个MD5字符串,给前端之后,前端用特定组合加上传输数据返回一个RSA加密的字符串,后端接收后解密,然后和自身的字符串进行对比,以确认数据来源的准确性.
    这都是本人的浅浅理解,加密这一块水深似海,我不过是看到了小小的一点,如果内容有误欢迎各位大佬指正,谢谢.

    相关文章

      网友评论

        本文标题:基于RSA的前后端登陆密码加密JAVA实现

        本文链接:https://www.haomeiwen.com/subject/evzxiqtx.html