zoukankan      html  css  js  c++  java
  • RSA算法

    1. 什么是RSA

    RSA算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法。在了解RSA算法之前,先熟悉下几个术语 。根据密钥的使用方法,可以将密码分为对称密码和公钥密码 :
    对称密码:加密和解密使用同一种密钥的方式 
    公钥密码:加密和解密使用不同的密码的方式,因此公钥密码通常也称为非对称密码。

    1.1、一点历史

    1976年以前,所有的加密方法都是同一种模式:

      (1)甲方选择某一种加密规则,对信息进行加密;

      (2)乙方使用同一种规则,对信息进行解密。

    由于加密和解密使用同样规则(简称"密钥"),这被称为"对称加密算法"(Symmetric-key algorithm)。

    这种加密模式有一个最大弱点:甲方必须把加密规则告诉乙方,否则无法解密。保存和传递密钥,就成了最头疼的问题。

    1976年,两位美国计算机学家Whitfield Diffie 和 Martin Hellman,提出了一种崭新构思,可以在不直接传递密钥的情况下,完成解密。这被称为"Diffie-Hellman密钥交换算法"。这个算法启发了其他科学家。人们认识到,加密和解密可以使用不同的规则,只要这两种规则之间存在某种对应关系即可,这样就避免了直接传递密钥。

    这种新的加密模式被称为"非对称加密算法"。

      (1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。

      (2)甲方获取乙方的公钥,然后用它对信息加密。

      (3)乙方得到加密后的信息,用私钥解密。

    如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。

    1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。毫不夸张地说,只要有计算机网络的地方,就有RSA算法。

    这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。

    1.2.公开密钥加密

    公开密钥加密(public-key cryptography),也成为非对称加密,是密码学的一种算法,他需要两个密钥,一个是公开密钥,另一个是私有密钥,一个用作加密的时候,另一个则用作解密。

    • 明文:需要加密的内容,成为明文。
    • 密文:使用密钥把明文加密后的内容。只能用相应的另一个密钥才能解密得到原来的明文。甚至连最初用来加密的密钥也不能用作解密。

    2.对称加密&&非对称加密

    • 对称加密:加密和解密都是用同一个密钥的算法,称作对称加密。
    • 非对称加密:加密和解密需要不同的密钥。

    因为公钥加密的信息只用私钥才能解的开,所以只要私钥不泄露,通信就是安全的。

    3.RSA算法

    package Demo;
    
    import javax.crypto.*;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.UnsupportedEncodingException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.util.Scanner;
    
    
    /**
    *RSA算法
    *
    */
    public class RSAUtils {
    
        public static void main(String[] args) throws UnsupportedEncodingException {
            System.out.println("请输入要加密的内容和密码");
            System.out.println("请输入要加密的密码");
            Scanner scanner = new Scanner(System.in);
            String content = scanner.next();
            String password = scanner.next();
    
            // String content = "我是shoneworn";
            // String password = "12345678";
            // 加密
            System.out.println("加密前:" + content);
            byte[] encode = encrypt(content, password);
    
            //传输过程,不转成16进制的字符串,就等着程序崩溃掉吧
            String code = parseByte2HexStr(encode);
            System.out.println("密文字符串:" + code);
            byte[] decode = parseHexStr2Byte(code);
            // 解密
            byte[] decryptResult = decrypt(decode, password);
            System.out.println("解密后:" + new String(decryptResult, "UTF-8")); //不转码会乱码
    
        }
    
        /**
         * 加密
         *
         * @param content
         *            需要加密的内容
         * @param password
         *            加密密码
         * @return
         */
        public static byte[] encrypt(String content, String password) {
            try {
                KeyGenerator kgen = KeyGenerator.getInstance("AES");
                kgen.init(128, new SecureRandom(password.getBytes()));
                SecretKey secretKey = kgen.generateKey();
                byte[] enCodeFormat = secretKey.getEncoded();
                SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
                Cipher cipher = Cipher.getInstance("AES");// 创建密码器
                byte[] byteContent = content.getBytes("utf-8");
                cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
                byte[] result = cipher.doFinal(byteContent);
                return result; // 加密
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 解密
         *
         * @param content
         *            待解密内容
         * @param password
         *            解密密钥
         * @return
         */
        public static byte[] decrypt(byte[] content, String password) {
            try {
                KeyGenerator kgen = KeyGenerator.getInstance("AES");
                kgen.init(128, new SecureRandom(password.getBytes()));
                SecretKey secretKey = kgen.generateKey();
                byte[] enCodeFormat = secretKey.getEncoded();
                SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
                Cipher cipher = Cipher.getInstance("AES");// 创建密码器
                cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
                byte[] result = cipher.doFinal(content);
                return result; // 加密
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            }
            return null;
        }
        /**
         * 将二进制转换成16进制
         *
         * @param buf
         * @return
         */
        public static String parseByte2HexStr(byte buf[]) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < buf.length; i++) {
                String hex = Integer.toHexString(buf[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        }
        /**
         * 将16进制转换为二进制
         *
         * @param hexStr
         * @return
         */
        public static byte[] parseHexStr2Byte(String hexStr) {
            if (hexStr.length() < 1)
                return null;
            byte[] result = new byte[hexStr.length() / 2];
            for (int i = 0; i < hexStr.length() / 2; i++) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
        /**
         * 加密
         *
         * @param content
         *            需要加密的内容
         * @param password
         *            加密密码
         * @return
         */
        public static byte[] encrypt2(String content, String password) {
            try {
                SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES");
                Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
                byte[] byteContent = content.getBytes("utf-8");
                cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
                byte[] result = cipher.doFinal(byteContent);
                return result; // 加密
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

      

  • 相关阅读:
    【转】在.NET使用JSON作为数据交换格式
    类似QQ管家页面jquery图片轮换实例
    jquery+ajax 文件上传功能(无ifram嵌套)
    sql另辟蹊,持续更新
    【转】JavaScript 中 function 的动态执行
    八款js框架比较
    【转】怎样写出可维护的面向对象javascript
    【转】程序员该如何定位?
    WF4.0实战系列索引
    Microsoft Help Viewer help查看器所需的内容文件缺失或者损坏 解决办法
  • 原文地址:https://www.cnblogs.com/aaaazzzz/p/14429200.html
Copyright © 2011-2022 走看看