文档章节

java和.net相互http请求并且经过des的cbc模式加密解密

咖啡加糖
 咖啡加糖
发布于 2014/09/23 16:35
字数 2063
阅读 40
收藏 0

前端时间接了个需求,要求是和.net的一下停做对接,说到底就是,互相http发送get'或者post请求,之间遇到了一些问题,记录下来

手下发下java发送http的post请求的代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;




public class HttpTest2 {

/**
     * 向指定 URL 发送POST方法的请求
     * 
     * @param url
     *            发送请求的 URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("content-type", "text/html");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!"+e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    } 
    
    
    public static void main(String[] args) {
   
        String sr=HttpTest2.sendPost("路径", “参数”);

        System.out.println(sr);
  
    }
}

这里有个问题必须要说明

因为我用的是struts2,这个地方我遇到一个问题,就是如果conn.setRequestProperty("content-type", "text/html");这个地方只能是text/html,如果改成application/x-www-form-urlencoded这样一直无法获取,这个原因不清楚,网上说struts2中必须是text/html,其他的无法获取。


然后就是加密和解密了 ,用的是des的cbs模式,代码如下

package com.besttone.commons;


import java.net.URLDecoder;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;


import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;


import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class DESUtil2 {

/**
  *
  * @return DES算法密钥
  */
  public static byte[] generateKey() {
       try {


           // DES算法要求有一个可信任的随机数源
           SecureRandom sr = new SecureRandom();


           // 生成一个DES算法的KeyGenerator对象
           KeyGenerator kg = KeyGenerator.getInstance("DES");
           kg.init(sr);


           // 生成密钥
           SecretKey secretKey = kg.generateKey();


           // 获取密钥数据
           byte[] key = secretKey.getEncoded();


           return key;
       } catch (NoSuchAlgorithmException e) {
           System.err.println("DES算法,生成密钥出错!");
           e.printStackTrace();
       }


       return null;
  }


  /**
  * 加密函数
  *
  * @param data
  *            加密数据
  * @param key
  *            密钥
  * @return 返回加密后的数据
  */
  public static byte[] encrypt(byte[] data, byte[] key) {


       try {


           // DES算法要求有一个可信任的随机数源
           SecureRandom sr = new SecureRandom();


           // 从原始密钥数据创建DESKeySpec对象
           DESKeySpec dks = new DESKeySpec(key);


           // 创建一个密匙工厂,然后用它把DESKeySpec转换成
           // 一个SecretKey对象
           SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
           SecretKey secretKey = keyFactory.generateSecret(dks);


           // using DES in ECB mode
           Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");


           // 用密匙初始化Cipher对象
           cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);


           // 执行加密操作
           byte encryptedData[] = cipher.doFinal(data);


           return encryptedData;
       } catch (Exception e) {
           System.err.println("DES算法,加密数据出错!");
           e.printStackTrace();
       }


       return null;
  }


  /**
  * 解密函数
  *
  * @param data
  *            解密数据
  * @param key
  *            密钥
  * @return 返回解密后的数据
  */
  public static byte[] decrypt(byte[] data, byte[] key) {
       try {
           // DES算法要求有一个可信任的随机数源
           SecureRandom sr = new SecureRandom();


           // byte rawKeyData[] = /* 用某种方法获取原始密匙数据 */;


           // 从原始密匙数据创建一个DESKeySpec对象
           DESKeySpec dks = new DESKeySpec(key);


           // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成
           // 一个SecretKey对象
           SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
           SecretKey secretKey = keyFactory.generateSecret(dks);


           // using DES in ECB mode
           Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");


           // 用密匙初始化Cipher对象
           cipher.init(Cipher.DECRYPT_MODE, secretKey, sr);


           // 正式执行解密操作
           byte decryptedData[] = cipher.doFinal(data);


           return decryptedData;
       } catch (Exception e) {
           System.err.println("DES算法,解密出错。");
           e.printStackTrace();
       }


       return null;
  }


  /**
  * 加密函数
  *
  * @param data
  *            加密数据
  * @param key
  *            密钥
  * @return 返回加密后的数据
  */
  public static byte[] CBCEncrypt(byte[] data, byte[] key, byte[] iv) {


       try {
           // 从原始密钥数据创建DESKeySpec对象
           DESKeySpec dks = new DESKeySpec(key);


           // 创建一个密匙工厂,然后用它把DESKeySpec转换成
           // 一个SecretKey对象
           SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
           SecretKey secretKey = keyFactory.generateSecret(dks);


           // Cipher对象实际完成加密操作
           Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
           // 若采用NoPadding模式,data长度必须是8的倍数
           // Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");


           // 用密匙初始化Cipher对象
           IvParameterSpec param = new IvParameterSpec(iv);
           cipher.init(Cipher.ENCRYPT_MODE, secretKey, param);


           // 执行加密操作
           byte encryptedData[] = cipher.doFinal(data);


           return encryptedData;
       } catch (Exception e) {
           System.err.println("DES算法,加密数据出错!");
           e.printStackTrace();
       }


       return null;
  }


  /**
  * 解密函数
  *
  * @param data
  *            解密数据
  * @param key
  *            密钥
  * @return 返回解密后的数据
  */
  public static byte[] CBCDecrypt(byte[] data, byte[] key, byte[] iv) {
       try {
           // 从原始密匙数据创建一个DESKeySpec对象
           DESKeySpec dks = new DESKeySpec(key);


           // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成
           // 一个SecretKey对象
           SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
           SecretKey secretKey = keyFactory.generateSecret(dks);


           // using DES in CBC mode
           Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
           // 若采用NoPadding模式,data长度必须是8的倍数
           // Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");


           // 用密匙初始化Cipher对象
           IvParameterSpec param = new IvParameterSpec(iv);
           cipher.init(Cipher.DECRYPT_MODE, secretKey, param);


           // 正式执行解密操作
           byte decryptedData[] = cipher.doFinal(data);


           return decryptedData;
       } catch (Exception e) {
           System.err.println("DES算法,解密出错。");
           e.printStackTrace();
       }


       return null;
  }


  public static void main(String[] args) {
  try {
           byte[] key = "NEMOBIlE".getBytes("utf-8");
           byte[] iv = "NEMOBIlE".getBytes("utf-8");
           byte[] data = DESUtil2.CBCEncrypt("XXXXX".getBytes("utf-8"), key, iv);
           //加密转换  
           BASE64Encoder enc = new BASE64Encoder(); 
           
           BASE64Decoder dec = new BASE64Decoder(); 
           String encryptedtext = enc.encode(data); 
           System.out.println("加密后:" + encryptedtext);
           System.out.println("加密后:" + java.net.URLEncoder.encode(encryptedtext,"utf-8"));
           String aaa= java.net.URLDecoder.decode(java.net.URLEncoder.encode(encryptedtext,"utf-8"),"utf-8");
           byte[] resultArr = dec.decodeBuffer(aaa);
           System.out.println("解密后:" + new String(DESUtil2.CBCDecrypt(resultArr, key, iv)));
           
       } catch (Exception e) {
           e.printStackTrace();
       }
  } 
}

这里需要说明的是,如果是post请求,一般加过密后就不需要做.URLEncoder.encode的操作了,获取进行解密就行,但是如果是url的方式,

那么加密后必须要做URLEncoder.encode转换的,然后获取在直接进行解密,不然会出现问题的,

下面发下  .net的des加密代码

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
 
using System.Security.Cryptography;
using System.IO;
using System.Text;


namespace MobileCommonPay.Tool
{
    public class DES2
    {


        // CBC模式


        string iv = "NEMOBIlE";
        string key = "NEMOBIlE";


        /// <summary>
        /// DES加密偏移量,必须是>=8位长的字符串
        /// </summary>
        public string IV
        {
            get { return iv; }
            set { iv = value; }
        }


        /// <summary>
        /// DES加密的私钥,必须是8位长的字符串
        /// </summary>
        public string Key
        {
            get { return key; }
            set { key = value; }
        }


        /// <summary>
        /// 对字符串进行DES加密
        /// </summary>
        /// <param name="sourceString">待加密的字符串</param>
        /// <returns>加密后的BASE64编码的字符串</returns>
        public string Encrypt(string sourceString)
        {
            byte[] btKey = Encoding.Default.GetBytes(key);
            byte[] btIV = Encoding.Default.GetBytes(iv);
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            using (MemoryStream ms = new MemoryStream())
            {
                byte[] inData = Encoding.Default.GetBytes(sourceString);
                try
                {
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(inData, 0, inData.Length);
                        cs.FlushFinalBlock();
                    }
                    return Convert.ToBase64String(ms.ToArray());
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }
        }


        /// <summary>
        /// 对DES加密后的字符串进行解密
        /// </summary>
        /// <param name="encryptedString">待解密的字符串</param>
        /// <returns>解密后的字符串</returns>
        public string Decrypt(string encryptedString)
        {
            byte[] btKey = Encoding.Default.GetBytes(key);
            byte[] btIV = Encoding.Default.GetBytes(iv);
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();


            using (MemoryStream ms = new MemoryStream())
            {
                byte[] inData = Convert.FromBase64String(encryptedString);
                try
                {
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(inData, 0, inData.Length);
                        cs.FlushFinalBlock();
                    }
                    return Encoding.Default.GetString(ms.ToArray());
                }
                catch (Exception ex)
                {
                    return ex.Message;
                }
            }
        }


        /// <summary>
        /// 对文件内容进行DES加密
        /// </summary>
        /// <param name="sourceFile">待加密的文件绝对路径</param>
        /// <param name="destFile">加密后的文件保存的绝对路径</param>
        public void EncryptFile(string sourceFile, string destFile)
        {
            if (!File.Exists(sourceFile)) throw new FileNotFoundException("指定的文件路径不存在!", sourceFile);


            byte[] btKey = Encoding.Default.GetBytes(key);
            byte[] btIV = Encoding.Default.GetBytes(iv);
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] btFile = File.ReadAllBytes(sourceFile);


            using (FileStream fs = new FileStream(destFile, FileMode.Create, FileAccess.Write))
            {
                try
                {
                    using (CryptoStream cs = new CryptoStream(fs, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(btFile, 0, btFile.Length);
                        cs.FlushFinalBlock();
                    }
                }
                catch
                {
                    throw;
                }
                finally
                {
                    fs.Close();
                }
            }
        }


        /// <summary>
        /// 对文件内容进行DES加密,加密后覆盖掉原来的文件
        /// </summary>
        /// <param name="sourceFile">待加密的文件的绝对路径</param>
        public void EncryptFile(string sourceFile)
        {
            EncryptFile(sourceFile, sourceFile);
        }


        /// <summary>
        /// 对文件内容进行DES解密
        /// </summary>
        /// <param name="sourceFile">待解密的文件绝对路径</param>
        /// <param name="destFile">解密后的文件保存的绝对路径</param>
        public void DecryptFile(string sourceFile, string destFile)
        {
            if (!File.Exists(sourceFile)) throw new FileNotFoundException("指定的文件路径不存在!", sourceFile);


            byte[] btKey = Encoding.Default.GetBytes(key);
            byte[] btIV = Encoding.Default.GetBytes(iv);
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] btFile = File.ReadAllBytes(sourceFile);


            using (FileStream fs = new FileStream(destFile, FileMode.Create, FileAccess.Write))
            {
                try
                {
                    using (CryptoStream cs = new CryptoStream(fs, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(btFile, 0, btFile.Length);
                        cs.FlushFinalBlock();
                    }
                }
                catch
                {
                    throw;
                }
                finally
                {
                    fs.Close();
                }
            }
        }


        /// <summary>
        /// 对文件内容进行DES解密,加密后覆盖掉原来的文件
        /// </summary>
        /// <param name="sourceFile">待解密的文件的绝对路径</param>
        public void DecryptFile(string sourceFile)
        {
            DecryptFile(sourceFile, sourceFile);
        }
    }
}


.net中加密解密的问题,主要就是编码Encoding.Default这样默认的就不是utf-8了,这样加密出问题,这个时候要换成Encoding.GetEncoding("UTF-8")这样就可以了,

最后说下,对接真是麻烦,遇到好说话的人还好,如果遇到一些不好搞的人,那真是头疼的........


© 著作权归作者所有

咖啡加糖

咖啡加糖

粉丝 17
博文 21
码字总数 18836
作品 0
南京
程序员
私信 提问
Android平台和java平台 DES加密解密互通程序及其不能互通的原因 .

网上的demo一搜一大堆,但是,基本上都是一知半解(包括我)。为什么呢?我在尝试分别在两个平台加密的时候,竟然发现Android DES 加密和java DES加密的程序不能互通。就是加密的结果不一样,...

鉴客
2011/12/26
8.7K
11
Node系统模块crypto实现md5 Cipher等多种加密方式

crypto加密模块是C/C++实现这些算法后,暴露为javascript接口的模块,包含对 OpenSSL 的哈希、HMAC、加密、解密、签名、以及验证功能的一整套封装。Cipher Cipher类用于加密数据,属于对称密...

曲先森
2018/07/31
0
0
对称加密算法DES、3DES原理和实现方式

1、对称加密算法 1.1 定义 对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文(原始数据)和加密密钥(mi yue)一起经过特殊加密算法处理后,使其变成复杂的...

zchuanzhao
2015/11/04
0
0
java与C++通过des、blowfish互相加解密

在简单的服务器端与客户端通信的应用中,这种做法比较常见 DES、blowfish扫盲: 1.des的常见模式分为四种 ECB / CBC / CFB / OFB 这里使用默认的ECB ECB的缺陷:能从密文看出明文的规律 加密...

sumekey
2011/11/05
0
0
实现ios上传加密nodejs后台解密

今天在做项目的时候遇到一个问题,我需要在ios端把上传数据加密,防止中间代理捕获信息内容并修改数据库的信息。把数据传到后台在解码,实现数据安全。 下面介绍我实现的在nodejs的加密和解密...

90后爱国
2014/08/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

为什么重复的GET请求变慢了?

最近在研究慢请求监控的问题,写了一个简单的测试代码:在网页端(index.html)通过fetch函数向服务端获取数据,然后打印请求耗时。 function requestData() { let start = new Date(); ...

Fundebug
24分钟前
6
0
5年时间,我从开发做到总裁的秘籍--如何提升技术型管理者的领导力

作者:阿里云MVP 肖凯 对于深耕技术的一线开发者而言,大多数都希望把技术工作进行到底,或者一直从事和技术技术相关性更高的工作。但随着年龄和经验的增长,我对管理和技术的思考越来越多、...

阿里云云栖社区
30分钟前
3
0
LeetCode 142:环形链表 II Linked List Cycle II

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 ...

iCodeBugs
31分钟前
3
0
使用Shell脚本程序监控网站URL是否正常

导读 监控网站URL是否正常最常见的方法莫过于wget和curl命令了,这两个命令都是非常强大的,强大到网友查看帮助都无从选择的地步了,今天呢,老男孩老师正好录制Shell编程实战课程。 wget命令...

问题终结者
32分钟前
3
0
教你用Python制作微信好友背景墙

目录: 0 引言 1 环境 2 代码实现 3 后记 0 引言 前段时间,微信朋友圈开始出现了一种晒照片新形式,微信好友墙,即在一张大图片中展示出自己的所有微信好友的头像。 效果如下图,出于隐私考...

上海小胖
40分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部