C# 3DES加密详解
最近一个项目中,因为服务端是用的java开发的,客户端是用的C#,由于通信部分采用到了3DES加密,所以做个记录,以备以后需要的时候直接用。
这是对方(java)的加密算法,和网上流传的代码也差不多(主密钥直接写死了,方便测试)
packageorg.zwork.market.mina.msg;
importjava.security.spec.KeySpec;
importjavax.crypto.Cipher;
importjavax.crypto.SecretKey;
importjavax.crypto.SecretKeyFactory;
importjavax.crypto.spec.DESKeySpec;
importjavax.crypto.spec.DESedeKeySpec;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.zwork.market.MktContants;
publicclassThreeEncryptDecrypt{
privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(ThreeEncryptDecrypt.class);
//定义加密算法,可用DES,DESede,Blowfish
publicstaticfinalStringAlgorithm="DESede";
publicstaticStringDES="DES/ECB/NoPadding";
publicstaticStringTriDes="DESede/ECB/NoPadding";
//des加密
publicstaticbyte[]des_crypt(bytekey[],bytedata[]){
try{
KeySpecks=newDESKeySpec(key);
SecretKeyFactorykf=SecretKeyFactory.getInstance("DES");
SecretKeyky=kf.generateSecret(ks);
Cipherc=Cipher.getInstance(DES);
c.init(Cipher.ENCRYPT_MODE,ky);
returnc.doFinal(data);
}catch(Exceptione){
LOGGER.error("des_crypterror:",e);
returnnull;
}
}
//des解密
publicstaticbyte[]des_decrypt(bytekey[],bytedata[]){
try{
KeySpecks=newDESKeySpec(key);
SecretKeyFactorykf=SecretKeyFactory.getInstance("DES");
SecretKeyky=kf.generateSecret(ks);
Cipherc=Cipher.getInstance(DES);
c.init(Cipher.DECRYPT_MODE,ky);
returnc.doFinal(data);
}catch(Exceptione){
LOGGER.error("des_decrypterror:",e);
returnnull;
}
}
//3DES加密
publicstaticbyte[]trides_crypt(bytekey[],bytedata[]){
try{
byte[]k=newbyte[24];
intlen=data.length;
if(data.length%8!=0){
len=data.length-data.length%8+8;
}
byte[]needData=null;
if(len!=0)
needData=newbyte[len];
for(inti=0;i<len;i++){
needData[i]=0x00;
}
System.arraycopy(data,0,needData,0,data.length);
if(key.length==16){
System.arraycopy(key,0,k,0,key.length);
System.arraycopy(key,0,k,16,8);
}else{
System.arraycopy(key,0,k,0,24);
}
KeySpecks=newDESedeKeySpec(k);
SecretKeyFactorykf=SecretKeyFactory.getInstance("DESede");
SecretKeyky=kf.generateSecret(ks);
Cipherc=Cipher.getInstance(TriDes);
c.init(Cipher.ENCRYPT_MODE,ky);
returnc.doFinal(needData);
}catch(Exceptione){
LOGGER.error("trides_crypterror:",e);
returnnull;
}
}
//3DES解密
publicstaticbyte[]trides_decrypt(bytekey[],bytedata[]){
try{
byte[]k=newbyte[24];
intlen=data.length;
if(data.length%8!=0){
len=data.length-data.length%8+8;
}
byte[]needData=null;
if(len!=0)
needData=newbyte[len];
for(inti=0;i<len;i++){
needData[i]=0x00;
}
System.arraycopy(data,0,needData,0,data.length);
if(key.length==16){
System.arraycopy(key,0,k,0,key.length);
System.arraycopy(key,0,k,16,8);
}else{
System.arraycopy(key,0,k,0,24);
}
KeySpecks=newDESedeKeySpec(k);
SecretKeyFactorykf=SecretKeyFactory.getInstance("DESede");
SecretKeyky=kf.generateSecret(ks);
Cipherc=Cipher.getInstance(TriDes);
c.init(Cipher.DECRYPT_MODE,ky);
returnc.doFinal(needData);
}catch(Exceptione){
LOGGER.error("trides_decrypterror:",e);
returnnull;
}
}
publicstaticStringgetPass(Stringsource){
byte[]data=hexToBytes(source);
byte[]key="111111111111111111111111111a1.1.".getBytes();
Stringresult=byte2hex(trides_decrypt(key,data)).toUpperCase();
returnresult.substring(2,8);
}
publicstaticStringbyte2hex(byte[]data){
StringBuffersb=newStringBuffer();
for(inti=0;i<data.length;i++){
Stringtemp=Integer.toHexString(((int)data[i])&0xFF);
for(intt=temp.length();t<2;t++){
sb.append("0");
}
sb.append(temp);
}
returnsb.toString();
}
publicstaticbyte[]hexToBytes(Stringstr){
if(str==null){
returnnull;
}elseif(str.length()<2){
returnnull;
}else{
intlen=str.length()/2;
byte[]buffer=newbyte[len];
for(inti=0;i<len;i++){
buffer[i]=(byte)Integer.parseInt(str.substring(i*2,i*2+2),16);
}
returnbuffer;
}
}
}
因为客户端只负责数据加密,所以我这里只写了加密的部分。由于java和C#语言很相似,所以我就仿这他们给的java代码改成C#的,当然也在网上参考了一些代码,不过中间还是出现了些问题,比如C#不支持弱密钥(把密钥弄复杂点),因为没注意大小写造成加密结果不一致等等。编程这东西一个点都能让整个系统崩溃,所以小细节很重要!!!
publicclassDESHelper
{
///<summary>
///将密码转成直接数组
///</summary>
///<paramname="str"></param>
///<returns></returns>
publicstaticbyte[]HexToBytes(Stringstr)
{
if(str==null)
{
returnnull;
}
elseif(str.Length<2)
{
returnnull;
}
else
{
intlen=str.Length/2;
byte[]buffer=newbyte[len];
for(inti=0;i<len;i++)
{
vartemp=str.Substring(i*2,2);
buffer[i]=(byte)Convert.ToInt32(temp,16);
}
returnbuffer;
}
}
///<summary>
///3DES加密
///</summary>
///<paramname="key"></param>
///<paramname="data"></param>
///<returns></returns>
publicstaticbyte[]GetDes3EncryptedText(byte[]key,byte[]data)
{
byte[]k=newbyte[24];
intlen=data.Length;
if(data.Length%8!=0)
{
len=data.Length-data.Length%8+8;
}
byte[]needData=null;
if(len!=0)
needData=newbyte[len];
for(inti=0;i<len;i++)
{
needData[i]=0x00;
}
Buffer.BlockCopy(data,0,needData,0,data.Length);
if(key.Length==16)
{
Buffer.BlockCopy(key,0,k,0,key.Length);
Buffer.BlockCopy(key,0,k,16,8);
}
else
{
Buffer.BlockCopy(key,0,k,0,24);
}
vardes3=newTripleDESCryptoServiceProvider();
des3.Key=k;
des3.Mode=CipherMode.ECB;
des3.Padding=PaddingMode.Zeros;
using(MemoryStreamms=newMemoryStream())
using(CryptoStreamcs=newCryptoStream(ms,des3.CreateEncryptor(),CryptoStreamMode.Write))
{
cs.Write(data,0,data.Length);
cs.FlushFinalBlock();
returnms.ToArray();
}
}
///<summary>
///将加密结果转成字符串
///</summary>
///<paramname="data"></param>
///<returns></returns>
publicstaticStringGetByte2Hex(byte[]data)
{
StringBuildersb=newStringBuilder();
for(inti=0;i<data.Length;i++)
{
Stringtemp=string.Format("{0:X}",((int)data[i])&0xFF);
for(intt=temp.Length;t<2;t++)
{
sb.Append("0");
}
sb.Append(temp);
}
returnsb.ToString();
}
}
以上所述就是本文的全部内容了,希望大家能够喜欢。