RSA加密

作者: 炒鸡可耐的小葵花 | 来源:发表于2018-09-12 22:44 被阅读20次
    import java.math.BigInteger;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.NoSuchAlgorithmException;
    import java.security.Security;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.RSAPrivateKeySpec;
    import java.security.spec.RSAPublicKeySpec;
    import java.util.HashMap;
    
    import javax.crypto.Cipher;
    
    /**
     * RSA加密工具
     * Created by hyq on 2018/5/4
     */
    public class RSAUtil {
        /**
         * 生成公钥和私钥
         *
         * @throws NoSuchAlgorithmException
         */
        public static HashMap getKeys() throws NoSuchAlgorithmException {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            HashMap map = new HashMap();
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            keyPairGen.initialize(1024);
            KeyPair keyPair = keyPairGen.generateKeyPair();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            map.put("public", publicKey);
            map.put("private", privateKey);
            return map;
        }
    
        /**
         * 使用模和指数生成RSA公钥
         *
         * @param modulus  模
         * @param exponent 指数
         */
        public static RSAPublicKey getPublicKey(String modulus, String exponent) {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            try {
                BigInteger b1 = new BigInteger(modulus);
                BigInteger b2 = new BigInteger(exponent);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
                RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);
                return (RSAPublicKey) keyFactory.generatePublic(keySpec);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * 使用模和指数生成RSA私钥
         * /None/NoPadding
         *
         * @param modulus  模
         * @param exponent 指数
         * @return
         */
        public static RSAPrivateKey getPrivateKey(String modulus, String exponent) {
            try {
                Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
                BigInteger b1 = new BigInteger(modulus);
                BigInteger b2 = new BigInteger(exponent);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
                RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2);
                return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * 公钥加密
         *
         * @param data
         * @param publicKey
         * @return
         * @throws Exception
         */
        public static String encryptByPublicKey(String data, RSAPublicKey publicKey) throws Exception {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            // 模长
            int key_len = publicKey.getModulus().bitLength() / 8;
            // 加密数据长度 <= 模长-11
            String[] datas = splitString(data, key_len - 11);
            String mi = "";
            //如果明文长度大于模长-11则要分组加密
            for (String s : datas) {
                mi += bcd2Str(cipher.doFinal(s.getBytes()));
            }
            return mi;
        }
    
        /**
         * 私钥解密
         *
         * @param data
         * @param privateKey
         * @return
         * @throws Exception
         */
        public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey) throws Exception {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            //模长
            int key_len = privateKey.getModulus().bitLength() / 8;
            byte[] bytes = data.getBytes();
            byte[] bcd = ASCII_To_BCD(bytes, bytes.length);
            //System.err.println(bcd.length);
            //如果密文长度大于模长则要分组解密
            String ming = "";
            byte[][] arrays = splitArray(bcd, key_len);
            for (byte[] arr : arrays) {
                ming += new String(cipher.doFinal(arr));
            }
            return ming;
        }
    
        /**
         * ASCII码转BCD码
         */
        public static byte[] ASCII_To_BCD(byte[] ascii, int asc_len) {
            byte[] bcd = new byte[asc_len / 2];
            int j = 0;
            for (int i = 0; i < (asc_len + 1) / 2; i++) {
                bcd[i] = asc_to_bcd(ascii[j++]);
                bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i] << 4));
            }
            return bcd;
        }
    
        public static byte asc_to_bcd(byte asc) {
            byte bcd;
            if ((asc >= '0') && (asc <= '9'))
                bcd = (byte) (asc - '0');
            else if ((asc >= 'A') && (asc <= 'F'))
                bcd = (byte) (asc - 'A' + 10);
            else if ((asc >= 'a') && (asc <= 'f'))
                bcd = (byte) (asc - 'a' + 10);
            else
                bcd = (byte) (asc - 48);
            return bcd;
        }
    
        /**
         * BCD转字符串
         */
        public static String bcd2Str(byte[] bytes) {
            char temp[] = new char[bytes.length * 2], val;
            for (int i = 0; i < bytes.length; i++) {
                val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
                temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
                val = (char) (bytes[i] & 0x0f);
                temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
            }
            return new String(temp);
        }
    
        /**
         * 拆分字符串
         */
        public static String[] splitString(String string, int len) {
            int x = string.length() / len;
            int y = string.length() % len;
            int z = 0;
            if (y != 0) {
                z = 1;
            }
            String[] strings = new String[x + z];
            String str = "";
            for (int i = 0; i < x + z; i++) {
                if (i == x + z - 1 && y != 0) {
                    str = string.substring(i * len, i * len + y);
                } else {
                    str = string.substring(i * len, i * len + len);
                }
                strings[i] = str;
            }
            return strings;
        }
    
        /**
         * 拆分数组
         */
        public static byte[][] splitArray(byte[] data, int len) {
            int x = data.length / len;
            int y = data.length % len;
            int z = 0;
            if (y != 0) {
                z = 1;
            }
            byte[][] arrays = new byte[x + z][];
            byte[] arr;
            for (int i = 0; i < x + z; i++) {
                arr = new byte[len];
                if (i == x + z - 1 && y != 0) {
                    System.arraycopy(data, i * len, arr, 0, y);
                } else {
                    System.arraycopy(data, i * len, arr, 0, len);
                }
                arrays[i] = arr;
            }
            return arrays;
        }
    
        public static void main(String[] args) throws Exception {
            HashMap map = getKeys();
            //生成公钥和私钥
            RSAPublicKey publicKey = (RSAPublicKey) map.get("public");
            RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");
            //模
            String modulus = publicKey.getModulus().toString();
            modulus = "dd6be3d4de56287b8c3616b33bc1b7a5a2bb9148252140262420ee047f83b3165fb7674a759d60c24b71fd5437c7810f127f2c4370c2d4bdfcb55c08f1b3c715b7b2f57228e78e34039d2b967f54a58e345bc91e3dd54c7bea86d73c9e2de968736bf2b97f50bea891aa3519ae7238d76dff57cabba7cc0d370775657f3b5c83";
            BigInteger sixthtest2 = new BigInteger(modulus, 16);
            modulus = sixthtest2.toString();
            System.out.println("pubkey modulus=" + modulus);
            //公钥指数
            String public_exponent = publicKey.getPublicExponent().toString();
            public_exponent = "10001";
            BigInteger hh = new BigInteger(public_exponent, 16);
            public_exponent = hh.toString();
            System.out.println("pubkey exponent=" + public_exponent);
    //        //私钥指数
            String private_exponent = privateKey.getPrivateExponent().toString();
            private_exponent = "54712537089112817889981994641184352849048377286188637988954612170120627468763880489886706964032019663270893057329335059472175306012819568365723658387355119672809485653603643981222096667941140888521671620447127553757093714372635754674996604605878456428149342380671195977042995355568862882828346936935942070657";
            System.out.println("private exponent=" + private_exponent);
            //明文
            String ming = "147690";
            //使用模和指数生成公钥和私钥
            RSAPublicKey pubKey = RSAUtil.getPublicKey(modulus, public_exponent);
            RSAPrivateKey priKey = RSAUtil.getPrivateKey(modulus, private_exponent);
            //加密后的密文
            String mi = RSAUtil.encryptByPublicKey(ming, pubKey);
            System.err.println("mi=" + mi);
    //        //解密后的明文
            String ming2 = RSAUtil.decryptByPrivateKey(mi, priKey);
            System.err.println("ming2=" + ming2);
    //        System.out.println("=====================================进制转换===========================");
    //        String name="dd6be3d4de56287b8c3616b33bc1b7a5a2bb9148252140262420ee047f83b3165fb7674a759d60c24b71fd5437c7810f127f2c4370c2d4bdfcb55c08f1b3c715b7b2f57228e78e34039d2b967f54a58e345bc91e3dd54c7bea86d73c9e2de968736bf2b97f50bea891aa3519ae7238d76dff57cabba7cc0d370775657f3b5c83";
    //        BigInteger sixthtest = new BigInteger(name,16);
    //        System.out.println("publicKey.getModulus():"+sixthtest.toString());
    //
    //
    //        String name1="10001";
    //        BigInteger sixthtest1 = new BigInteger(name1,16);
    //        System.out.println("pubkey exponent:"+sixthtest1.toString());
    //        String name2="4de9ca08bc97cab4f6b88db25203af709c5bae1a99de2269896b00f61a3ca886e5f56e66380ec1de7c97c6d19cb31a09c8b3714ae5e1d8e4658917b29a026db9e1dd79e7333a7419302cd526c9c2bec27ab7117d2fb31b51acfa4554815bf474414bd5faf0276f7cb98753658abedbed79efd940c14269d8b7a2c83422fa2181";
    //        BigInteger sixthtest2 = new BigInteger(name2,16);
    //        System.out.println("private exponent:"+sixthtest2.toString());
        }
    }
    

    此处,要在应用的项目中添加一个jar包。

    相关文章

      网友评论

          本文标题:RSA加密

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