前端時間接了個需求,要求是和.net的一下停作對接,說到底就是,互相http發送get'或者post請求,之間遇到了一些問題,記錄下來html
手下發下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);
}
}
java
這裏有個問題必需要說明算法
由於我用的是struts2,這個地方我遇到一個問題,就是若是conn.setRequestProperty("content-type", "text/html");這個地方只能是text/html,若是改爲application/x-www-form-urlencoded這樣一直沒法獲取,這個緣由不清楚,網上說struts2中必須是text/html,其餘的沒法獲取。app
而後就是加密和解密了 ,用的是des的cbs模式,代碼以下dom
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();
}
}
}
ide
這裏須要說明的是,若是是post請求,通常加過密後就不須要作.URLEncoder.encode的操做了,獲取進行解密就行,可是若是是url的方式,函數
那麼加密後必需要作URLEncoder.encode轉換的,而後獲取在直接進行解密,否則會出現問題的,post
下面發下 .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")這樣就能夠了,
最後說下,對接真是麻煩,遇到好說話的人還好,若是遇到一些很差搞的人,那真是頭疼的........