以下为c,delphi的des加密解密算法,现在除了中文外其余的,都没问题。哪位帮忙看看是何原因,谢谢!
unit DESUnit;
interface
uses
SysUtils;
function DESEncryptStr(Str, Key: String): String;
function DESDecryptStr(Str, Key: String): String;
function DESEncryptStrToHex(Str, Key: String): String;
function DESDecryptStrFromHex(StrHex, Key: String): String;
implementation
const
BitIP: array[0..63] of Byte =
(57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7,
56, 48, 40, 32, 24, 16, 8, 0,
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6);
BitCP: array[0..63] of Byte =
(39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25,
32, 0, 40, 8, 48, 16, 56, 24);
BitExp: array[0..47] of Byte =
(31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10,
11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20,
21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0);
BitPM: array[0..31] of Byte =
(15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9,
1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24);
sBox: array[0..7] of array[0..63] of Byte =
((14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13),
(15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9),
(10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12),
(7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14),
(2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3),
(12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13),
(4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12),
(13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11));
BitPMC1: 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);
BitPMC2: 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);
type
TKeyByte = array[0..5] of Byte;
TDesMode = (dmEncry, dmDecry);
var
subKey: array[0..15] of TKeyByte;
procedure InitPermutation(var inData: array of Byte);
var
newData: array[0..7] of Byte;
I: Integer;
begin
FillChar(newData, 8, 0);
for I := 0 to 63 do
if (inData[BitIP[I] shr 3] and (1 shl (7 - (BitIP[I] and $07)))) <> 0 then
newData[I shr 3] := newData[I shr 3] or (1 shl (7 - (I and $07)));
for I := 0 to 7 do inData[I] := newData[I];
end;
procedure ConversePermutation(var inData: array of Byte);
var
newData: array[0..7] of Byte;
I: Integer;
begin
FillChar(newData, 8, 0);
for I := 0 to 63 do
if (inData[BitCP[I] shr 3] and (1 shl (7 - (BitCP[I] and $07)))) <> 0 then
newData[I shr 3] := newData[I shr 3] or (1 shl (7 - (I and $07)));
for I := 0 to 7 do inData[I] := newData[I];
end;
procedure Expand(inData: array of Byte; var outData: array of Byte);
var
I: Integer;
begin
FillChar(outData, 6, 0);
for I := 0 to 47 do
if (inData[BitExp[I] shr 3] and (1 shl (7 - (BitExp[I] and $07)))) <> 0 then
outData[I shr 3] := outData[I shr 3] or (1 shl (7 - (I and $07)));
end;
procedure Permutation(var inData: array of Byte);
var
newData: array[0..3] of Byte;
I: Integer;
begin
FillChar(newData, 4, 0);
for I := 0 to 31 do
if (inData[BitPM[I] shr 3] and (1 shl (7 - (BitPM[I] and $07)))) <> 0 then
newData[I shr 3] := newData[I shr 3] or (1 shl (7 - (I and $07)));
for I := 0 to 3 do inData[I] := newData[I];
end;
function Si(s, inByte: Byte): Byte;
var
c: Byte;
begin
c := (inByte and $20) or ((inByte and $1E) shr 1) or
((inByte and $01) shl 4);
Result := (sBox[s][c] and $0F);
end;
procedure PermutationChoose1(inData: array of Byte; var outData: array of Byte);
var
I: Integer;
begin
FillChar(outData, 7, 0);
for I := 0 to 55 do
if (inData[BitPMC1[I] shr 3] and (1 shl (7 - (BitPMC1[I] and $07)))) <> 0 then
outData[I shr 3] := outData[I shr 3] or (1 shl (7 - (I and $07)));
end;
procedure PermutationChoose2(inData: array of Byte; var outData: array of Byte);
var
I: Integer;
begin
FillChar(outData, 6, 0);
for I := 0 to 47 do
if (inData[BitPMC2[I] shr 3] and (1 shl (7 - (BitPMC2[I] and $07)))) <> 0 then
outData[I shr 3] := outData[I shr 3] or (1 shl (7 - (I and $07)));
end;
procedure cycleMove(var inData: array of Byte; bitMove: Byte);
var
I: Integer;
begin
for I := 0 to bitMove - 1 do
begin
inData[0] := (inData[0] shl 1) or (inData[1] shr 7);
inData[1] := (inData[1] shl 1) or (inData[2] shr 7);
inData[2] := (inData[2] shl 1) or (inData[3] shr 7);
inData[3] := (inData[3] shl 1) or ((inData[0] and $10) shr 4);
inData[0] := (inData[0] and $0F);
end;
end;
procedure MakeKey(inKey: array of Byte; var outKey: array of TKeyByte);
const
bitDisplace: array[0..15] of Byte =
(1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1);
var
outData56: array[0..6] of Byte;
key28l: array[0..3] of Byte;
key28r: array[0..3] of Byte;
key56o: array[0..6] of Byte;
I: Integer;
begin
permutationChoose1(inKey, outData56);
key28l[0] := outData56[0] shr 4;
key28l[1] := (outData56[0] shl 4) or (outData56[1] shr 4);
key28l[2] := (outData56[1] shl 4) or (outData56[2] shr 4);
key28l[3] := (outData56[2] shl 4) or (outData56[3] shr 4);
key28r[0] := outData56[3] and $0F;
key28r[1] := outData56[4];
key28r[2] := outData56[5];
key28r[3] := outData56[6];
for I := 0 to 15 do
begin
cycleMove(key28l, bitDisplace[I]);
cycleMove(key28r, bitDisplace[I]);
key56o[0] := (key28l[0] shl 4) or (key28l[1] shr 4);
key56o[1] := (key28l[1] shl 4) or (key28l[2] shr 4);
key56o[2] := (key28l[2] shl 4) or (key28l[3] shr 4);
key56o[3] := (key28l[3] shl 4) or (key28r[0]);
key56o[4] := key28r[1];
key56o[5] := key28r[2];
key56o[6] := key28r[3];
permutationChoose2(key56o, outKey[I]);
end;
end;
procedure Encry(inData, subKey: array of Byte; var outData: array of Byte);
var
outBuf: array[0..5] of Byte;
buf: array[0..7] of Byte;
I: Integer;
begin
expand(inData, outBuf);
for I := 0 to 5 do outBuf[I] := outBuf[I] xor subKey[I];
buf[0] := outBuf[0] shr 2;
buf[1] := ((outBuf[0] and $03) shl 4) or (outBuf[1] shr 4);
buf[2] := ((outBuf[1] and $0F) shl 2) or (outBuf[2] shr 6);
buf[3] := outBuf[2] and $3F;
buf[4] := outBuf[3] shr 2;
buf[5] := ((outBuf[3] and $03) shl 4) or (outBuf[4] shr 4);
buf[6] := ((outBuf[4] and $0F) shl 2) or (outBuf[5] shr 6);
buf[7] := outBuf[5] and $3F;
for I := 0 to 7 do buf[I] := si(I, buf[I]);
for I := 0 to 3 do outBuf[I] := (buf[I * 2] shl 4) or buf[I * 2 + 1];
permutation(outBuf);
for I := 0 to 3 do outData[I] := outBuf[I];
end;
procedure DesData(desMode: TDesMode; inData: array of Byte; var outData: array
of Byte);
var
I, j: Integer;
temp, buf: array[0..3] of Byte;
begin
for I := 0 to 7 do outData[I] := inData[I];
initPermutation(outData);
if desMode = dmEncry then
begin
for I := 0 to 15 do
begin
for j := 0 to 3 do temp[j] := outData[j];
for j := 0 to 3 do outData[j] := outData[j + 4];
encry(outData, subKey[I], buf);
for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j];
end;
for j := 0 to 3 do temp[j] := outData[j + 4];
for j := 0 to 3 do outData[j + 4] := outData[j];
for j := 0 to 3 do outData[j] := temp[j];
end
else if desMode = dmDecry then
begin
for I := 15 downto 0 do
begin
for j := 0 to 3 do temp[j] := outData[j];
for j := 0 to 3 do outData[j] := outData[j + 4];
encry(outData, subKey[I], buf);
for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j];
end;
for j := 0 to 3 do temp[j] := outData[j + 4];
for j := 0 to 3 do outData[j + 4] := outData[j];
for j := 0 to 3 do outData[j] := temp[j];
end;
conversePermutation(outData);
end;
function DESEncryptStr(Str, Key: String): String;
var
StrByte, OutByte, KeyByte: array[0..7] of Byte;
StrResult: String;
I, j: Integer;
begin
if (Length(Str) > 0) and (Ord(Str[Length(Str)]) = 0) then
raise Exception.Create('Error: the last char is NULL char.');
if Length(Key) < 8 then
while Length(Key) < 8 do Key := Key + Chr(0);
while Length(Str) mod 8 <> 0 do Str := Str + Chr(0);
for j := 0 to 7 do KeyByte[j] := Ord(Key[j + 1]);
makeKey(KeyByte, subKey);
StrResult := '';
for I := 0 to Length(Str) div 8 - 1 do
begin
for j := 0 to 7 do
StrByte[j] := Ord(Str[I * 8 + j + 1]);
desData(dmEncry, StrByte, OutByte);
for j := 0 to 7 do
StrResult := StrResult + Char(OutByte[j]);
end;
Result := StrResult;
end;
function DESDecryptStr(Str, Key: String): String;
var
StrByte, OutByte, KeyByte: array[0..7] of Byte;
StrResult: String;
I, j: Integer;
begin
if Length(Key) < 8 then
while Length(Key) < 8 do Key := Key + Chr(0);
for j := 0 to 7 do KeyByte[j] := Ord(Key[j + 1]);
makeKey(KeyByte, subKey);
StrResult := '';
for I := 0 to Length(Str) div 8 - 1 do
begin
for j := 0 to 7 do StrByte[j] := Ord(Str[I * 8 + j + 1]);
desData(dmDecry, StrByte, OutByte);
for j := 0 to 7 do
StrResult := StrResult + Char(OutByte[j]);
end;
while (Length(StrResult) > 0) and
(Ord(StrResult[Length(StrResult)]) = 0) do
Delete(StrResult, Length(StrResult), 1);
Result := StrResult;
end;
function DESEncryptStrToHex(Str, Key: String): String;
var
StrResult, TempResult, temp: String;
I: Integer;
begin
TempResult := DESEncryptStr(Str, Key);
StrResult := '';
for I := 0 to Length(TempResult) - 1 do
begin
temp := String(Format('%x', [Ord(TempResult[I + 1])]));
if Length(temp) = 1 then temp := '0' + temp;
StrResult := StrResult + temp;
end;
Result := StrResult;
end;
function HexToInt(Hex: String): Integer;
var
I, Res: Integer;
ch: AnsiChar;
begin
Res := 0;
for I := 0 to Length(Hex) - 1 do
begin
ch := Hex[I + 1];
if (ch >= '0') and (ch <= '9') then
Res := Res * 16 + Ord(ch) - Ord('0')
else if (ch >= 'A') and (ch <= 'F') then
Res := Res * 16 + Ord(ch) - Ord('A') + 10
else if (ch >= 'a') and (ch <= 'f') then
Res := Res * 16 + Ord(ch) - Ord('a') + 10
else raise Exception.Create('Error: not a Hex String');
end;
Result := Res;
end;
function DESDecryptStrFromHex(StrHex, Key: String): String;
var
Str, temp: String;
I: Integer;
begin
Str := '';
for I := 0 to Length(StrHex) div 2 - 1 do
begin
temp := Copy(StrHex, I * 2 + 1, 2);
Str := Str + Char(HexToInt(temp));
end;
Result := DESDecryptStr(Str, Key);
end;
end.
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <ctype.h>
#define MAXPKGLEN 10240
#define ENCRYPT 0
#define DECRYPT 1
#define ECB 0
#define CBC 1
#define KEY_LEN_8 8
#define KEY_LEN_16 16
#define KEY_LEN_24 24
#define PAD_ISO_1 0
#define PAD_ISO_2 1
#define PAD_PKCS_7 2
#define PAD_BLANK 9
typedef enum
{
false = 0,
true = 1
} bool;
typedef char (*PSubKey)[16][48];
const char IP_Table[64] =
{
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
const char IPR_Table[64] =
{
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
const char E_Table[48] =
{
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
const char P_Table[32] =
{
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
const char PC1_Table[56] =
{
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
const char PC2_Table[48] =
{
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
const char LOOP_Table[16] =
{
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
const char S_Box[8][4][16] =
{
{
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
{ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
{ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
},
{
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
{ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
{ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}
},
{
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
{ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
},
{
{ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
{ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
},
{
{ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
{ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
},
{
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
{ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
{ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}
},
{
{ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
{ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
{ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
},
{
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
{ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
{ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
{ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}
}
};
static void ByteToBit(char *Out, const char *In, int bits);
static void BitToByte(char *Out, const char *In, int bits);
static void RotateL(char *In, int len, int loop);
static void Xor(char *InA, const char *InB, int len);
static void Transform(char *Out, const char *In, const char *Table, int len);
static void S_func(char Out[32], const char In[48]);
static void F_func(char In[32], const char Ki[48]);
static void SetSubKey(PSubKey pSubKey, const char Key[8]);
static void DES(char Out[8], const char In[8], const PSubKey pSubKey, int Type);
/*******************************************************************
函 数 名 称: ByteToBit
功 能 描 述: 把BYTE转化为Bit流
参 数 说 明: Out: 输出的Bit流[in][out]
In: 输入的BYTE流[in]
bits: Bit流的长度[in]
返回值 说明: void
*******************************************************************/
static void ByteToBit(char *Out, const char *In, int bits)
{
int i;
for (i=0; i<bits; ++i)
Out[i] = (In[i>>3]>>(7 - i&7)) & 1;
}
/*******************************************************************
函 数 名 称: BitToByte
功 能 描 述: 把Bit转化为Byte流
参 数 说 明: Out: 输出的BYTE流[in][out]
In: 输入的Bit流[in]
bits: Bit流的长度[in]
返回值 说明: void
*******************************************************************/
static void BitToByte(char *Out, const char *In, int bits)
{
int i;
memset(Out, 0, bits>>3);
for (i=0; i<bits; ++i)
Out[i>>3] |= In[i]<<(7 - i&7);
}
/*******************************************************************
函 数 名 称: RotateL
功 能 描 述: 把BIT流按位向左迭代
参 数 说 明: In: 输入的Bit流[in][out]
len: Bit流的长度[in]
loop: 向左迭代的长度
返回值 说明: void
*******************************************************************/
static void RotateL(char *In, int len, int loop)
{
char szTmp[256] ;
if (len >= 256)
return;
if (loop <= 0 || loop>=256)
return;
memset(szTmp, 0x00, sizeof(szTmp));
memcpy(szTmp, In, loop);
memmove(In, In+loop, len-loop);
memcpy(In+len-loop, szTmp, loop);
}
/*******************************************************************
函 数 名 称: Xor
功 能 描 述: 把两个Bit流进行异或
参 数 说 明: InA: 输入的Bit流[in][out]
InB: 输入的Bit流[in]
loop: Bit流的长度
返回值 说明: void
*******************************************************************/
static void Xor(char *InA, const char *InB, int len)
{
int i;
for (i=0; i<len; ++i)
InA[i] ^= InB[i];
}
/*******************************************************************
函 数 名 称: Transform
功 能 描 述: 把两个Bit流按表进行位转化
参 数 说 明: Out: 输出的Bit流[out]
In: 输入的Bit流[in]
Table: 转化需要的表指针
len: 转化表的长度
返回值 说明: void
*******************************************************************/
static void Transform(char *Out, const char *In, const char *Table, int len)
{
char szTmp[256] ;
int i;
if (!Out || !In || !Table)
return;
if (len >= 256)
return;
memset(szTmp, 0x00, sizeof(szTmp));
for (i=0; i<len; ++i)
szTmp[i] = In[Table[i]-1];
memcpy(Out, szTmp, len);
}
/*******************************************************************
函 数 名 称: S_func
功 能 描 述: 实现数据加密S BOX模块
参 数 说 明: Out: 输出的32Bit[out]
In: 输入的48Bit[in]
返回值 说明: void
*******************************************************************/
static void S_func(char Out[32], const char In[48])
{
int i,j,k,l;
for (i=0,j=0,k=0; i<8; ++i,In+=6,Out+=4){
j = (In[0]<<1) + In[5];
k = (In[1]<<3) + (In[2]<<2) + (In[3]<<1) + In[4];
for ( l=0; l<4; ++l)
Out[l] = (S_Box[i][j][k]>>(3 - l)) & 1;
}
}
/*******************************************************************
函 数 名 称: F_func
功 能 描 述: 实现数据加密到输出P
参 数 说 明: Out: 输出的32Bit[out]
In: 输入的48Bit[in]
返回值 说明: void
*******************************************************************/
static void F_func(char In[32], const char Ki[48])
{
char MR[48] = {0};
memset(MR, 0x00, sizeof(MR));
Transform(MR, In, E_Table, 48);
Xor(MR, Ki, 48);
S_func(In, MR);
Transform(In, In, P_Table, 32);
}
/*******************************************************************
函 数 名 称: SetSubKey
功 能 描 述: 变换(换位)8字节密钥,生成16个子密钥
参 数 说 明: pSubKey: 转换生成的16个子密钥[out]
Key: 输入的8字节64Bit密钥[in]
返回值 说明: void
*******************************************************************/
static void SetSubKey(PSubKey pSubKey, const char Key[8])
{
int i;
char K[64] = {0}, *KL=&K[0], *KR=&K[28];
ByteToBit(K, Key, 64);
Transform(K, K, PC1_Table, 56);
for ( i=0; i<16; ++i){
RotateL(KL, 28, LOOP_Table[i]);
RotateL(KR, 28, LOOP_Table[i]);
Transform((*pSubKey)[i], K, PC2_Table, 48);
}
}
/*******************************************************************
函 数 名 称: DES
功 能 描 述: 处理8字节64位的数据
参 数 说 明: Out: 输出的8字节[out]
In: 输入的8字节待加密[in]
pSubKey: 转换后的16个48位子密钥
Type: 类型:加密ENCRYPT,解密DECRYPT
返回值 说明: void
*******************************************************************/
static void DES(char Out[8], const char In[8], const PSubKey pSubKey, int Type)
{
int i;
char M[64] = {0}, *ML=&M[0], *MR=&M[32], szTmp[32] = {0};
ByteToBit(M, In, 64);
Transform(M, M, IP_Table, 64);
if (Type == ENCRYPT){
for (i=0; i<16; ++i){
memcpy(szTmp, MR, 32);
F_func(MR, (*pSubKey)[i]);
Xor(MR, ML, 32);
memcpy(ML, szTmp, 32);
}
}
else{
for (i=15; i>=0; --i){
memcpy(szTmp, MR, 32);
F_func(MR, (*pSubKey)[i]);
Xor(MR, ML, 32);
memcpy(ML, szTmp, 32);
}
}
RotateL(M, 64, 32);
Transform(M, M, IPR_Table, 64);
BitToByte(Out, M, 64);
}
/*******************************************************************
函 数 名 称: Run1Des
功 能 描 述: 执行单DES算法对文本加解密
参 数 说 明: bType :类型:加密ENCRYPT,解密DECRYPT
bMode :模式:ECB,CBC
In :待加密串指针
in_len :待加密串的长度,同时Out的缓冲区大小应大于或者等于in_len
Key :密钥(可为8位,16位,24位)支持3密钥
key_len :密钥长度
Out :待输出串指针
out_len :输出缓存大小
cvecstr :8字节随即字符串
返回值 说明: int :是否加密成功,1:成功,0:失败
*******************************************************************/
int Run1Des(int bType, int bMode, const char *In, unsigned int in_len, const char *Key, unsigned int key_len, char* Out, unsigned int
out_len, const char cvecstr[8]){
int i,j,k;
char m_SubKey[16][48] = {0};
char cvec[8] = {0};
char cvin[8] = {0};
/*参数不合法*/
if (!In || !Key || !Out)
return 0;
/*密钥长度,单DES只支持8字节(64位的密钥,每个第8位作为奇偶校验位),多于8字节的自动裁剪*/
if (key_len %8 != 0 )
return 0;
/*被加密数据长度,必需为8字节的倍数,如果非8的倍数,调用RunPad()函数补位*/
if (in_len %8 != 0 )
return 0;
/*输出缓存大小判断*/
if (out_len < in_len)
return 0;
/*生成16个子密钥*/
memset(m_SubKey, 0x00, sizeof(m_SubKey));
SetSubKey(&m_SubKey, Key);
if (bMode == ECB){
/*每8字节加密*/
for (i=0,j=in_len>>3; i<j; ++i,Out+=8,In+=8){
DES(Out, In, &m_SubKey, bType);
}
}
else if (bMode == CBC){
if (cvecstr == NULL)
return 0;
memcpy(cvec, cvecstr, 8);
for (i=0,j=in_len>>3; i<j; ++i,Out+=8,In+=8){
if (bType == ENCRYPT){
for ( k=0; k<8; ++k){
cvin[k] = In[k] ^ cvec[k];
}
}
else{
memcpy(cvin, In, 8);
}
DES(Out, cvin, &m_SubKey, bType);
if (bType == ENCRYPT){
memcpy(cvec, Out, 8);
}
else{
for (k=0; k<8; ++k){
Out[k] = Out[k] ^ cvec[k];
}
memcpy(cvec, cvin, 8);
}
}
}
else{
return 0;
}
return 1;
}
/*******************************************************************
函 数 名 称: RunPad
功 能 描 述: 根据协议对加密前的数据进行填充
参 数 说 明: nType :类型:PAD类型
In :数据串指针
Out :填充输出串指针
in_len :数据的长度
padlen :(in,out)输出buffer的长度,填充后的长度
返回值 说明: 是否填充成功
*******************************************************************/
int RunPad(int nType,const char* In,int datalen,char* Out,int* padlen)
{
int res = datalen %8 ;
char cEmpty[8]={' ',' ',' ',' ',' ',' ',' '}; //不足8的倍数后面补空格
if(*padlen < (datalen+8-res)){
return 0;
}
else{
memcpy(Out,In,datalen);
if (res == 0) {
*padlen =datalen;
return 1;
}
*padlen = (datalen+8-res);
}
if(nType == PAD_ISO_1){
memset(Out+datalen,0x00,8-res);
}
else if(nType == PAD_ISO_2){
memset(Out+datalen,0x80,1);
memset(Out+datalen,0x00,7-res);
}
else if(nType == PAD_PKCS_7) {
memset(Out+datalen,8-res,8-res);
}
else{
strncat((char*)Out+datalen,cEmpty,8-res);
}
return 1;
}
/*解密后,将填充的字符去掉*/
void RunRsm(char *Text)
{
int len,tmpint;
len=strlen(Text);
tmpint=*(Text+len-1);
*(Text+len-tmpint)=0x00;
}
/*----------------------------------
二进制密文转换为十六进制
需要16个字符表示
-----------------------------------*/
void BitToHex(char *DatOut,bool *DatIn,int Num)
{
int i=0;
for(i=0;i<Num/4;i++)
{
DatOut[i]=0;
}
for(i=0;i<Num/4;i++)
{
DatOut[i] = DatIn[i*4]+(DatIn[i*4+1]<<1)
+(DatIn[i*4+2]<<2)+(DatIn[i*4+3]<<3);
if((DatOut[i]%16)>9)
{
DatOut[i]=DatOut[i]%16+'7'; /* 余数大于9时处理 10-15 to A-F*/
} /* 输出字符 */
else
{
DatOut[i]=DatOut[i]%16+'0'; /* 输出字符 */
}
}
}
/*---------------------------------------------
// 十六进制字符转二进制
//----------------------------------------------*/
void HexToBit(bool *DatOut,char *DatIn,int Num)
{
int i=0; /* 字符型输入 */
for(i=0;i<Num;i++)
{
if((DatIn[i/4])>'9') /* 大于9 */
{
DatOut[i]=((DatIn[i/4]-'7')>>(i%4))&0x01;
}
else
{
DatOut[i]=((DatIn[i/4]-'0')>>(i%4))&0x01;
}
}
}
int send(unsigned char *in,int *len){
unsigned char souchar[MAXPKGLEN];
unsigned char destchar[MAXPKGLEN];
unsigned char pad[MAXPKGLEN];
unsigned char tmp_str[MAXPKGLEN];
char cvecstr[8];
int ret,out_len,pad_len;
printf("-send-[%d][%s]--\n",*len,in);
/**加密**/
memset(souchar,0x00,sizeof(souchar));
memset(destchar,0x00,sizeof(destchar));
memset(cvecstr,0x00,sizeof(cvecstr));
memset(pad,0x00,sizeof(pad));
memset(tmp_str,0x00,sizeof(tmp_str));
strcpy(souchar,in);
pad_len = MAXPKGLEN ;
ret = RunPad(PAD_ISO_1,souchar,*len,pad,&pad_len);
out_len = MAXPKGLEN ;
ret = Run1Des( ENCRYPT, ECB, pad, pad_len , "test_key", 8, destchar, out_len, cvecstr) ;
ret = bcl_xstr_to_strx(destchar,pad_len,tmp_str);
printf("--AA[%d][%s][%s]--\n",pad_len,destchar,tmp_str);
memset(destchar,0x00,sizeof(destchar));
ret = bcl_strx_to_xstr(tmp_str,destchar);
printf("--BB[%d][%s][%s]--\n",pad_len,destchar,tmp_str);
*len = pad_len*2;
printf("-send[%d]-[%s]--\n",*len,tmp_str);
printf("%s\n",in);
return 0 ;
}
int recv(unsigned char *in,int *len){
unsigned char souchar[MAXPKGLEN];
unsigned char destchar[MAXPKGLEN];
unsigned char tmp_str[MAXPKGLEN];
int i,ret,out_len,in_len;
char cvecstr[8];
if(*len >= MAXPKGLEN )
return -1 ;
/**解密**/
memset(souchar,0x00,sizeof(souchar));
memset(destchar,0x00,sizeof(destchar));
memset(cvecstr,0x00,sizeof(cvecstr));
memcpy(souchar, in,*len);
ret = bcl_strx_to_xstr(souchar,tmp_str);
in_len = *len/2;
out_len = MAXPKGLEN;
ret = Run1Des(DECRYPT, ECB, tmp_str, in_len , "test_key", 8 , destchar, out_len, cvecstr) ;
printf("-解密-[%s]--[%d]--\n",destchar,in_len);
for(i=0;i<in_len;i++) {
printf("%c",destchar[i]);
}
printf("\n");
for(i=0;i<in_len;i++) {
printf("%02X",destchar[i]);
}
printf("\n");
*len = in_len;
printf("-8-[%s]--[%d]--\n",in,*len);
return 0 ;
}
int bcl_xstr_to_strx(unsigned char *xstr,int len,char *strx){
int i;
if(xstr ==NULL)
return 0;
if(strx ==NULL )
return -1;
for(i=0;i<len;i++){
sprintf(&strx[i*2],"%02X",xstr[i]);
}
strx[i*2+1] = 0x0 ;
return 0;
}
int bcl_strx_to_xstr( char * strx, unsigned char * xstr )
{
int i;
int ch;
int len;
char buf[5];
if ( strx == NULL )
return 0;
len = strlen( strx );
if ( len == 0 )
return 0;
if ( len % 2 != 0 )
return -1;
for ( i = 0; i < len / 2; i++ ) {
memcpy( buf, &strx[i*2], 2 );
if ( !isdigit(buf[0]) ) {
if ( toupper(buf[0]) < 'A' || toupper(buf[0]) > 'F' )
return -1;
}
if ( !isdigit(buf[1]) ) {
if ( toupper(buf[1]) < 'A' || toupper(buf[1]) > 'F' )
return -1;
}
buf[2] = 0x0;
sscanf( buf, "%x", &ch );
xstr[i] = ch;
}
xstr[i] = 0x0;
return 0;
}
int main(int argc, char* argv[]){
unsigned char *in="D20F5ADD4F4BF775";
int len1=strlen(in);
int *len=&len1;
//send(in,len);
recv(in,len);
return 0;
}