RSA加密

作者: 夜月行者 | 来源:发表于2017-11-27 18:28 被阅读0次

    简介

    在非对称加密中,最常用的应该就是RSA加密了吧。
    在讲对称加密的时候,就曾经说过,对称加密算法在加密和解密时使用的是同一个秘钥,加解密双方必须使用同一个密钥才能进行正常的沟通。而非对称加密则不然,非对称加密算法需要两个密钥来进行加密和解密,分别是公钥和私钥。
    这个公钥和私钥必须是一对的,如果用公钥对数据进行加密,那么只有使用对应的私钥才能解密,反之亦然。由于加密和解密使用的是两个不同的密钥,因此,这种算法叫做非对称加密算法。

    工作过程

    乙方生成一对密钥(公钥和私钥)并将公钥向其它方公开;
    得到该公钥的甲方使用该密钥对机密信息进行加密后再发送给乙方;
    乙方再用自己保存的另一把专用密钥(私钥)对加密后的信息进行解密;
    乙方只能用其专用密钥(私钥)解密由对应的公钥加密后的信息;
    在传输过程中,即使攻击者截获了传输的密文,并得到了乙的公钥,也无法破解密文,因为只有乙的私钥才能解密密文。

    相关的问题

    RSA算法本身对密钥的格式等有一些规定,而且因为应用比较广泛,所以在证书中也有使用。

    X509标准:X.509证书标准支持三种不对称加密算法:RSA, DSA, Diffie-Hellman algorithms。最常用的是RSA算法。

    PKC:The Public-Key Cryptography Standards (PKCS)是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。
    PKCS#8:描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等[27]。

    java demo

    
     
    import com.google.common.collect.Maps;
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
     
    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;
    import java.util.Map;
     
    /**
    * Created by xiang.li on 2015/3/3.
    * RSA 加解密工具类
    */
    public class RSA {
        /**
         * 定义加密方式
         */
        private final static String KEY_RSA = "RSA";
        /**
         * 定义签名算法
         */
        private final static String KEY_RSA_SIGNATURE = "MD5withRSA";
        /**
         * 定义公钥算法
         */
        private final static String KEY_RSA_PUBLICKEY = "RSAPublicKey";
        /**
         * 定义私钥算法
         */
        private final static String KEY_RSA_PRIVATEKEY = "RSAPrivateKey";
     
        /**
         * 初始化密钥
         * @return
         */
        public static Map<String, Object> init() {
            Map<String, Object> map = null;
            try {
                KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA);
                generator.initialize(1024);
                KeyPair keyPair = generator.generateKeyPair();
                // 公钥
                RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
                // 私钥
                RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
                // 将密钥封装为map
                map = Maps.newHashMap();
                map.put(KEY_RSA_PUBLICKEY, publicKey);
                map.put(KEY_RSA_PRIVATEKEY, privateKey);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return map;
        }
     
        /**
         * 用私钥对信息生成数字签名
         * @param data 加密数据
         * @param privateKey 私钥
         * @return
         */
        public static String sign(byte[] data, String privateKey) {
            String str = "";
            try {
                // 解密由base64编码的私钥
                byte[] bytes = decryptBase64(privateKey);
                // 构造PKCS8EncodedKeySpec对象
                PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(bytes);
                // 指定的加密算法
                KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
                // 取私钥对象
                PrivateKey key = factory.generatePrivate(pkcs);
                // 用私钥对信息生成数字签名
                Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
                signature.initSign(key);
                signature.update(data);
                str = encryptBase64(signature.sign());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return str;
        }
     
        /**
         * 校验数字签名
         * @param data 加密数据
         * @param publicKey 公钥
         * @param sign 数字签名
         * @return 校验成功返回true,失败返回false
         */
        public static boolean verify(byte[] data, String publicKey, String sign) {
            boolean flag = false;
            try {
                // 解密由base64编码的公钥
                byte[] bytes = decryptBase64(publicKey);
                // 构造X509EncodedKeySpec对象
                X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
                // 指定的加密算法
                KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
                // 取公钥对象
                PublicKey key = factory.generatePublic(keySpec);
                // 用公钥验证数字签名
                Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
                signature.initVerify(key);
                signature.update(data);
                flag = signature.verify(decryptBase64(sign));
            } catch (Exception e) {
                e.printStackTrace();
            }
            return flag;
        }
     
        /**
         * 私钥解密
         * @param data 加密数据
         * @param key 私钥
         * @return
         */
        public static byte[] decryptByPrivateKey(byte[] data, String key) {
            byte[] result = null;
            try {
                // 对私钥解密
                byte[] bytes = decryptBase64(key);
                // 取得私钥
                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
                KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
                PrivateKey privateKey = factory.generatePrivate(keySpec);
                // 对数据解密
                Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                result = cipher.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
     
        /**
         * 私钥解密
         * @param data 加密数据
         * @param key 公钥
         * @return
         */
        public static byte[] decryptByPublicKey(byte[] data, String key) {
            byte[] result = null;
            try {
                // 对公钥解密
                byte[] bytes = decryptBase64(key);
                // 取得公钥
                X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
                KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
                PublicKey publicKey = factory.generatePublic(keySpec);
                // 对数据解密
                Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
                cipher.init(Cipher.DECRYPT_MODE, publicKey);
                result = cipher.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
     
        /**
         * 公钥加密
         * @param data 待加密数据
         * @param key 公钥
         * @return
         */
        public static byte[] encryptByPublicKey(byte[] data, String key) {
            byte[] result = null;
            try {
                byte[] bytes = decryptBase64(key);
                // 取得公钥
                X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
                KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
                PublicKey publicKey = factory.generatePublic(keySpec);
                // 对数据加密
                Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
                result = cipher.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
     
        /**
         * 私钥加密
         * @param data 待加密数据
         * @param key 私钥
         * @return
         */
        public static byte[] encryptByPrivateKey(byte[] data, String key) {
            byte[] result = null;
            try {
                byte[] bytes = decryptBase64(key);
                // 取得私钥
                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
                KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
                PrivateKey privateKey = factory.generatePrivate(keySpec);
                // 对数据加密
                Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
                cipher.init(Cipher.ENCRYPT_MODE, privateKey);
                result = cipher.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
     
        /**
         * 获取公钥
         * @param map
         * @return
         */
        public static String getPublicKey(Map<String, Object> map) {
            String str = "";
            try {
                Key key = (Key) map.get(KEY_RSA_PUBLICKEY);
                str = encryptBase64(key.getEncoded());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return str;
        }
     
        /**
         * 获取私钥
         * @param map
         * @return
         */
        public static String getPrivateKey(Map<String, Object> map) {
            String str = "";
            try {
                Key key = (Key) map.get(KEY_RSA_PRIVATEKEY);
                str = encryptBase64(key.getEncoded());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return str;
        }
     
        /**
         * BASE64 解密
         * @param key 需要解密的字符串
         * @return 字节数组
         * @throws Exception
         */
        public static byte[] decryptBase64(String key) throws Exception {
            return (new BASE64Decoder()).decodeBuffer(key);
        }
     
        /**
         * BASE64 加密
         * @param key 需要加密的字节数组
         * @return 字符串
         * @throws Exception
         */
        public static String encryptBase64(byte[] key) throws Exception {
            return (new BASE64Encoder()).encodeBuffer(key);
        }
     
        /**
         * 测试方法
         * @param args
         */
        public static void main(String[] args) {
            String privateKey = "";
            String publicKey = "";
            // 生成公钥私钥
            Map<String, Object> map = init();
            publicKey = getPublicKey(map);
            privateKey = getPrivateKey(map);
            System.out.println("公钥: \n\r" + publicKey);
            System.out.println("私钥: \n\r" + privateKey);
            System.out.println("公钥加密--------私钥解密");
            String word = "你好,世界!";
            byte[] encWord = encryptByPublicKey(word.getBytes(), publicKey);
            String decWord = new String(decryptByPrivateKey(encWord, privateKey));
            System.out.println("加密前: " + word + "\n\r" + "解密后: " + decWord);
            System.out.println("私钥加密--------公钥解密");
            String english = "Hello, World!";
            byte[] encEnglish = encryptByPrivateKey(english.getBytes(), privateKey);
            String decEnglish = new String(decryptByPublicKey(encEnglish, publicKey));
            System.out.println("加密前: " + english + "\n\r" + "解密后: " + decEnglish);
            System.out.println("私钥签名——公钥验证签名");
            // 产生签名
            String sign = sign(encEnglish, privateKey);
            System.out.println("签名:\r" + sign);
            // 验证签名
            boolean status = verify(encEnglish, publicKey, sign);
            System.out.println("状态:\r" + status);
        }
    }
    
    
    
    

    参考:http://blog.csdn.net/happylee6688/article/details/45218801

    相关文章

      网友评论

          本文标题:RSA加密

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