关于.net des解密报错的问题。

调用对方得接口,接口返回的字符串是用des加密的,我现在接收放回的加密字符串后,用.net的des解密算法解密,调试报错:要解密的数据的长度无效。 不知道是哪里的问题。我看给的例子用java的这几句就解开了, String str = new String(DesUtil.decrypt(DesUtil
.hexStr2ByteArr(bodyData)), "UTF-8");
String parameters = URLDecoder.decode(str, "UTF-8"); 但是我使用.net des解密就报错,请大神指点一下 。

得把你的代码贴出来才能看出问题呢

这是对方java加密使用的算法代码
package com.hisun.commonBusi.utils;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;

public class DESString {
private static String strDefaultKey = "WPS2SUG";

private Cipher encryptCipher = null;

private Cipher decryptCipher = null;

/**

  • 将16进制byte数组转换为表示16进制值的字符串, 如:byte[]{8,18}转换为:0813, 和public static byte[]
  • hexStr2ByteArr(String strIn) 互为可逆的转换过程
  • @param arrB
  • 需要转换的byte数组
  • @return 转换后的字符串
  • @throws Exception
  • 本方法不处理任何异常,所有异常全部抛出 */ public static String byteArr2HexStr(byte[] arrB) throws Exception { int iLen = arrB.length; // 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍 StringBuffer sb = new StringBuffer(iLen * 2); for (int i = 0; i < iLen; i++) { int intTmp = arrB[i]; // 把负数转换为正数 while (intTmp < 0) { intTmp = intTmp + 256; } // 小于0F的数需要在前面补0 if (intTmp < 16) { sb.append("0"); } sb.append(Integer.toString(intTmp, 16)); }

return new String(sb.toString().getBytes(), "UTF-8");
}

/**

  • 将表示16进制值的字符串转换为16进制byte数组, 和public static String byteArr2HexStr(byte[]
  • arrB) 互为可逆的转换过程
  • @param strIn
  • 需要转换的字符串
  • @return 转换后的byte数组
  • @throws Exception
  • 本方法不处理任何异常,所有异常全部抛出
  • */ public static byte[] hexStr2ByteArr(String strIn) throws Exception { byte[] arrB = strIn.getBytes("UTF-8"); int iLen = arrB.length;

// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
byte[] arrOut = new byte[iLen / 2];
for (int i = 0; i < iLen; i = i + 2) {
String strTmp = new String(arrB, i, 2, "UTF-8");
arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
}
return arrOut;
}

/**

  • 默认构造方法,使用默认密钥
  • @throws Exception */ public DESString() throws Exception { this(strDefaultKey); }

/**

  • 指定密钥构造方法
  • @param strKey
  • 指定的密钥
  • @throws Exception */ public DESString(String strKey) { Security.addProvider(new com.sun.crypto.provider.SunJCE()); try { Key key = getKey(strKey.getBytes("UTF-8"));

encryptCipher = Cipher.getInstance("DES");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);

decryptCipher = Cipher.getInstance("DES");
decryptCipher.init(Cipher.DECRYPT_MODE, key);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

/**

  • 加密字节数组
  • @param arrB
  • 需加密的字节数组
  • @return 加密后的字节数组
  • @throws Exception */ public byte[] encrypt(byte[] arrB) throws Exception { return encryptCipher.doFinal(arrB); }

/**

  • 加密字符串
  • @param strIn
  • 需加密的字符串
  • @return 加密后的字符串
  • @throws Exception */ public String encrypt(String strIn) throws Exception { return byteArr2HexStr(encrypt(strIn.getBytes("UTF-8"))); }

/**

  • 解密字节数组
  • @param arrB
  • 需解密的字节数组
  • @return 解密后的字节数组
  • @throws Exception */ public byte[] decrypt(byte[] arrB) throws Exception { return decryptCipher.doFinal(arrB); }

/**

  • 解密字符串
  • @param strIn
  • 需解密的字符串
  • @return 解密后的字符串
  • @throws Exception */ public String decrypt(String strIn) throws Exception { return new String(decrypt(hexStr2ByteArr(strIn)), "UTF-8"); }

/**

  • 从指定字符串生成密钥,密钥所需的字节数组长度为8位 不足8位时后面补0,超出8位只取前8位
  • @param arrBTmp
  • 构成该字符串的字节数组
  • @return 生成的密钥
  • @throws java.lang.Exception */ private Key getKey(byte[] arrBTmp) throws Exception { // 创建一个空的8位字节数组(默认值为0) byte[] arrB = new byte[8];

// 将原始字节数组转换为8位
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i];
}

// 生成密钥
Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES");

return key;
}

public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//String test = "{\"p3\":\"11111\",\"p21\":\"01\",\"p22\":\"0\",\"p23\":\"232323232323\"}";
String test;
test="6f8f6fa45a2e1976a57856abfac7511eb3e73d062dfb6097446e351579751a2f61253fea7ee095c3172157c79f07feae7c57e6fd9ab572c84e43505e7bfc2da66a208d656b49f1b8651061db390e14b0a92fce4f74dd2a2544173e298c197ca380d952cd111afda400e9f8e9cf6c783cc28d7e352c5112087c57e6fd9ab572c8675b25b6d7eda238eb77ffcdb4e11c00e017a513287381f94a3c3288b5f7d78836d99b6bfc9ad06be1aea0394368d2398b9cc276393c64c6317778e8ce041a6ae017a513287381f99f7caa672e489d37bf6d672aa19bd846df785d28f4f3870f83cb1a1980f6db3b";
// DESPlus des = new DESPlus();//默认密钥
/* DESString des = new DESString("WPS2SUG");// 自定义密钥
System.out.println("加密前的字符:" + test);
String tencryptString = des.encrypt(test);
System.out.println("加密后的字符:" + tencryptString);
*/

// test="{\"p1\":\"1\",\"p2\":\"\",\"p6\":\"gh_79b5657929f2\",\"p13\":\"http://ip:port/res?queryStrs\"}";
DESString des111 = new DESString("ecssWechat");// 自定义密钥
String tmp;
tmp= des111.decrypt(test);
// tmp=des111.encrypt(test);
System.out.println(tmp);
System.out.println("decord后的字符:" + java.net.URLDecoder.decode(tmp));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}

我解密的时候就 string content =decrypt(reader.readtoend(),"这里是key"); reader就是我访问接口地址的一个streamreader

这是我.net 解密用的算法
///
/// 进行DES加密。
///
/// 要加密的字符串。
/// 密钥,且必须为8位。
/// 以Base64格式返回的加密字符串。
public static string Encrypt(string pToEncrypt, string sKey)
{
using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
{
byte[] inputByteArray = Encoding.UTF8.GetBytes(pToEncrypt);
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
cs.Close();
}
string str = Convert.ToBase64String(ms.ToArray());
ms.Close();
return str;
}
}

    // <summary>
    // 进行DES解密。
    // </summary>
    // <param name="pToDecrypt">要解密的以Base64</param>
    // <param name="sKey">密钥,且必须为8位。</param>
    // <returns>已解密的字符串。</returns>
    public static string Decrypt(string pToDecrypt, string sKey)
    {
        byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);
        using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
        {
            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                cs.Close();
            }
            string str = Encoding.UTF8.GetString(ms.ToArray());
            ms.Close();
            return str;
        }
    } 

请大神们帮帮我,如果我的解密算法不对,能不能给粘贴一个有用的解密代码

///
/// des3解密
///
///
///
///
///
public string Des3Decrypt(string data, string key, string iv)
{
try
{
data = data.Replace(" ", "+");
byte[] bData = Convert.FromBase64String(data);
byte[] bKey = System.Text.Encoding.Default.GetBytes(key);
byte[] bIV = System.Text.Encoding.Default.GetBytes(iv);
MemoryStream msDecrypt = new MemoryStream(bData);
TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider
{
Key = bKey,
IV = bIV,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7
};
CryptoStream csDecrypt = new CryptoStream(msDecrypt,
tdsp.CreateDecryptor(),
CryptoStreamMode.Read);
byte[] fromEncrypt = new byte[bData.Length];
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
return System.Text.Encoding.UTF8.GetString(fromEncrypt);
}
catch (Exception e)
{
return null;
}
}

            试试这个

首先,调试获取一段从接口来的数据,然后在这个网站用密码在线解密一下 http://tool.oschina.net/encrypt/,如果成功就是你的解密算法有问题。试试下面这个:
http://tool.oschina.net/encrypt////
/// DES解密方法
///
/// 密文
/// 密钥
/// 解密后的明文
public static string DESDecrypt(string text,string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
int len;
len = text.Length / 2;
byte[] inputByteArray = new byte[len];
int x, i;
for (x = 0; x < len; x++)
{
i = Convert.ToInt32(text.Substring(x * 2, 2), 16);
inputByteArray[x] = (byte)i;
}
try
{
des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
string estring = Encoding.Default.GetString(ms.ToArray());
ms.Dispose();
cs.Dispose();
return estring;
}
catch
{
return "";
}

    } 

请注意C#的数据类型和java的数据类型定义不同,确切的说C#的byte(0~255)与java的byte(-0128~127)是不同的,所以加解密的时候注意字符长度控制,当然了des的
加解密本身对长度也有限制,提前将数据用base64转一下,在次强调长度。