一定要注意加密结果一样。java的类如下:
package com.benan.common;
/**
* @author tianya
*
* 简单的DES加密算法
*/
import java.security.NoSuchAlgorithmException;
import java.security.Security;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* DES加密的,文件中共有两个方法,加密、解密
*
*/
public class DES2 {
private String Algorithm = "DES";
private KeyGenerator keygen;
private SecretKey deskey;
private Cipher cipher;
private byte[] encryptorData;
private byte[] decryptorData; /**
* 初始化 DES 实例
*/
public DES2() {
init();
} /**
* 初始化 DES 加密算法的一些参数
*/
public void init() {
Security.addProvider(new com.sun.crypto.provider.SunJCE());
try {
keygen = KeyGenerator.getInstance(Algorithm);//初始化一个密匙
byte key[]="12312345".getBytes();
deskey=new SecretKeySpec(key,"DES"); 根据给定的字节数组构造一个密钥
// deskey = keygen.generateKey();
// for(int i=0;i<deskey.getEncoded().length;i++){
// System.out.println(deskey.getEncoded()[i]);
//}
cipher = Cipher.getInstance(Algorithm);//生成一个实现指定转(DES)换的 Cipher 对象
}
catch(NoSuchAlgorithmException ex){
ex.printStackTrace();
}
catch(NoSuchPaddingException ex){
ex.printStackTrace();
}
} /**
* 对 byte[] 进行加密
* @param datasource 要加密的数据
* @return 返回加密后的 byte 数组
*/
public byte[] createEncryptor(byte[] datasource) {
try {
cipher.init(Cipher.ENCRYPT_MODE, deskey);// 指定加密模式
encryptorData = cipher.doFinal(datasource);//按单部分操作加密或解密数据io
}
catch(java.security.InvalidKeyException ex){
ex.printStackTrace();
}
catch(javax.crypto.BadPaddingException ex){
ex.printStackTrace();
}
catch(javax.crypto.IllegalBlockSizeException ex){
ex.printStackTrace();
}
return encryptorData;
}
/**
* 将字符串加密
*
* @param datasource
* @return
* @throws Exception
*/
public byte[] createEncryptor(String datasource) throws Exception{
return createEncryptor(datasource.getBytes());
}
/**
* 对 datasource 数组进行解密
* @param datasource 要解密的数据
* @return 返回加密后的 byte[]
*/
public byte[] createDecryptor(byte[] datasource) {
try {
cipher.init(Cipher.DECRYPT_MODE, deskey);
decryptorData = cipher.doFinal(datasource);
}
catch(java.security.InvalidKeyException ex){
ex.printStackTrace();
}
catch(javax.crypto.BadPaddingException ex){
ex.printStackTrace();
}
catch(javax.crypto.IllegalBlockSizeException ex){
ex.printStackTrace();
}
return decryptorData;
}
/**
*
* 将 DES 加密过的 byte数组转换为字符串
*
* @param dataByte
* @return
*/
public String byteToString(byte[] dataByte)
{
String returnStr = null;
BASE64Encoder be = new BASE64Encoder();
returnStr = be.encode(dataByte);
return returnStr;
}
/**
*
* 将字符串转换为DES算法可以解密的byte数组
*
* @param dataByte
* @return
* @throws Exception
*/
public byte[] stringToByte(String datasource)throws Exception {
BASE64Decoder bd = new BASE64Decoder();
byte[] sorData = bd.decodeBuffer(datasource);
return sorData;
}
/**
* 输出 byte数组
*
* @param data
*/
public void printByte(byte[] data)
{
System.out.println("*********开始输出字节流**********");
System.out.println("字节流: "+data.toString());
for(int i = 0 ; i < data.length ; i++){
System.out.println("第 "+i+"字节为:"+ data[i]);
}
System.out.println("*********结束输出字节流**********");
}
public static void main(String args[])throws Exception
{
//加密源数据
String encryptorString = "01000050-0-0000"; DES2 des = new DES2();
//加密获得的byte数组
byte[] encryptorByte = des.createEncryptor(encryptorString);
//加密后的byte[] 转换来的字符串
String byteToString = des.byteToString(encryptorByte);
System.out.println("加密前的数据:"+encryptorString);
System.out.println("加密后的byte[]");
des.printByte(encryptorByte);
System.out.println("加密后的数据:"+byteToString);
/*
* 可以对字符串进行一系列的处理
*/
//解密后的字符串
String decryptorString = null;
//将byteToString转换为原来的byte[]
byte[] stringToByte = des.stringToByte(byteToString);
//将stringToByte解密后的byte[]
byte[]decryptorByte = des.createDecryptor(stringToByte);
System.out.println("解密后"+des.byteToString(decryptorByte));
//解密后的byte[]转换为原来的字符串
decryptorString = new String(decryptorByte);
System.out.println("解密前的数据:"+byteToString);
System.out.println("转换来的解密的byte[]");
des.printByte(stringToByte);
System.out.println("解密后的数据:"+decryptorString);
} }
java的加密结果是:HIKJKMVKJKKKKNKVKVKKKK
我需要C#出来的加密结果也这样。
不要告诉我改java类,这个行不通,因为原来java生成的结果已经发布出去,改起来的成本太高。
谢谢各位高手 分不够的话以后再补啊。急需,如能改成,可另赠QB 10个。 请加MSN:[email protected]
也可EmailTo:[email protected]
package com.benan.common;
/**
* @author tianya
*
* 简单的DES加密算法
*/
import java.security.NoSuchAlgorithmException;
import java.security.Security;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* DES加密的,文件中共有两个方法,加密、解密
*
*/
public class DES2 {
private String Algorithm = "DES";
private KeyGenerator keygen;
private SecretKey deskey;
private Cipher cipher;
private byte[] encryptorData;
private byte[] decryptorData; /**
* 初始化 DES 实例
*/
public DES2() {
init();
} /**
* 初始化 DES 加密算法的一些参数
*/
public void init() {
Security.addProvider(new com.sun.crypto.provider.SunJCE());
try {
keygen = KeyGenerator.getInstance(Algorithm);//初始化一个密匙
byte key[]="12312345".getBytes();
deskey=new SecretKeySpec(key,"DES"); 根据给定的字节数组构造一个密钥
// deskey = keygen.generateKey();
// for(int i=0;i<deskey.getEncoded().length;i++){
// System.out.println(deskey.getEncoded()[i]);
//}
cipher = Cipher.getInstance(Algorithm);//生成一个实现指定转(DES)换的 Cipher 对象
}
catch(NoSuchAlgorithmException ex){
ex.printStackTrace();
}
catch(NoSuchPaddingException ex){
ex.printStackTrace();
}
} /**
* 对 byte[] 进行加密
* @param datasource 要加密的数据
* @return 返回加密后的 byte 数组
*/
public byte[] createEncryptor(byte[] datasource) {
try {
cipher.init(Cipher.ENCRYPT_MODE, deskey);// 指定加密模式
encryptorData = cipher.doFinal(datasource);//按单部分操作加密或解密数据io
}
catch(java.security.InvalidKeyException ex){
ex.printStackTrace();
}
catch(javax.crypto.BadPaddingException ex){
ex.printStackTrace();
}
catch(javax.crypto.IllegalBlockSizeException ex){
ex.printStackTrace();
}
return encryptorData;
}
/**
* 将字符串加密
*
* @param datasource
* @return
* @throws Exception
*/
public byte[] createEncryptor(String datasource) throws Exception{
return createEncryptor(datasource.getBytes());
}
/**
* 对 datasource 数组进行解密
* @param datasource 要解密的数据
* @return 返回加密后的 byte[]
*/
public byte[] createDecryptor(byte[] datasource) {
try {
cipher.init(Cipher.DECRYPT_MODE, deskey);
decryptorData = cipher.doFinal(datasource);
}
catch(java.security.InvalidKeyException ex){
ex.printStackTrace();
}
catch(javax.crypto.BadPaddingException ex){
ex.printStackTrace();
}
catch(javax.crypto.IllegalBlockSizeException ex){
ex.printStackTrace();
}
return decryptorData;
}
/**
*
* 将 DES 加密过的 byte数组转换为字符串
*
* @param dataByte
* @return
*/
public String byteToString(byte[] dataByte)
{
String returnStr = null;
BASE64Encoder be = new BASE64Encoder();
returnStr = be.encode(dataByte);
return returnStr;
}
/**
*
* 将字符串转换为DES算法可以解密的byte数组
*
* @param dataByte
* @return
* @throws Exception
*/
public byte[] stringToByte(String datasource)throws Exception {
BASE64Decoder bd = new BASE64Decoder();
byte[] sorData = bd.decodeBuffer(datasource);
return sorData;
}
/**
* 输出 byte数组
*
* @param data
*/
public void printByte(byte[] data)
{
System.out.println("*********开始输出字节流**********");
System.out.println("字节流: "+data.toString());
for(int i = 0 ; i < data.length ; i++){
System.out.println("第 "+i+"字节为:"+ data[i]);
}
System.out.println("*********结束输出字节流**********");
}
public static void main(String args[])throws Exception
{
//加密源数据
String encryptorString = "01000050-0-0000"; DES2 des = new DES2();
//加密获得的byte数组
byte[] encryptorByte = des.createEncryptor(encryptorString);
//加密后的byte[] 转换来的字符串
String byteToString = des.byteToString(encryptorByte);
System.out.println("加密前的数据:"+encryptorString);
System.out.println("加密后的byte[]");
des.printByte(encryptorByte);
System.out.println("加密后的数据:"+byteToString);
/*
* 可以对字符串进行一系列的处理
*/
//解密后的字符串
String decryptorString = null;
//将byteToString转换为原来的byte[]
byte[] stringToByte = des.stringToByte(byteToString);
//将stringToByte解密后的byte[]
byte[]decryptorByte = des.createDecryptor(stringToByte);
System.out.println("解密后"+des.byteToString(decryptorByte));
//解密后的byte[]转换为原来的字符串
decryptorString = new String(decryptorByte);
System.out.println("解密前的数据:"+byteToString);
System.out.println("转换来的解密的byte[]");
des.printByte(stringToByte);
System.out.println("解密后的数据:"+decryptorString);
} }
java的加密结果是:HIKJKMVKJKKKKNKVKVKKKK
我需要C#出来的加密结果也这样。
不要告诉我改java类,这个行不通,因为原来java生成的结果已经发布出去,改起来的成本太高。
谢谢各位高手 分不够的话以后再补啊。急需,如能改成,可另赠QB 10个。 请加MSN:[email protected]
也可EmailTo:[email protected]
现在问题应该出在java的代码没有初始化向量吧?
还有java的padding默认补位是0x01,0x02,0x03,0x04,0x05……
C#的是0x00,
希望尽快得到答案,急的啊
使用的代码就是java的
然后引用到你的C#项目里面就OK了
这样不是很方便吗!!
好像.net有个用来加密的类!!
这里有C#的加密工具,和源码.看可以不.
public static string Encrypt(string val, string key)
{
string retVal = string.Empty; try
{
byte[] byteArray = Encoding.UTF8.GetBytes(val);
byte[] byteKey = Encoding.UTF8.GetBytes(key); DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = MakeCryptoServiceProviderKey(byteKey, des.Key.Length);
des.IV = MakeCryptoServiceProviderKey(byteKey, des.IV.Length); ICryptoTransform cryptor = des.CreateEncryptor();
using (MemoryStream mem = new System.IO.MemoryStream())
using (CryptoStream cryptStreem = new CryptoStream(mem, cryptor, CryptoStreamMode.Write))
{
cryptStreem.Write(byteArray, 0, byteArray.Length);
cryptStreem.FlushFinalBlock(); byte[] bytesOut = mem.ToArray(); retVal = Convert.ToBase64String(bytesOut);
}
}
catch
{
retVal = string.Empty;
} return retVal;
}
解密
public static string Decrypt(string val, string key)
{
string retVal = string.Empty; try
{
byte[] byteArray = System.Convert.FromBase64String(val);
byte[] byteKey = System.Text.Encoding.UTF8.GetBytes(key); DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = MakeCryptoServiceProviderKey(byteKey, des.Key.Length);
des.IV = MakeCryptoServiceProviderKey(byteKey, des.IV.Length); ICryptoTransform cryptor = des.CreateDecryptor();
using (MemoryStream mem = new MemoryStream(byteArray))
using (CryptoStream cryptStreem = new CryptoStream(mem, cryptor, CryptoStreamMode.Read))
using (StreamReader srOut = new StreamReader(cryptStreem, System.Text.Encoding.UTF8))
{
retVal = srOut.ReadToEnd();
}
}
catch
{
retVal = string.Empty;
} return retVal;
}key做成
private static byte[] MakeCryptoServiceProviderKey(byte[] byteKey, int newSize)
{
byte[] newBytes = new byte[newSize];
newBytes.Initialize(); if (byteKey.Length <= newSize)
{
for (int index = 0; index < byteKey.Length; index++)
{
newBytes[index] = byteKey[index];
}
}
else
{
int pos = 0;
for (int index = 0; index < byteKey.Length; index++)
{
newBytes[pos++] ^= byteKey[index];
if (pos >= newBytes.Length)
{
pos = 0;
}
}
}
return newBytes;
}
使用的代码就是java的
然后引用到你的C#项目里面就OK了
这样不是很方便吗!!
这个newSize传什么参数?
使用的代码就是java的
然后引用到你的C#项目里面就OK了
这样不是很方便吗!!
12345678-1-1234的java加密结果为JQBamoto96Jl5ygqD3riQA==;C#的加密结果为:GEpj9yUWLNddcxSGkyJ8HQ==
33333333-3-3333的java加密结果为QtuoCH8qn9quaS8zK7uaJQ==;C#的加密结果为:XEfmB28fh4gtRqNHeoc0lg==
12456789-X-1111的java加密结果为FBoifyo884N7l3VWBqVRpsecbPU22nDu;C#的加密结果为:bQsE6vqnrpmeyi5CU6EUcA==
12345678-9-0000的java加密结果为JQBamoto96LmGOH++rkjUQ==;C#的加密结果为:GEpj9yUWLNfQ8d1dwQvzKA==
44448888-L-1243的java加密结果为CrtUZDTLo0sKIUiW/gmvzQ==;C#的加密结果为:SgUctfAMgagtx+GRKiVVUg==
byte key[]="12312345".getBytes(); 得到的会不会是 0x00,0x31,0x00,0x32,0x00,0x33,.. ? 因为是unicode
基本上拷贝进去直接调试就可以
java中用的是这个deskey=new SecretKeySpec(key,"DES"); 根据给定的字节数组构造一个密钥
你看看SecretKeySpec中是怎么做的,然后在c#中按相同逻辑处理
折腾了我N长时间,什么 向量啊什么 乱七八糟的 什么base64 我搞了N长时间。后来为了解决问题,我不得不写了一个java的加密解密中间程序。
每次建立通信的时候我在内部把 加密串交给 我那个单独的java程序来做。
----------------我的方法非常愚蠢,但一定能快速解决你现在遇到的问题。
最后,如果你解决了 DES加密与JAVA DES加密相互通信的正确方式之后希望你不吝赐教~
:)
/// 字符串DES加密及解密类
/// </summary>
public class secret_string
{
//默认密钥向量
private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
/**/
/**/
/**/
/// <summary>
/// DES加密字符串
/// </summary>
/// <param name="encryptString">待加密的字符串</param>
/// <param name="encryptKey">加密密钥,要求为8位</param>
/// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
public static string EncryptDES(string encryptString, string encryptKey)
{
try
{
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
byte[] rgbIV = Keys;
byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
return Convert.ToBase64String(mStream.ToArray());
}
catch
{
return encryptString;
}
} /**/
/**/
/**/
/// <summary>
/// DES解密字符串
/// </summary>
/// <param name="decryptString">待解密的字符串</param>
/// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
/// <returns>解密成功返回解密后的字符串,失败返源串</returns>
public static string DecryptDES(string decryptString, string decryptKey)
{
try
{
byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
byte[] rgbIV = Keys;
byte[] inputByteArray = Convert.FromBase64String(decryptString);
DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
return Encoding.UTF8.GetString(mStream.ToArray());
}
catch
{
return decryptString;
}
}
}我用的这个des加密解密的密钥字符有受到限制,使用有些密钥加密后接不能解密,如123456aaa,就不能解密!有没有密钥不限制字符的解密类!