1、NET 与 Java DES 加密\解密 互通 方式 2009-1-9 17:44:54 由于.net DES 对称算法的运算模式。默认值为CipherMode.CBC(密码块链模式) 而java默认运算模式是ECB(电子密码本模式 ),具体模式介绍请参考MSDN 所以 只需要指定DES 对称算法的运算模式为ECB 就可以实现与Java DES加密、解密的互通 附上.net DES加密、解密代码 using System; using System.Text; using System.Security.Cryptography;
2、///
3、ng Text)
{
return Encrypt(Text,"xxxxxxx");
}
///
4、es = new DESCryptoServiceProvider(); des.Mode = System.Security.Cryptography.CipherMode.ECB; byte[] inputByteArray; inputByteArray=Encoding.Default.GetBytes(Text); des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); des.IV =ASCIIEncoding.ASCII.GetBytes(sKey); System.IO.MemoryStr
5、eam ms=new System.IO.MemoryStream(); CryptoStream cs=new CryptoStream(ms,des.CreateEncryptor(),CryptoStreamMode.Write); cs.Write(inputByteArray,0,inputByteArray.Length); cs.FlushFinalBlock(); StringBuilder ret=new StringBuilder(); foreach( byte b in ms.ToArray()) {
6、 ret.AppendFormat("{0:X2}",b);
}
return ret.ToString();
}
#endregion
#region ========解密========
///
7、 Decrypt(Text,"xxxxxxx");
}
///
8、Provider();
des.Mode = System.Security.Cryptography.CipherMode.ECB;
int len;
len=Text.Length/2;
byte[] inputByteArray = new byte[len];
int x,i;
for(x=0;x 9、 des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
System.IO.MemoryStream ms=new System.IO.MemoryStream();
CryptoStream cs=new CryptoStream(ms,des.CreateDecryptor(),CryptoStreamMode.Write);
cs.Write(inputByteArray,0,inputByteArray.Length);
10、
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}
#endregion
}[原文地址:
今天碰上一件令我头大的事情。我们的系统要和一个外部系统进行通讯,传输方式是采用 DES 算法对消息进行加密,再用 BASE64 编码。不过对方系统是用 C# 写的。平台不一样,于是我和对面的老兄先测试一下加密解密。这一测试问题就来了。两边采用同样的密钥,对同一个字符串加密出来的结果不一样。怎么办呢?我先把他那边的代码要过来了,他是这样写的(C#):
11、 public static string Encrypt(string message, string key)
{
DES des = new DESCryptoServiceProvider();
des.Key = Encoding.UTF8.GetBytes(key);
des.IV = Encoding.UTF8.GetBytes(key);
byte[] bytes = Encoding.UTF8.GetBytes(message);
byte[] resultBytes = 12、des.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length);
return Convert.ToBase64String(resultBytes);
}
而我这边呢,是用 Java 这样写的(仅仅加密到字节串,BASE64 编码是在另一个类里):
public static byte[] desEncrypt(String message, String key) throws Exception {
Cipher cipher = Cipher.g 13、etInstance("DES");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
14、 return cipher.doFinal(message.getBytes("UTF-8"));
}
两边一对比我就奇怪了,他那边怎么有个 IV (initialization vector)?我打开JDK文档一看Cipher类,竟然也有一个getIV()方法。看来这 IV 大有来头。于是在JDK文档里面到处找IV,找到了一个叫“IvParameterSpec“的类,莫非就是它?它实现的是 AlgorithmParameterSpec 接口,而Cipher.init()中就有一个 AlgorithmParameterSpec 类型的参数。那么看来就是它了。于是参考了I 15、vParameterSpec的构造函数后,我这样把它加进去:
public static byte[] desEncrypt(String message, String key) throws Exception {
Cipher cipher = Cipher.getInstance("DES");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory 16、getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
return cipher.doFinal(message.getBytes("UTF-8"));
}
这下行了吧, 17、结果一运行报异常:
java.security.InvalidAlgorithmParameterException: ECB mode cannot use IV
这又是什么? “ECB”? 还是找吧,在JDK文档中找到了这么几句鬼东西:
the SunJCE provider uses ECB as the default mode, and PKCS5 Padding as the default padding scheme for DES, DES-EDE and Blowfish ciphers. This means that in the case o 18、f the SunJCE provider,
Cipher c1 = Cipher.getInstance("DES/ECB/PKCS5Padding");
and
Cipher c1 = Cipher.getInstance("DES");
are equivalent statements.
哦,问题就出在方法里的第一行。那么不准用 ECB,该用什么呢?在该文往下找,找到了这么几项:
The following names can be specified as the mode component in a transformation whe 19、n requesting an instance of Cipher:
NONE: No mode.
CBC: Cipher Block Chaining Mode, as defined in FIPS PUB 81.
CFB: Cipher Feedback Mode, as defined in FIPS PUB 81.
ECB: Electronic Codebook Mode, as defined in: The National Institute of Standards and Technology (NIST) Federal Information Pro 20、cessing Standard (FIPS) PUB 81, "DES Modes of Operation," U.S. Department of Commerce, Dec 1980.
OFB: Output Feedback Mode, as defined in FIPS PUB 81.
PCBC: Propagating Cipher Block Chaining, as defined by Kerberos V4.
我这样都换着试一下就行了。哎,运气不错,拿着第一个 CBC 试一下就成功了,加密后的字符串也“正确”了。
我那个方法就变成这样:
21、public static byte[] desEncrypt(String message, String key) throws Exception {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
22、
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
return cipher.doFinal(message.getBytes("UTF-8"));
}
这样,解决了这个 ECB 之后,Java 和 .net 23、 平台的两个应用终于能够相互加密和解密数据了。
[原文地址:
2010-07-08 11:32
这里贴出来的是可通用的C#与java的DES加密类,希望对大家管用直接复制即可用
C#DES加密解密类
/// 24、]>
///
/// 25、ovider();
provider.Key = Encoding.ASCII.GetBytes(key.Substring(0, 8));
provider.IV = Encoding.ASCII.GetBytes(key.Substring(0, 8));
byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(str);
MemoryStream stream = new MemoryStream() 26、
CryptoStream stream2 = new CryptoStream(stream, provider.CreateEncryptor(), CryptoStreamMode.Write);
stream2.Write(bytes, 0, bytes.Length);
stream2.FlushFinalBlock();
StringBuilder builder = new StringBuilder();
f 27、oreach (byte num in stream.ToArray())
{
builder.AppendFormat("{0:X2}", num);
}
stream.Close();
return builder.ToString();
}
catch (Exception) { return "xxxx"; }
}
28、 /// 29、y
{
DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
provider.Key = Encoding.ASCII.GetBytes(key.Substring(0, 8));
provider.IV = Encoding.ASCII.GetBytes(key.Substring(0, 8));
byte[] buffer = new byte 30、[str.Length / 2];
for (int i = 0; i < (str.Length / 2); i++)
{
int num2 = Convert.ToInt32(str.Substring(i * 2, 2), 0x10);
buffer[i] = (byte)num2;
}
MemoryStream stream = new MemoryStream();
31、
CryptoStream stream2 = new CryptoStream(stream, provider.CreateDecryptor(), CryptoStreamMode.Write);
stream2.Write(buffer, 0, buffer.Length);
stream2.FlushFinalBlock();
stream.Close();
return Encoding.GetEncoding("G 32、B2312").GetString(stream.ToArray());
}
catch (Exception) { return ""; }
}
}
JAVADES加密解密类
package com.bgxt.messages;
import java.io.UnsupportedEncodingException;
import java.security.*;
import javax.crypto.Cipher;
import javax.crypto.SecretKey 33、
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
/**
* 字符串工具集合
* @author Liudong
*/
public class StringUtils {
private static final String PASSWORD_CRYPT_KEY = XmlUtil.getConfig().getPasswdKey().subst 34、ring(0,8);
//private final static String DES = "DES";
//private static final byte[] desKey;
//解密数据
public static String decrypt(String message,String key) throws Exception {
byte[] bytesrc =convertHexString(message);
Cipher cipher = Cipher.getInstanc 35、e("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = 36、new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] retByte = cipher.doFinal(bytesrc);
return new String(retByte);
}
public static byte[] encrypt(String message, String key)
throws Ex 37、ception {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
38、 IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
return cipher.doFinal(message.getBytes("UTF-8"));
}
public static String encrypt(String value){
String result="";
try{
value=.URLEncoder.encode(value, "ut 39、f-8");
result=toHexString(encrypt(value, PASSWORD_CRYPT_KEY)).toUpperCase();
}catch(Exception ex){
ex.printStackTrace();
return "";
}
return result;
}
public static byte[] convertHexString(String ss)
{
byte digest[] = new byte[ss.length() / 2];
for(int i = 0; i < diges 40、t.length; i++)
{
String byteString = ss.substring(2 * i, 2 * i + 2);
int byteValue = Integer.parseInt(byteString, 16);
digest[i] = (byte)byteValue;
}
return digest;
}
public static String toHexString(byte b[]) {
StringBuffer hexString = new StringBuff 41、er();
for (int i = 0; i < b.length; i++) {
String plainText = Integer.toHexString(0xff & b[i]);
if (plainText.length() < 2)
plainText = "0" + plainText;
hexString.append(plainText);
}
return hexString.toString();
} 42、
public static void main(String[] args) throws Exception {
String value="01";
System.out.println("加密数据:"+value);
System.out.println("密码为:"+XmlUtil.getConfig().getPasswdKey());
String a=encrypt( value);
System.out.println("加密后的数据为:"+a);
}
}C#加密解密方法
1、方法 43、一 (不可逆加密)
public string EncryptPassword(string PasswordString,string PasswordFormat )
{
string encryptPassword = null;
if (PasswordFormat="SHA1"){
encryptPassword=FormsAuthortication.HashPasswordForStoringInConfigFile(PasswordString
,"SHA1");
}
elseif (PasswordFo 44、rmat="MD5")
{ encryptPassword=FormsAuthortication.HashPasswordForStoringInConfigFile(PasswordString
,"MD5");
}
return encryptPassword ;
}
2、方法二 (可逆加密)
public interface IBindesh
{
string encode(string str);
string decode(string str);
}
public class Encrypt 45、ionDecryption : IBindesh
{
public string encode(string str)
{
string htext = "";
for ( int i = 0; i < str.Length; i++)
{
htext = htext + (char) (str[i] + 10 - 1_*2);
}
return htext;
} 46、
public string decode(string str)
{
string dtext = "";
for ( int i=0; i < str.Length; i++)
{
dtext = dtext + (char) (str[i] - 10 + 1*2);
}
return dtext;
}
3、方法三 (可逆加密)
47、 const string KEY_64 = "VavicApp";//注意了,是8个字符,64位
const string IV_64 = "VavicApp";
public string Encode(string data)
{
byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(KEY_64);
byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(IV_64);
48、
DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
int i = cryptoProvider.KeySize;
MemoryStream ms = new MemoryStream();
CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey,
byIV), CryptoStreamM 49、ode.Write);
StreamWriter sw = new StreamWriter(cst);
sw.Write(data);
sw.Flush();
cst.FlushFinalBlock();
sw.Flush();
return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
}
public string Decode(string data)
{
byte[] byKey = System.Text.






