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(); } }
以上所述就是本文的全部内容了,希望大家能够喜欢。