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

求助: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 webAPI接口返回值判断
  • ¥15 自动化测试 UI Automtion
  • ¥20 关于#深度学习#的问题:2708)输出:邻接矩阵A 或者 节点索引方式:通过随机游走或者其他方式,保持节点连接类似下图(语言-python)
  • ¥15 win2012 iscsi ipsec
  • ¥15 封装的 matplotlib animation 不显示图像
  • ¥15 python摄像头画面无法显示
  • ¥15 关于#3d#的问题:d标定算法(语言-python)
  • ¥15 cve,cnnvd漏洞扫描工具推荐
  • ¥15 图像超分real-esrgan网络自己训练模型遇到问题
  • ¥15 如何构建全国统一的物流管理平台?