zoukankan      html  css  js  c++  java
  • 浅谈RSA加密算法

    一、什么是非对称加密

    1、加密的密钥与加密的密钥不相同,这样的加密算法称之为非对称加密

    2、密钥分为:公钥,私钥

       公钥:可以对外给任何人的加密和解密的密码,是公开的

         私钥:通过私钥可以生成公钥,但从公钥被认为无法生成公钥(被推导出的概率小到不考虑)

    3、当将要加密的内容用公钥加密的时候,只能用私钥来解密

         当将要加密的内容用私钥加密的时候,只能用公钥来解密

    4、公钥与私钥的关系,利用一个简单的公式来生成公钥和私钥,即非对称加密的公钥和私钥之间存在某一个公式关系

    5、常见的非对称加密算法

      RSA,DSA


    二、什么是RSA算法

    RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。
    RSA的算法涉及三个参数,n、e1、e2。
    其中,n是两个大质数p、q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度。
    e1和e2是一对相关的值,e1可以任意取,但要求e1与(p-1)*(q-1)互质;再选择e2,要求(e2*e1)mod((p-1)*(q-1))=1。
    (n,e1),(n,e2)就是密钥对。其中(n,e1)为公钥,(n,e2)为私钥。[1] 
    RSA加解密的算法完全相同,设A为明文,B为密文,则:A=B^e2 mod n;B=A^e1 mod n;(公钥加密体制中,一般用公钥加密,私钥解密)
    e1和e2可以互换使用,即:
    A=B^e1 mod n;B=A^e2 mod n;
     
    三、RSA加密算法的使用
    1、RSA密钥的生成,返回一个KeyPair对象
    KeyPair 用于非对称加密,KeyPair中包含了一个公钥和一个私钥
        /**
         * 通过指定的密钥长度生成非对称的密钥对
         * @param keySize  推荐使用1024,2048 ,不允许低于1024
         * @return
         */
        public static KeyPair generateRSAKeyPair(int keySize){
            KeyPair ret = null;
            try {
                //1、准备生成
                KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
                //2、初始化,设置秘钥长度
                generator.initialize(keySize);
                //3、生成,并且返回
                ret = generator.generateKeyPair();
    
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return ret;
        }

    2、获取私钥和公钥

    PublicKey 和 PrivateKey 都是Key类型的

         KeyPair keyPair = EncryptUtil.generateRSAKeyPair(1024);
            //获取公钥,可以给任何人
            PublicKey publicKey = keyPair.getPublic();
         //获取私钥 PrivateKey privateKey
    = keyPair.getPrivate();

    3、RSA加密

    /**
         *  RSA 加密
         * @param data  需要加密的数据
         * @param key  可以是 PublicKey,也可以是PrivateKey
         * @return
         */
        public static byte[] rsaEncrypt(byte[] data ,Key key){
            byte[] ret = null;
            if (data != null
                    && data.length>0
                    && key!=null) {
                // 1、创建Cipher 使用RSA
                try {
                    Cipher cipher = Cipher.getInstance("RSA");
                    //设置Key
                    cipher.init(Cipher.ENCRYPT_MODE,key);
                    ret = cipher.doFinal(data);
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (BadPaddingException e) {
                    e.printStackTrace();
                } catch (IllegalBlockSizeException e) {
                    e.printStackTrace();
                }
            }
            return ret;
        }

    4、RSA解密

    /**
         *  RSA 解密
         * @param data 要解密的数据
         * @param key  可以是 PublicKey,也可以是PrivateKey
         * @return
         */
        public static byte[] rsaDecrypt(byte[] data ,Key key){
            byte[] ret = null;
    
            if (data != null
                    && data.length>0
                    && key!=null) {
                // 1、创建Cipher 使用RSA
                try {
                    Cipher cipher = Cipher.getInstance("RSA");
                    //设置Key
                    cipher.init(Cipher.DECRYPT_MODE,key);
                    ret = cipher.doFinal(data);
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (BadPaddingException e) {
                    e.printStackTrace();
                } catch (IllegalBlockSizeException e) {
                    e.printStackTrace();
                }
            }
            return ret;
        }

    5、公钥与私钥的存储

    一对公钥和私钥创建好之后,我们需要存储起来以后使用

        //获得公钥 私钥
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();
            //编码将PublicKey和PrivateKey对象转换为字节数组,该字节数组为公钥、私钥的实际数据
            byte[] publicKeyEncoded = publicKey.getEncoded();
            byte[] privateKeyEncoded = privateKey.getEncoded();
         //将字节数组通过Base64编码算法 编码成可见的字符形式 String publickey
    = Base64.encodeToString(publicKeyEncoded, Base64.NO_WRAP); String privatekey = Base64.encodeToString(privateKeyEncoded, Base64.NO_WRAP);
         //进行存储操作
         。。。。

    6、公钥与私钥的加载

    通常 1、获取密钥对 2、获取公钥、私钥 3、保存公钥、私钥,保存形式基本为字符串形式

    那么在以后的使用中就需要获取公钥和私钥来使用

    需要知道:

      6.1、KeyFactory可以来加载相应的公钥和私钥

      6.2、公钥加载 使用 X509EncodedKeySpec(byte[])

      6.3、私钥加载 使用 PCKS8EncodedKeySpec(byte[])

    //获取公钥
    //str_publickey 为公钥字符串形式数据(公钥先编码成byte[] 在 形成字符串)
    //解码
                byte[] publicdecode = Base64.decode(new String(str_publickey), Base64.NO_WRAP);
                //构造X509EncodedKeySpec对象
                X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicdecode);
                //指定加密算法
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                //取得公钥
                PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
    //解码
    //获取私钥
    //str_private 为私钥字符串形式的数据 byte[] privatedecode = Base64.decode(new String(str_private), Base64.NO_WRAP); //构造X509EncodedKeySpec对象 PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privatedecode); //指定加密算法 keyFactory = KeyFactory.getInstance("RSA"); //取得私钥 PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);

    相关知识:

    浅谈DES加密算法

  • 相关阅读:
    Android事件详解——拖放事件DragEvent
    Android 用户界面---拖放(Drag and Drop)(三)
    Android 用户界面---拖放(Drag and Drop)(二)
    Android 用户界面---拖放(Drag and Drop)(一)
    Android开发者指南-用户界面-拖放-Drag and Drop[原创译文]
    Android L动画入门
    基本介绍LINUX远程PC软件:PUTTY、SecureCRT、X-Manager
    js字的数目的计算方法(与word计算公式为)
    动机,努力工作,提高能力,提高战斗力,要注意保暖,维护创业热情。
    pig询问top k,每个返回hour和ad_network_id最大的两个记录(SUBSTRING,order,COUNT_STAR,limit)
  • 原文地址:https://www.cnblogs.com/xqxacm/p/4889553.html
Copyright © 2011-2022 走看看