httpclient Post请求 参数用des加密

需求如下,提供远程调用的借口,参数加密。

直接上代码

des加密算法代码:
 

package com.ruisitech.bi.util;

import java.security.SecureRandom;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * 类  名  称:AESEncryptTools   
 * 类  描  述:DES加密解密算法
 */
public final class DESEncryptTools {

    static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(DESEncryptTools.class);

    //加密算是des
    private static final String ALGORITHM = "DES";
    //转换格式
    private static final String TRANSFORMATION = "DES/ECB/PKCS5Padding";

    private static String key = "134xmkd766";


    //利用8个字节64位的key给src加密
    public static byte[] encrypt(byte[] src) {
        try {
            //加密
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(ALGORITHM);
            KeySpec keySpec = new DESKeySpec(key.getBytes());
            SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
            secureRandom.setSeed(key.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, secureRandom);
            byte[] enMsgBytes = cipher.doFinal(src);
            return enMsgBytes;
        } catch (Exception e) {
            e.printStackTrace();
            logger.info(e);
        }
        return null;
    }

    //利用8个字节64位的key给src解密
    public static byte[] decrypt(byte[] encryptBytes){
        try {
            Cipher deCipher = Cipher.getInstance(TRANSFORMATION);
            SecretKeyFactory deDecretKeyFactory = SecretKeyFactory.getInstance(ALGORITHM);
            KeySpec deKeySpec = new DESKeySpec(key.getBytes());
            SecretKey deSecretKey = deDecretKeyFactory.generateSecret(deKeySpec);
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
            secureRandom.setSeed(key.getBytes());

            deCipher.init(Cipher.DECRYPT_MODE, deSecretKey, secureRandom);
            byte[] deMsgBytes = deCipher.doFinal(encryptBytes);
            return deMsgBytes;
        } catch (Exception e) {
            e.printStackTrace();
            logger.info(e);
        }
        return null;
    }


    public static void main(String[] args) throws Exception{
        String msg = "123";
        System.out.println("加密前:"+msg);
        byte[] encryptBytes = DESEncryptTools.encrypt(msg.getBytes());
        System.out.println("加密后:"+new String(encryptBytes));
        byte[] deMsgBytes = DESEncryptTools.decrypt(encryptBytes);
        System.out.println("解密后:"+new String(deMsgBytes));
    }
}

响应端代码

package com.ruisitech.bi.web.custombi;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
/**
 * @author:mazhen
 * @date:2018/12/6 17:48:
 * @description: 后台数据筛选功能对应控制器
 */
@Controller
@RequestMapping(value = "/userFilter")
public class UserFilterController {
    static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(UserFilterController.class);

    @RequestMapping(value="/queryBossWithUid.action", method = RequestMethod.POST)
    //  此时方法默认为 get方式
//    @RequestMapping(value="/queryBossWithUid.action")
    public @ResponseBody
    Object saveRhQueryCondition1(HttpServletRequest req, HttpServletResponse res) {

        String uid = req.getParameter(UserFilterConstants.TYPE_UID);
        BASE64Decoder base64decoder = new BASE64Decoder();
        try {
            byte[] encodeByte = base64decoder.decodeBuffer(uid);
            uid = new String(DESEncryptTools.decrypt(encodeByte));

        } catch (IOException e) {
            e.printStackTrace();
            logger.info(e);
        }
        //这里进行具体的业务处理并返回
        HashMap<String, String> hashMap = new HashMap<String, String>();
        hashMap.put("status","UP");
        String  str = JSONObject.toJSON(hashMap).toString();
        return str;
    }


}

客户端请求

package com.ruisitech.bi.util;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import sun.misc.BASE64Encoder;

/**
 * @author:mazhen
 * @date:2018/12/28 14:17:
 * @description:
 */
public class HttpClientUtil {

        public static void main(String[] args) {
            // 请求接口地址
            String url = "http://localhost:8080/rsbi/userFilter/queryBossWithUid.action";
//            String url = "http://localhost:8080/rsbi/alarm/updateAlarmCountResultTxtNum.action";
            // 请求参数
            String uid = "123";

            HttpClient httpclient = null;
            PostMethod post = null;
            GetMethod get = null;
            try {
                //创建连接
                httpclient = new HttpClient();
                // post方式
                post = new PostMethod(url);
                // 设置编码方式
                post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
                System.out.println(new String(DESEncryptTools.encrypt(uid.getBytes())));
                // 不编解码的话,请求端加密后在是服务端无法将解密
                BASE64Encoder base64encoder = new BASE64Encoder();
                String encode=base64encoder.encode(DESEncryptTools.encrypt(uid.getBytes()));

                // 添加参数
                post.addParameter("uid", encode);
//                post.addParameter("uid", new String(DESEncryptTools.encrypt(uid.getBytes())));
                // 执行请求
                int i = httpclient.executeMethod(post);
                // 接口返回信息
                String info = new String(post.getResponseBody(), "UTF-8");


                // get方式
//                // 因为加密后的字符问题,会报异常,如java.lang.IllegalArgumentException:
//                //  Invalid uri 'http://localhost:8080/rsbi/userFilter/queryBossWithUid.action?uid=[B@65fb9ffc': Invalid query
//                get = new GetMethod(url+"?uid="+DESEncryptTools.encrypt(uid.getBytes()));
//                // 设置编码方式
//                get.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
                get.
//                // 添加参数
                get.addParameter("uid", uid);
//                // 执行请求
//                int i = httpclient.executeMethod(get);
//                // 接口返回信息
//                String info = new String(get.getResponseBody(), "UTF-8");

                System.out.println(info);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 关闭连接,释放资源
                post.releaseConnection();
                ((SimpleHttpConnectionManager) httpclient.getHttpConnectionManager()).shutdown();
            }
        }
}

现在分享下开发过程中遇到的问题:

1对传参加密后导致get方式接口无法调用,就是编码后导致url中会有各种特殊字符

对uid加密后报错如下:
java.lang.IllegalArgumentException: Invalid uri 'http://localhost:8080/rsbi/userFilter/queryBossWithUid.action?uid=[B@65fb9ffc': Invalid query

解决方案:将post修改为get方式,在方法上增加method = RequestMethod.POST

 

2请求端加密后在是服务端无法将加密

//报错如下:
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
原因一
SecureRandom 实现完全隨操作系统本身的內部狀態,除非調用方在調用 getInstance 方法之後又調用了 setSeed 方法;该实现在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系统上则不同。

原因二:
1、加密完byte[] 后,需要将加密了的byte[] 转换成base64保存,如: 
BASE64Encoder base64encoder = new BASE64Encoder(); 
String encode=base64encoder.encode(bytes); 

2、解密前,需要将加密后的字符串从base64转回来再解密,如: 
BASE64Decoder base64decoder = new BASE64Decoder(); 
byte[] encodeByte = base64decoder.decodeBuffer(str); 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值