java小兵 2021-06-19 20:27 采纳率: 80%
浏览 108
已采纳

求助:RSA加密发送http请求失败

菜鸟求助,这个接口怎样加密,才能发送请求成功,自己搞了半天也没解决。最好把加密代码提供下,感觉不尽!

接口信息:

测试接口地址 URL: http://221.13.13.133:21974

请求方式:POST

Content-Type:application/x-www-form-urlencoded

请求参数:

  unitCode:软件服务商统一社会信用代码
  projectId:项目ID
  data: 加密后的数据

数据加密说明:

接口平台为每个接入平台颁发一个数字证书(一对公私钥),接入平台必须通过数字证书的公钥对上行数据进行RSA加密 后再进行Base64编码后提交。 签名加密规则:

  1. 加密算法RSA密钥位数1024;
  2. 签名算法SHA256WithRSA;
  3. 加解密Cipher算法:RAS/ECB/PKCS1Padding;
  4. 加密原始数据为JSON字符串;
  5. 加密最终为Base64编码数据;字符串统一采用UTF-8编码格式。

 

测试数据:

projectId:1270995441467150337

unitCode:9133011009519461XC

data: {"address":"安徽宿州","authType":"1","backPhoto":"https://uniubi-aiot.oss-cn-hangzhou.aliyuncs.com/device/84E0F424B99851FA/20210217083909_243_rgb.jpg","educationCode":"6","frontPhoto":"https://uniubi-aiot.oss-cn-hangzhou.aliyuncs.com/device/84E0F424B99851FA/20210217083909_243_rgb.jpg","headImageUrl":"https://uniubi-aiot.oss-cn-hangzhou.aliyuncs.com/device/84E0F424B99851FA/20210217083909_243_rgb.jpg","idCard":"340881199705260330","majorHistoryB":false,"nation":"汉族","personType":"03","phone":"15988776666","signOrg":"杭州市上城区公安局","trueName":"严佳勇","validityPeriod":"2012010120200101"}

公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXGI8/U6r8m8bxrF+nb3ONgEUgcykJyo7ZyrAfzX8pbU/t58p89B5O2+zM2ArKBfX5krnUfdMM4DNhPh6HaR+TIFB6qbNCoaQY2IUP9RfsC/vo0Yyz7hZjrThwy+fLfQxZz5jCnrND4lUfKYk8Zh+SzFIsO4HOnsFiGOTIepyOtQIDAQAB

私钥:MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJcYjz9TqvybxvGsX6dvc42ARSBzKQnKjtnKsB/NfyltT+3nynz0Hk7b7MzYCsoF9fmSudR90wzgM2E+HodpH5MgUHqps0KhpBjYhQ/1F+wL++jRjLPuFmOtOHDL58t9DFnPmMKes0PiVR8piTxmH5LMUiw7gc6ewWIY5Mh6nI61AgMBAAECgYBvjnd89wZAebc6Cd2Z3qS/LZxcKAp9qysrTAYbhPrFGGsyKLgM56RU7vV4DG5y2FHS0W0YoUmosQPeYSHjMk9XizWc4RC5h3KX1FThEJgA/bGmv1kY7zURkCukq4RZRJDTc2LkQM7+ihFDyBt9fruROC48mzzV92V639iSO1tDxQJBANHZZUl5bsXBozRSjMBWc/WghLUvvdmJcsm4fQfYdXNsDYylGRAxi5wludHtzrIL1rpIuYtGh0SxW54Ak7Y71B8CQQC4U1QhW960MtbeWp56HbxDvK3SDRTDvEXIF8+1hAdFPFipaMShci8+y4uz9FiDWYDI0nU0SjEqsVuYQJjITmKrAkBo0TzNcXFKKAl8Fgul+sjbFL2Uvu8GXKhQZ+1T4OPxrjQqX0DgnM7ORO3HFRCcUFuGGtNK5QSl5C0OA93ENagjAkBAllJAbiSXF8lamH43Y/v38EEn/RVtkKcS+eT6QY0aoY6frepYd94+LqyBHfl17QLHW5dd/zFDOGpT6y6d4XmJAkAM1DD/QlzsD23zj+HeCiFY5EqEMvB3evi+yqdZ5J5th1VK4ywfeWwUueWDd3yyJy8sK+4vNmvuQci/zBbKU0+n

 

 

  • 写回答

2条回答 默认 最新

  • CX0405 2021-06-21 14:17
    关注
    package com.example.demo1;
    
    import javax.crypto.Cipher;
    import javax.crypto.NoSuchPaddingException;
    import java.io.ByteArrayOutputStream;
    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.Base64;
    import java.util.HashMap;
    import java.util.Map;
    
    public class TestRSA
    {
        /**
         * 测试方法
         */
        public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException {
            String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXGI8/U6r8m8bxrF+nb3ONgEUgcykJyo7ZyrAfzX8pbU/t58p89B5O2+zM2ArKBfX5krnUfdMM4DNhPh6HaR+TIFB6qbNCoaQY2IUP9RfsC/vo0Yyz7hZjrThwy+fLfQxZz5jCnrND4lUfKYk8Zh+SzFIsO4HOnsFiGOTIepyOtQIDAQAB";
            String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJcYjz9TqvybxvGsX6dvc42ARSBzKQnKjtnKsB/NfyltT+3nynz0Hk7b7MzYCsoF9fmSudR90wzgM2E+HodpH5MgUHqps0KhpBjYhQ/1F+wL++jRjLPuFmOtOHDL58t9DFnPmMKes0PiVR8piTxmH5LMUiw7gc6ewWIY5Mh6nI61AgMBAAECgYBvjnd89wZAebc6Cd2Z3qS/LZxcKAp9qysrTAYbhPrFGGsyKLgM56RU7vV4DG5y2FHS0W0YoUmosQPeYSHjMk9XizWc4RC5h3KX1FThEJgA/bGmv1kY7zURkCukq4RZRJDTc2LkQM7+ihFDyBt9fruROC48mzzV92V639iSO1tDxQJBANHZZUl5bsXBozRSjMBWc/WghLUvvdmJcsm4fQfYdXNsDYylGRAxi5wludHtzrIL1rpIuYtGh0SxW54Ak7Y71B8CQQC4U1QhW960MtbeWp56HbxDvK3SDRTDvEXIF8+1hAdFPFipaMShci8+y4uz9FiDWYDI0nU0SjEqsVuYQJjITmKrAkBo0TzNcXFKKAl8Fgul+sjbFL2Uvu8GXKhQZ+1T4OPxrjQqX0DgnM7ORO3HFRCcUFuGGtNK5QSl5C0OA93ENagjAkBAllJAbiSXF8lamH43Y/v38EEn/RVtkKcS+eT6QY0aoY6frepYd94+LqyBHfl17QLHW5dd/zFDOGpT6y6d4XmJAkAM1DD/QlzsD23zj+HeCiFY5EqEMvB3evi+yqdZ5J5th1VK4ywfeWwUueWDd3yyJy8sK+4vNmvuQci/zBbKU0+n";
    
            String str = "{\"address\":\"安徽宿州\",\"authType\":\"1\",\"backPhoto\":\"https://uniubi-aiot.oss-cn-hangzhou.aliyuncs.com/device/84E0F424B99851FA/20210217083909_243_rgb.jpg\",\"educationCode\":\"6\",\"frontPhoto\":\"https://uniubi-aiot.oss-cn-hangzhou.aliyuncs.com/device/84E0F424B99851FA/20210217083909_243_rgb.jpg\",\"headImageUrl\":\"https://uniubi-aiot.oss-cn-hangzhou.aliyuncs.com/device/84E0F424B99851FA/20210217083909_243_rgb.jpg\",\"idCard\":\"340881199705260330\",\"majorHistoryB\":false,\"nation\":\"汉族\",\"personType\":\"03\",\"phone\":\"15988776666\",\"signOrg\":\"杭州市上城区公安局\",\"trueName\":\"严佳勇\",\"validityPeriod\":\"2012010120200101\"}";
            // 公钥加密,私钥解密
            String enStr1 = TestRSA.encryptByPublicKey(str, publicKey);
            System.out.println("公钥加密后:" + enStr1);
            String deStr1 = TestRSA.decryptByPrivateKey(enStr1, privateKey);
            System.out.println("私钥解密后:" + deStr1);
    
            // 产生签名
            String sign = sign(enStr1, privateKey);
            System.out.println("签名:" + sign);
            // 验证签名
            boolean status = verify(enStr1, publicKey, sign);
            System.out.println("状态:" + status);
    
        }
    
        //定义加密方式
        public static final String KEY_RSA = "RSA";
        //定义公钥关键词
        public static final String KEY_RSA_PUBLICKEY = "RSAPublicKey";
        //定义私钥关键词
        public static final String KEY_RSA_PRIVATEKEY = "RSAPrivateKey";
        //定义签名算法
        private final static String KEY_RSA_SIGNATURE = "SHA256WithRSA";
        /**
         * **
         * RSA最大加密大小
         */
        private final static int MAX_ENCRYPT_BLOCK = 117;
    
        /**
         * **
         * RSA最大解密大小
         */
        private final static int MAX_DECRYPT_BLOCK = 128;
    
        /**
         * 生成公私密钥对
         */
        public static Map<String, Object> init()
        {
            Map<String, Object> map = null;
            try
            {
                KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA);
                //设置密钥对的bit数,越大越安全,但速度减慢,一般使用512或1024
                generator.initialize(1024);
                KeyPair keyPair = generator.generateKeyPair();
                // 获取公钥
                RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
                // 获取私钥
                RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
                // 将密钥对封装为Map
                map = new HashMap<String, Object>();
                map.put(KEY_RSA_PUBLICKEY, publicKey);
                map.put(KEY_RSA_PRIVATEKEY, privateKey);
            } catch (NoSuchAlgorithmException e)
            {
                e.printStackTrace();
            }
    
            return map;
        }
    
        /**
         * 获取Base64编码的公钥字符串
         */
        public static String getPublicKey(Map<String, Object> map)
        {
            String str = "";
            Key key = (Key) map.get(KEY_RSA_PUBLICKEY);
            str = encryptBase64(key.getEncoded());
            return str;
        }
    
        /**
         * 获取Base64编码的私钥字符串
         */
        public static String getPrivateKey(Map<String, Object> map)
        {
            String str = "";
            Key key = (Key) map.get(KEY_RSA_PRIVATEKEY);
            str = encryptBase64(key.getEncoded());
            return str;
        }
    
        /**
         * BASE64 解码
         *
         * @param key 需要Base64解码的字符串
         * @return 字节数组
         */
        public static byte[] decryptBase64(String key)
        {
            return Base64.getDecoder().decode(key);
        }
    
        /**
         * BASE64 编码
         *
         * @param key 需要Base64编码的字节数组
         * @return 字符串
         */
        public static String encryptBase64(byte[] key)
        {
            return new String(Base64.getEncoder().encode(key));
        }
    
        /**
         * 公钥加密
         *
         * @param encryptingStr
         * @param publicKeyStr
         * @return
         */
        public static String encryptByPublicKey(String encryptingStr, String publicKeyStr)
        {
            try
            {
                // 将公钥由字符串转为UTF-8格式的字节数组
                byte[] publicKeyBytes = decryptBase64(publicKeyStr);
                // 获得公钥
                X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
                // 取得待加密数据
                byte[] data = encryptingStr.getBytes("UTF-8");
                KeyFactory factory;
                factory = KeyFactory.getInstance(KEY_RSA);
                PublicKey publicKey = factory.generatePublic(keySpec);
                // 对数据加密
                Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
                // 返回加密后由Base64编码的加密信息
                int inputLen = data.length;
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                int offSet = 0;
                byte[] cache;
                int i = 0;
                // 对数据分段解密
                while (inputLen - offSet > 0)
                {
                    if (inputLen - offSet > MAX_ENCRYPT_BLOCK)
                    {
                        cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                    } else
                    {
                        cache = cipher.doFinal(data, offSet, inputLen - offSet);
                    }
                    out.write(cache, 0, cache.length);
                    i++;
                    offSet = i * MAX_ENCRYPT_BLOCK;
                }
                byte[] decryptedData = out.toByteArray();
                out.close();
                return encryptBase64(decryptedData);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
        /**
         * 私钥解密
         *
         * @param encryptedStr
         * @param privateKeyStr
         * @return
         */
        public static String decryptByPrivateKey(String encryptedStr, String privateKeyStr)
        {
            try
            {
                // 对私钥解密
                byte[] privateKeyBytes = decryptBase64(privateKeyStr);
                // 获得私钥
                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
                // 获得待解密数据
                byte[] data = decryptBase64(encryptedStr);
                KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
                PrivateKey privateKey = factory.generatePrivate(keySpec);
                // 对数据解密
                Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                // 返回UTF-8编码的解密信息
                int inputLen = data.length;
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                int offSet = 0;
                byte[] cache;
                int i = 0;
                // 对数据分段解密
                while (inputLen - offSet > 0)
                {
                    if (inputLen - offSet > MAX_DECRYPT_BLOCK)
                    {
                        cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
                    } else
                    {
                        cache = cipher.doFinal(data, offSet, inputLen - offSet);
                    }
                    out.write(cache, 0, cache.length);
                    i++;
                    offSet = i * MAX_DECRYPT_BLOCK;
                }
                byte[] decryptedData = out.toByteArray();
                out.close();
                return new String(decryptedData, "UTF-8");
            } catch (Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
        /**
         * 私钥加密
         *
         * @param encryptingStr
         * @param privateKeyStr
         * @return
         */
        public static String encryptByPrivateKey(String encryptingStr, String privateKeyStr)
        {
            try
            {
                byte[] privateKeyBytes = decryptBase64(privateKeyStr);
                // 获得私钥
                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
                // 取得待加密数据
                byte[] data = encryptingStr.getBytes("UTF-8");
                KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
                PrivateKey privateKey = factory.generatePrivate(keySpec);
                // 对数据加密
                Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
                cipher.init(Cipher.ENCRYPT_MODE, privateKey);
                // 返回加密后由Base64编码的加密信息
                int inputLen = data.length;
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                int offSet = 0;
                byte[] cache;
                int i = 0;
                // 对数据分段解密
                while (inputLen - offSet > 0)
                {
                    if (inputLen - offSet > MAX_ENCRYPT_BLOCK)
                    {
                        cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                    } else
                    {
                        cache = cipher.doFinal(data, offSet, inputLen - offSet);
                    }
                    out.write(cache, 0, cache.length);
                    i++;
                    offSet = i * MAX_ENCRYPT_BLOCK;
                }
                byte[] decryptedData = out.toByteArray();
                out.close();
                return encryptBase64(decryptedData);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
        /**
         * 公钥解密
         *
         * @param encryptedStr
         * @param publicKeyStr
         * @return
         */
        public static String decryptByPublicKey(String encryptedStr, String publicKeyStr)
        {
            try
            {
                // 对公钥解密
                byte[] publicKeyBytes = decryptBase64(publicKeyStr);
                // 取得公钥
                X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
                // 取得待加密数据
                byte[] data = decryptBase64(encryptedStr);
                KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
                PublicKey publicKey = factory.generatePublic(keySpec);
                // 对数据解密
                Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
                cipher.init(Cipher.DECRYPT_MODE, publicKey);
                // 返回UTF-8编码的解密信息
                int inputLen = data.length;
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                int offSet = 0;
                byte[] cache;
                int i = 0;
                // 对数据分段解密
                while (inputLen - offSet > 0)
                {
                    if (inputLen - offSet > MAX_DECRYPT_BLOCK)
                    {
                        cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
                    } else
                    {
                        cache = cipher.doFinal(data, offSet, inputLen - offSet);
                    }
                    out.write(cache, 0, cache.length);
                    i++;
                    offSet = i * MAX_DECRYPT_BLOCK;
                }
                byte[] decryptedData = out.toByteArray();
                out.close();
                return new String(decryptedData, "UTF-8");
            } catch (Exception e)
            {
                e.printStackTrace();
            }
    
            return null;
        }
    
        /**
         * 用私钥对加密数据进行签名
         *
         * @param encryptedStr
         * @param privateKey
         * @return
         */
        public static String sign(String encryptedStr, String privateKey)
        {
            String str = "";
            try
            {
                //将私钥加密数据字符串转换为字节数组
                byte[] data = encryptedStr.getBytes();
                // 解密由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 encryptedStr
         * @param publicKey
         * @param sign
         * @return 校验成功返回true,失败返回false
         */
        public static boolean verify(String encryptedStr, String publicKey, String sign)
        {
            boolean flag = false;
            try
            {
                //将私钥加密数据字符串转换为字节数组
                byte[] data = encryptedStr.getBytes();
                // 解密由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;
        }
    }
    
    

    加密代码

     

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)