AES,DESede/CBC/PKCS5Padding

工作中用到一个DES解码问题,废了一份周折总算做出来了。这里把代码贴出来,希望对大家有用。

import java.security.Key;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

public class DESTool {
	private static final String Algorithm = "DESede"; //定义加密算法
	public static final String CIPHER_ALGORITHM = "DESede/CBC/PKCS5Padding";
	//public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
	 public static final String IV = "12345678";

	/**
	 * 加密
	 * @param datasource
	 * @param password
	 * @return
	 */

	public static byte[] desCrypto(byte[] src, String password) {
		try {
			
			DESedeKeySpec deskey = new DESedeKeySpec(password.getBytes());
			SecretKeyFactory skf = SecretKeyFactory.getInstance(Algorithm);
			Key key = skf.generateSecret(deskey);
			Cipher cipher1 = Cipher.getInstance(CIPHER_ALGORITHM);
			IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
			cipher1.init(Cipher.ENCRYPT_MODE, key,iv);
			
			return cipher1.doFinal(src);//在单一方面的加密或解密  
			
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	/**
	 * 解密
	 * @param src
	 * @param password
	 * @return
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] src, String password) {
		try {
			DESedeKeySpec deskey = new DESedeKeySpec(password.getBytes());
			SecretKeyFactory skf = SecretKeyFactory.getInstance(Algorithm);
			Key key = skf.generateSecret(deskey);
			Cipher cipher1 = Cipher.getInstance(CIPHER_ALGORITHM);
			IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
			cipher1.init(Cipher.DECRYPT_MODE, key,iv);
			return cipher1.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e1) {
			// TODO: handle exception  
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}
	
	//转换成十六进制字符串
	public static String byte2Hex(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1) {
				hs = hs + "0" + stmp;
			} else {
				hs = hs + stmp;
			}
			if (n < b.length - 1)
				hs = hs + ":";
		}
		return hs.toUpperCase();
	}
	
	//十六进制字符串转换成整形数组
	public static byte[] hex2byte(String hex) {
		 int arrayLenth = hex.length() / 2;
		 byte[] inputByteArray = new byte[arrayLenth];
         for (int x = 0; x < arrayLenth; x++)
         {
        	 int beginIndex = x * 2;
        	 int  endIndex = beginIndex +2;
        	 int coventInt = Integer.valueOf(hex.substring(beginIndex,endIndex),16);
             inputByteArray[x] = (byte)coventInt;
         }  
         
         return inputByteArray;

	}
	public static String util_decrypt(String encodString){
		String  password = "0123456789abcd9876543210";
		byte[] srcBytes = decrypt(hex2byte(encodString),password);
		return new String(srcBytes);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
        // TODO Auto-generated method stub  
        //添加新安全算法,如果用JCE就要把它添加进去  
        Security.addProvider(new com.sun.crypto.provider.SunJCE());   
        String password="0123456789abcd9876543210";  
        String szSrc = "37231dcf2bc2cf202f47b419c1cfb9fce1c14d2e86a93b6d1012fefff90c6ea6719a311e7c4e3e757fe98426226148d75eadbade59e6e440f8459beac47be790";  
        //String szSrc = "{\"cn\":\"xiongjun\",\"sn\":\"xiongjun\",\"__tick\":1395929492055}";
        //System.out.println("加密前的字符串:" + szSrc);  
        //byte[] encoded = desCrypto(szSrc.getBytes(),password);  
        //System.out.println("加密后的字符串:" + byte2Hex(encoded));  
        byte[] srcBytes = decrypt(hex2byte(szSrc),password);  
        //byte[] srcBytes = decrypt(encoded,password);  
        System.out.println("解密后的字符串:" + new String(srcBytes));
       
          
        System.out.println(password.length()); 
	}

 

最近做一个接口,与JAVA的关于DES/CBC/PKCS5Padding 互相解密。在网上找了很多资料,摸索了3天才摸索出来。同样的明文,用JAVA加密的密文死活都跟用DELPHI加密的不相等,有时候少于8个字符的就正常,多了8个字符的就有问题,原来是有个7把7改成8就可以了。害人啊,, function EncryDes(const str:string;const keystr:string;const ivstr:string):string ; var key:tkey64; Context:TDESContext; Block,iv:TDESBlock; i,j,len,posnum:smallint; poschar,xx:char; xuhuan:integer; begin for i:=0 to 7 do begin if i > (length(keystr)-1) then key[i] :=0 else key[i] := byte(keystr[i+1]); end; for i:=0 to 7 do begin if i > (length(ivstr)-1) then iv[i]:=0 else iv[i] := byte(ivstr[i+1]); end; InitEncryptDES(Key, Context, true); len := length(AnsiString(str)); xx:= char( 8- (len mod 8)); if len<=8 then xuhuan:=0 else xuhuan:=round(len/8); for i:=0 to xuhuan do begin for j:=0 to 7 do begin if ((i*8+j+1)<=len) then //关键这一步,网上好多参考资料都是((i*7+j+1)<=len),而不是((i*8+j+1)<=len) 害人啊,害得我摸索了3天,,哎 begin poschar:=str[i*8+j+1]; block[j]:=byte(poschar); end else block[j]:=byte(xx); end; EncryptDESCBC(Context, IV, Block); for j:= 0 to 7 do begin posnum:=block[j]; result := result + inttohex(posnum,2); end; iv:=block; end; end; //完整代码如下 unit dmdes; {*********************************************************} {* DELPHI、PHP、C#通用DES编码解码单元 *} {* 由TurboPower LockBox部分代码改写 *} {* 滕州市东鸣软件工作室制作 ZWF 2011-12-27 *} {*********************************************************} {EncryDes为编码函数,DecryDes为解码函数,keystr为密码,ivstr为偏移量, 一般设置keystr,ivstr相同,内容为八位字节长度的字符串,编码结果为十六进制字串} interface uses Windows,SysUtils; type PKey64 = ^TKey64; TKey64 = array [0..7] of Byte; type TDESBlock = array[0..7] of Byte; TDESContext = packed record TransformedKey : array [0..31] of LongInt; Encrypt : Boolean; end; function EncryDes(const str:string;const keystr:string;const ivstr:string):string ; function DecryDes(const str:string;const keystr:string;const ivstr:string):string ; function DecryDessec(const str:string;const keystr:string;const ivstr:string):string ; implementation procedure XorMemPrim(var Mem1; const Mem2; Count : Cardinal); register; asm push esi push edi mov esi, eax //esi = Mem1 mov edi, edx //edi = Mem2 push ecx //save byte count shr ecx, 2 //convert to dwords jz @Continue cld @Loop1: //xor dwords at a time mov eax, [edi] xor [esi], eax add esi, 4 add edi, 4 dec ecx jnz @Loop1 @Continue: //handle remaining bytes (3 or less) pop ecx and ecx, 3 jz @Done @Loop2: //xor remaining bytes mov al, [edi] xor [esi], al inc esi inc edi dec ecx jnz @Loop2 @Done: pop edi pop esi end; { -------------------------------------------------------------------------- } procedure XorMem(var Mem1; const Mem2; Count : Cardinal); begin XorMemPrim(Mem1, Mem2, Count); end; { -------------------------------------------------------------------------- } procedure EncryptDES(const Context : TDESContext; var Block : TDESBlock); const SPBox : array [0..7, 0..63] of DWord = (($01010400, $00000000, $00010000, $01010404, $01010004, $00010404, $00000004, $00010000, $00000400, $01010400, $01010404, $00000400, $01000404, $01010004, $01000000, $00000004, $00000404, $01000400, $01000400, $00010400, $00010400, $01010000, $01010000, $01000404, $00010004, $01000004, $01000004, $00010004, $00000000, $00000404, $00010404, $01000000, $00010000, $01010404, $00000004, $01010000, $01010400, $01000000, $01000000, $00000400, $01010004, $00010000, $00010400, $01000004, $00000400, $00000004, $01000404, $00010404, $01010404, $00010004, $01010000, $01000404, $01000004, $00000404, $00010404, $01010400, $00000404, $01000400, $01000400, $00000000, $00010004, $00010400, $00000000, $01010004), ($80108020, $80008000, $00008000, $00108020, $00100000, $00000020, $80100020, $80008020, $80000020, $80108020, $80108000, $80000000, $80008000, $00100000, $00000020, $80100020, $00108000, $00100020, $80008020, $00000000, $80000000, $00008000, $00108020, $80100000, $00100020, $80000020, $00000000, $00108000, $00008020, $80108000, $80100000, $00008020, $00000000, $00108020, $80100020, $00100000, $80008020, $80100000, $80108000, $00008000, $80100000, $80008000, $00000020, $80108020, $00108020, $00000020, $00008000, $80000000, $00008020, $80108000, $00100000, $80000020, $00100020, $80008020, $80000020, $00100020, $00108000, $00000000, $80008000, $00008020, $80000000, $80100020, $80108020, $00108000), ($00000208, $08020200, $00000000, $08020008, $08000200, $00000000, $00020208, $08000200, $00020008, $08000008, $08000008, $00020000, $08020208, $00020008, $08020000, $00000208, $08000000, $00000008, $08020200, $00000200, $00020200, $08020000, $08020008, $00020208, $08000208, $00020200, $00020000, $08000208, $00000008, $08020208, $00000200, $08000000, $08020200, $08000000, $00020008, $00000208, $00020000, $08020200, $08000200, $00000000, $00000200, $00020008, $08020208, $08000200, $08000008, $00000200, $00000000, $08020008, $08000208, $00020000, $08000000, $08020208, $00000008, $00020208, $00020200, $08000008, $08020000, $08000208, $00000208, $08020000, $00020208, $00000008, $08020008, $00020200), ($00802001, $00002081, $00002081, $00000080, $00802080, $00800081, $00800001, $00002001, $00000000, $00802000, $00802000, $00802081, $00000081, $00000000, $00800080, $00800001, $00000001, $00002000, $00800000, $00802001, $00000080, $00800000, $00002001, $00002080, $00800081, $00000001, $00002080, $00800080, $00002000, $00802080, $00802081, $00000081, $00800080, $00800001, $00802000, $00802081, $00000081, $00000000, $00000000, $00802000, $00002080, $00800080, $00800081, $00000001, $00802001, $00002081, $00002081, $00000080, $00802081, $00000081, $00000001, $00002000, $00800001, $00002001, $00802080, $00800081, $00002001, $00002080, $00800000, $00802001, $00000080, $00800000, $00002000, $00802080), ($00000100, $02080100, $02080000, $42000100, $00080000, $00000100, $40000000, $02080000, $40080100, $00080000, $02000100, $40080100, $42000100, $42080000, $00080100, $40000000, $02000000, $40080000, $40080000, $00000000, $40000100, $42080100, $42080100, $02000100, $42080000, $40000100, $00000000, $42000000, $02080100, $02000000, $42000000, $00080100, $00080000, $42000100, $00000100, $02000000, $40000000, $02080000, $42000100, $40080100, $02000100, $40000000, $42080000, $02080100, $40080100, $00000100, $02000000, $42080000, $42080100, $00080100, $42000000, $42080100, $02080000, $00000000, $40080000, $42000000, $00080100, $02000100, $40000100, $00080000, $00000000, $40080000, $02080100, $40000100), ($20000010, $20400000, $00004000, $20404010, $20400000, $00000010, $20404010, $00400000, $20004000, $00404010, $00400000, $20000010, $00400010, $20004000, $20000000, $00004010, $00000000, $00400010, $20004010, $00004000, $00404000, $20004010, $00000010, $20400010, $20400010, $00000000, $00404010, $20404000, $00004010, $00404000, $20404000, $20000000, $20004000, $00000010, $20400010, $00404000, $20404010, $00400000, $00004010, $20000010, $00400000, $20004000, $20000000, $00004010, $20000010, $20404010, $00404000, $20400000, $00404010, $20404000, $00000000, $20400010, $00000010, $00004000, $20400000, $00404010, $00004000, $00400010, $20004010, $00000000, $20404000, $20000000, $00400010, $20004010), ($00200000, $04200002, $04000802, $00000000, $00000800, $04000802, $00200802, $04200800, $04200802, $00200000, $00000000, $04000002, $00000002, $04000000, $04200002, $00000802, $04000800, $00200802, $00200002, $04000800, $04000002, $04200000, $04200800, $00200002, $04200000, $00000800, $00000802, $04200802, $00200800, $00000002, $04000000, $00200800, $04000000, $00200800, $00200000, $04000802, $04000802, $04200002, $04200002, $00000002, $00200002, $04000000, $04000800, $00200000, $04200800, $00000802, $00200802, $04200800, $00000802, $04000002, $04200802, $04200000, $00200800, $00000000, $00000002, $04200802, $00000000, $00200802, $04200000, $00000800, $04000002, $04000800, $00000800, $00200002), ($10001040, $00001000, $00040000, $10041040, $10000000, $10001040, $00000040, $10000000, $00040040, $10040000, $10041040, $00041000, $10041000, $00041040, $00001000, $00000040, $10040000, $10000040, $10001000, $00001040, $00041000, $00040040, $10040040, $10041000, $00001040, $00000000, $00000000, $10040040, $10000040, $10001000, $00041040, $00040000, $00041040, $00040000, $10041000, $00001000, $00000040, $10040040, $00001000, $00041040, $10001000, $00000040, $10000040, $10040000, $10040040, $10000000, $00040000, $10001040, $00000000, $10041040, $00040040, $10000040, $10040000, $10001000, $10001040, $00000000, $10041040, $00041000, $00041000, $00001040, $00001040, $00040040, $10000000, $10041000)); var I, L, R, Work : DWord; CPtr : PDWord; procedure SplitBlock(const Block : TDESBlock; var L, R : DWord); register; asm push ebx push eax mov eax, [eax] mov bh, al mov bl, ah rol ebx, 16 shr eax, 16 mov bh, al mov bl, ah mov [edx], ebx pop eax mov eax, [eax+4] mov bh, al mov bl, ah rol ebx, 16 shr eax, 16 mov bh, al mov bl, ah mov [ecx], ebx pop ebx end; procedure JoinBlock(const L, R : LongInt; var Block : TDESBlock); register; asm push ebx mov bh, al mov bl, ah rol ebx, 16 shr eax, 16 mov bh, al mov bl, ah mov [ecx+4], ebx mov bh, dl mov bl, dh rol ebx, 16 shr edx, 16 mov bh, dl mov bl, dh mov [ecx], ebx pop ebx end; procedure IPerm(var L, R : DWord); var Work : DWord; begin Work := ((L shr 4) xor R) and $0F0F0F0F; R := R xor Work; L := L xor Work shl 4; Work := ((L shr 16) xor R) and $0000FFFF; R := R xor Work; L := L xor Work shl 16; Work := ((R shr 2) xor L) and $33333333; L := L xor Work; R := R xor Work shl 2; Work := ((R shr 8) xor L) and $00FF00FF; L := L xor Work; R := R xor Work shl 8; R := (R shl 1) or (R shr 31); Work := (L xor R) and $AAAAAAAA; L := L xor Work; R := R xor Work; L := (L shl 1) or (L shr 31); end; procedure FPerm(var L, R : DWord); var Work : DWord; begin L := L; R := (R shl 31) or (R shr 1); Work := (L xor R) and $AAAAAAAA; L := L xor Work; R := R xor Work; L := (L shr 1) or (L shl 31); Work := ((L shr 8) xor R) and $00FF00FF; R := R xor Work; L := L xor Work shl 8; Work := ((L shr 2) xor R) and $33333333; R := R xor Work; L := L xor Work shl 2; Work := ((R shr 16) xor L) and $0000FFFF; L := L xor Work; R := R xor Work shl 16; Work := ((R shr 4) xor L) and $0F0F0F0F; L := L xor Work; R := R xor Work shl 4; end; begin SplitBlock(Block, L, R); IPerm(L, R); CPtr := @Context; for I := 0 to 7 do begin Work := (((R shr 4) or (R shl 28)) xor CPtr^); Inc(CPtr); L := L xor SPBox[6, Work and $3F]; L := L xor SPBox[4, Work shr 8 and $3F]; L := L xor SPBox[2, Work shr 16 and $3F]; L := L xor SPBox[0, Work shr 24 and $3F]; Work := (R xor CPtr^); Inc(CPtr); L := L xor SPBox[7, Work and $3F]; L := L xor SPBox[5, Work shr 8 and $3F]; L := L xor SPBox[3, Work shr 16 and $3F]; L := L xor SPBox[1, Work shr 24 and $3F]; Work := (((L shr 4) or (L shl 28)) xor CPtr^); Inc(CPtr); R := R xor SPBox[6, Work and $3F]; R := R xor SPBox[4, Work shr 8 and $3F]; R := R xor SPBox[2, Work shr 16 and $3F]; R := R xor SPBox[0, Work shr 24 and $3F]; Work := (L xor CPtr^); Inc(CPtr); R := R xor SPBox[7, Work and $3F]; R := R xor SPBox[5, Work shr 8 and $3F]; R := R xor SPBox[3, Work shr 16 and $3F]; R := R xor SPBox[1, Work shr 24 and $3F]; end; FPerm(L, R); JoinBlock(L, R, Block); end; procedure InitEncryptDES(const Key : TKey64; var Context : TDESContext; Encrypt : Boolean); const PC1 : array [0..55] of Byte = (56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3); PC2 : array [0..47] of Byte = (13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31); CTotRot : array [0..15] of Byte = (1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28); CBitMask : array [0..7] of Byte = (128, 64, 32, 16, 8, 4, 2, 1); var PC1M : array [0..55] of Byte; PC1R : array [0..55] of Byte; KS : array [0..7] of Byte; I, J, L, M : LongInt; begin {convert PC1 to bits of key} for J := 0 to 55 do begin L := PC1[J]; M := L mod 8; PC1M[J] := Ord((Key[L div 8] and CBitMask[M]) 0); end; {key chunk for each iteration} for I := 0 to 15 do begin {rotate PC1 the right amount} for J := 0 to 27 do begin L := J + CTotRot[I]; if (L (length(keystr)-1) then key[i] :=0 else key[i] := byte(keystr[i+1]); end; for i:=0 to 7 do begin if i > (length(ivstr)-1) then iv[i]:=0 else iv[i] := byte(ivstr[i+1]); end; InitEncryptDES(Key, Context, true); len := length(AnsiString(str)); xx:= char( 8- (len mod 8)); if len<=8 then xuhuan:=0 else xuhuan:=round(len/8); for i:=0 to xuhuan do begin for j:=0 to 7 do begin if ((i*8+j+1) (length(temp)-1) then key[i] :=0 else key[i] := byte(temp[i+1]); end; temp := ivstr; for i:=0 to 7 do begin if i > (length(temp)-1) then iv[i] := 0 else iv[i] := byte(temp[i+1]); end; InitEncryptDES(Key, Context, False); temp := str; posnum := 0; for i:=0 to length(temp)-1 do begin Block[posnum] := byte(temp[i+1]); posnum := posnum+1; if posnum = 8 then begin bak := block; EncryptDESCBC(Context, IV, Block); for j:= 0 to 7 do begin // temp := temp+inttostr(byte(block[i]))+' '; res := res + char(block[j]); end; iv := bak; posnum := 0; end; end; if posnum 0 then begin // end else begin temp:=''; for i:= 1 to length(res) do begin temp := temp+char(res[i]); end; Result:= trim(temp); end; end; function DecryDes(const str:string;const keystr:string;const ivstr:string):string ; var key:tkey64; Context:TDESContext; bak,Block,iv:TDESBlock; i,j,len,posnum:smallint; poschar,xx:char; res,lss:string; begin for i:=0 to 7 do begin if i > (length(keystr)-1) then key[i] :=0 else key[i] := byte(keystr[i+1]); end; for i:=0 to 15 do begin if i > (length(ivstr)-1) then iv[i]:=0 else iv[i] := byte(ivstr[i+1]); end; InitEncryptDES(Key, Context, false); res:=''; for j:= 0 to (length(str) div 2)-1 do begin lss:=copy(str,j*2+1,2); res:=res+ char(StrToInt('$'+lss)) ; end; len := length(AnsiString(res)); for i:=0 to round(len/8)-1 do begin for j:=0 to 7 do begin if ((i*7+j+1)<=len) then begin poschar:=res[i*8+j+1]; block[j]:=byte(poschar); end else begin block[j]:=byte(xx); end; end; bak:=block; EncryptDESCBC(Context, IV, Block); for j:= 0 to 7 do begin result := result + char(block[j]); end; iv:=bak; end; end; end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值