zoukankan      html  css  js  c++  java
  • RSA算法 JS加密 JAVA解密

    有这样一个需求,前端登录的usernamepassword,password必需加密。但不可使用MD5,由于后台要检測password的复杂度,那么在保证安全的前提下将password传到后台呢,答案就是使用RSA非对称加密算法解决 。

    java代码

    须要依赖 commons-codec
    RSACoder.java

    import org.apache.commons.codec.binary.Base64;
    
    import javax.crypto.Cipher;
    import java.security.*;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * Created by lake on 17-4-12.
     */
    public class RSACoder {
        public static final String KEY_ALGORITHM = "RSA";
        public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
    
        private static final String PUBLIC_KEY = "RSAPublicKey";
        private static final String PRIVATE_KEY = "RSAPrivateKey";
    
        public static byte[] decryptBASE64(String key) {
            return Base64.decodeBase64(key);
        }
    
        public static String encryptBASE64(byte[] bytes) {
            return Base64.encodeBase64String(bytes);
        }
    
        /**
         * 用私钥对信息生成数字签名
         *
         * @param data       加密数据
         * @param privateKey 私钥
         * @return
         * @throws Exception
         */
        public static String sign(byte[] data, String privateKey) throws Exception {
            // 解密由base64编码的私钥
            byte[] keyBytes = decryptBASE64(privateKey);
            // 构造PKCS8EncodedKeySpec对象
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            // KEY_ALGORITHM 指定的加密算法
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            // 取私钥匙对象
            PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
            // 用私钥对信息生成数字签名
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(priKey);
            signature.update(data);
            return encryptBASE64(signature.sign());
        }
    
        /**
         * 校验数字签名
         *
         * @param data      加密数据
         * @param publicKey 公钥
         * @param sign      数字签名
         * @return 校验成功返回true 失败返回false
         * @throws Exception
         */
        public static boolean verify(byte[] data, String publicKey, String sign)
                throws Exception {
            // 解密由base64编码的公钥
            byte[] keyBytes = decryptBASE64(publicKey);
            // 构造X509EncodedKeySpec对象
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            // KEY_ALGORITHM 指定的加密算法
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            // 取公钥匙对象
            PublicKey pubKey = keyFactory.generatePublic(keySpec);
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initVerify(pubKey);
            signature.update(data);
            // 验证签名是否正常
            return signature.verify(decryptBASE64(sign));
        }
    
        public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception{
            // 对密钥解密
            byte[] keyBytes = decryptBASE64(key);
            // 取得私钥
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
            // 对数据解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return cipher.doFinal(data);
        }
    
        /**
         * 解密<br>
         * 用私钥解密
         *
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] decryptByPrivateKey(String data, String key)
                throws Exception {
            return decryptByPrivateKey(decryptBASE64(data),key);
        }
    
        /**
         * 解密<br>
         * 用公钥解密
         *
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] decryptByPublicKey(byte[] data, String key)
                throws Exception {
            // 对密钥解密
            byte[] keyBytes = decryptBASE64(key);
            // 取得公钥
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key publicKey = keyFactory.generatePublic(x509KeySpec);
            // 对数据解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            return cipher.doFinal(data);
        }
    
        /**
         * 加密<br>
         * 用公钥加密
         *
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] encryptByPublicKey(String data, String key)
                throws Exception {
            // 对公钥解密
            byte[] keyBytes = decryptBASE64(key);
            // 取得公钥
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key publicKey = keyFactory.generatePublic(x509KeySpec);
            // 对数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return cipher.doFinal(data.getBytes());
        }
    
        /**
         * 加密<br>
         * 用私钥加密
         *
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] encryptByPrivateKey(byte[] data, String key)
                throws Exception {
            // 对密钥解密
            byte[] keyBytes = decryptBASE64(key);
            // 取得私钥
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
            // 对数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            return cipher.doFinal(data);
        }
    
        /**
         * 取得私钥
         *
         * @param keyMap
         * @return
         * @throws Exception
         */
        public static String getPrivateKey(Map<String, Key> keyMap)
                throws Exception {
            Key key = (Key) keyMap.get(PRIVATE_KEY);
            return encryptBASE64(key.getEncoded());
        }
    
        /**
         * 取得公钥
         *
         * @param keyMap
         * @return
         * @throws Exception
         */
        public static String getPublicKey(Map<String, Key> keyMap)
                throws Exception {
            Key key = keyMap.get(PUBLIC_KEY);
            return encryptBASE64(key.getEncoded());
        }
    
        /**
         * 初始化密钥
         *
         * @return
         * @throws Exception
         */
        public static Map<String, Key> initKey() throws Exception {
            KeyPairGenerator keyPairGen = KeyPairGenerator
                    .getInstance(KEY_ALGORITHM);
            keyPairGen.initialize(1024);
            KeyPair keyPair = keyPairGen.generateKeyPair();
            Map<String, Key> keyMap = new HashMap(2);
            keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥
            keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥
            return keyMap;
        }
    }

    測试类
    RSACoderTest.java

    import org.junit.Before;
    import org.junit.Test;
    
    import java.security.Key;
    import java.util.Map;
    
    import static org.junit.Assert.assertEquals;
    import static org.junit.Assert.assertTrue;
    
    /**
     * Created by lake on 17-4-12.
     */
    public class RSACoderTest {
        private String publicKey;
        private String privateKey;
    
        @Before
        public void setUp() throws Exception {
            Map<String, Key> keyMap = RSACoder.initKey();
            publicKey = RSACoder.getPublicKey(keyMap);
            privateKey = RSACoder.getPrivateKey(keyMap);
            System.err.println("公钥: 
    
    " + publicKey);
            System.err.println("私钥: 
    
    " + privateKey);
        }
    
        @Test
        public void test() throws Exception {
            System.err.println("公钥加密——私钥解密");
            String inputStr = "abc";
            byte[] encodedData = RSACoder.encryptByPublicKey(inputStr, publicKey);
            byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,
                    privateKey);
            String outputStr = new String(decodedData);
            System.err.println("加密前: " + inputStr + "
    
    " + "解密后: " + outputStr);
            assertEquals(inputStr, outputStr);
        }
    
        @Test
        public void testSign() throws Exception {
            System.err.println("私钥加密——公钥解密");
            String inputStr = "sign";
            byte[] data = inputStr.getBytes();
            byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);
            byte[] decodedData = RSACoder.decryptByPublicKey(encodedData, publicKey);
            String outputStr = new String(decodedData);
            System.err.println("加密前: " + inputStr + "
    
    " + "解密后: " + outputStr);
            assertEquals(inputStr, outputStr);
            System.err.println("私钥签名——公钥验证签名");
            // 产生签名
            String sign = RSACoder.sign(encodedData, privateKey);
            System.err.println("签名:" + sign);
            // 验证签名
            boolean status = RSACoder.verify(encodedData, publicKey, sign);
            System.err.println("状态:" + status);
            assertTrue(status);
        }
    }
    

    前端代码

    依赖 jsencrypt 项目

    <script src="bin/jsencrypt.min.js"></script>
    <script type="text/javascript">
        var encrypt = new JSEncrypt();
        encrypt.setPublicKey('java生成的公钥');
        var encrypted = encrypt.encrypt('加密的字符串');
    </script>

    说明

    前端生成加密的字符串encrypted,传到后台,java使用私钥进行解密就可以。

  • 相关阅读:
    解决 搭建Jekins过程中 启动Tomcat的java.net.UnknownHostException异常
    射手和农场主
    java 和 JS(javaScript)中的反斜杠正则转义
    分享修改密码的SharePoint Web part: ITaCS Change Password web part
    分享微软官方Demo用的SharePoint 2010, Exchange 2010, Lync 2010虚拟机
    Office 365 的公共网站的一些限制及解决的办法
    SharePoint 2013 关闭 customErrors
    安装 KB2844286 导致SharePoint 2010 XSLT web part 显示出现错误
    安装Office Web Apps Server 2013 – KB2592525安装失败
    如何将hyper-v虚拟机转换成vmware的虚拟机- 转换SharePoint 2010 Information Worker Demonstration and Evaluation Virtual Machine (SP1)
  • 原文地址:https://www.cnblogs.com/llguanli/p/8915706.html
Copyright © 2011-2022 走看看