IDEA加密算法,本人新手,最好能有详细说明。
本人想开发一个BS客户端加密,服务器端解密的登录系统。
客户端准备使用JS编写加密算法,服务器端准备用C#编写服务器端解密算法。
现征求:
JavaScript的IDEA客户端加密算法和C#的服务器端解密算法!若谁有现成的登录系统,可以发到我邮箱,分不够,可以另开新帖!

解决方案 »

  1.   

    unit IDEA;interfaceuses
      Windows, Messages, SysUtils, Classes,Dialogs;
      function BinToHex(strBin:string):string;
      function HexToTen(strHex:string):int64;
      function LeftMove(S:string;P:integer):String;
      function ModAdd(intAdd1,intAdd2:int64):int64;
      function ModMul(intMul1,intMul2:int64;intFlag:integer):int64;
      function ModXor(intXor1,intXor2:int64):int64;
      procedure CreatePassword(strPassword:string;VAR arrPassword:array of int64;VAR arrOpenPassword:array of int64);       //产生加密子密钥函数
      procedure GetOpenPassword(intSource:int64;VAR intResult:int64;Flag:integer);       //求取解密子密钥函数
      procedure CreateKeyTable();                         //产生加、解密子密钥之间的对应关系表
      procedure Riddle(arrPassword:array of int64;arrRiddleKey:array of int64;VAR arrOpenPassword:array of int64);StdCall;export;         //IDEA数据解密函数
      procedure CreateOpenPassword(VAR arrOpenPassKey:array of int64);                     //产生解密子密钥函数
      procedure CreateKey(VAR arrKey:array of int64;VAR arrOpenKey:array of int64;VAR strOutKey:string);StdCall;export;     //产生加密密钥函数
    implementationConst strNum:array[1..16] of string[4]=('0000','0001','0010','0011','0100','0101','0110','0111','1000','1001','1010','1011','1100','1101','1110','1111');
    Const chrHex:array[1..16] of char=('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
    var
      g_arr_Ten_Password:array[1..52] of int64;
      g_arr_Flag:array[1..52] of integer;
      g_arr_Table:array[1..52] of integer;
    ...{--------------------------------------------------------------------}procedure CreateKey(VAR arrKey:array of int64;VAR arrOpenKey:array of int64;VAR strOutKey:string);StdCall;export;
    var
    intKey,intLoop1,intLoop2,intLoop3:integer;
    hexKey,ch,strTemp:string;
    strKey:string[128];
    begin
    strKey:='';
    Randomize;
    for intLoop1:=1 to 8 do
     begin
       intKey:=Random(65536);
       hexKey:=IntToHex(intKey,4);
       strTemp:='';
       for intLoop2:=1 to 4 do
        begin
         ch:=Copy(hexKey,intLoop2,1);
         for intLoop3:=1 to 16 do
          begin
            if ch = chrHex[intLoop3] then
              begin
               ch:= strNum[intLoop3];
               break;
              end;
          end;
         strTemp:=strTemp+ch;
        end;
       strKey:=strKey+strTemp;
     end;
    strOutKey:=strKey;                          
    CreatePassword(strKey,arrKey,arrOpenKey);       //调用产生加密子密钥过程
    end;
    ...{--------------------------------------------------------------------}function BinToHex(strBin:string):string;
    var
    intLoop1,intLoop2:integer;
    strTemp,strResult:string;
    begin
    intLoop1:=1;
    strResult:='';
    if Length(strBin) <> 16 then ShowMessage('二进制数据长度有错!');
    while (intLoop1<=16) do
     begin
      strTemp:=Copy(strBin,intLoop1,4);
      for  intLoop2:=1 to 16 do
       if strTemp=strNum[intLoop2] then
        begin
          strTemp:=chrHex[intLoop2];
          break;
        end;
      strResult:=strResult+strTemp;
      intLoop1:=intLoop1 + 4;
     end;
    BinToHex:=strResult;
    end;
    ...{--------------------------------------------------------------------}function HexToTen(strHex:string):int64;         //十六进制转十进制
    var
    intLoop1,intLoop2,intTemp:integer;
    intResult:int64;
    strTemp:string;
    begin
    intResult:=0;
    intTemp:=0;
    if Length(strHex) <> 4 then ShowMessage('十六进制数据长度有错!');
    for intLoop1:=1 to 4 do
     begin
      Case intLoop1 of
       1:intTemp:=4096;
       2:intTemp:=256;
       3:intTemp:=16;
       4:intTemp:=1
      end;
      strTemp:=Copy(strHex,intLoop1,1);
      for intLoop2:=1 to 16 do
       if UpperCase(strTemp) = chrHex[intLoop2] then
        begin
         intResult:=intResult+(Int64(intLoop2) - 1)*Int64(intTemp);
         break;
        end;
     end;
    HexToTen:=intResult;
    end;
    ...{--------------------------------------------------------------------}function LeftMove(S:string;P:integer):String;
    var
    int_Len,i:integer;
    str_Result,str_Num:string;
    begin
    int_Len:=length(s);
    str_Num:=S;
    str_Result:='';
    if int_Len <= P then
      str_Result :=S
    else
    begin
      for i:=P+1 to int_Len do
        str_Result:=str_Result+copy(str_Num,i,1);
      str_Result:=str_Result+copy(str_Num,1,p);
    end;
    LeftMove:=Trim(str_Result);
    end;
    ...{--------------------------------------------------------------------}function ModAdd(intAdd1,intAdd2:int64):int64;
    begin
    ModAdd:=(intAdd1 + intAdd2) mod 65536;   //模65536求和
    end;function ModMul(intMul1,intMul2:int64;intFlag:integer):int64;
    var intTemp:int64;
    begin
    intTemp:=(intMul1 * intMul2) mod 65537; 
    if intFlag = 0 then
     begin
      if intMul1 = 0     then    intTemp:=65537 - intMul2;
      if intMul2 = 0     then    intTemp:=65537 - intMul1;
      if intTemp = 65536 then    intTemp:=0;
      if intTemp = 65537 then    intTemp:=1;
     end
    else
     begin
      if intMul1 = 0     then    intTemp:=65537 - intMul2;
      if intMul2 = 0     then    intTemp:=65537 - intMul1;
      if intTemp = 0     then    intTemp:=65536;
      if intTemp = 65537 then    intTemp:=1;
      if intTemp = 65536 then    intTemp:=0;                   
     end;
    ModMul:=intTemp;
    end;function ModXor(intXor1,intXor2:int64):int64;
    begin
    ModXor:= intXor1 xor intXor2;
    end;
    ...{--------------------------------------------------------------------}procedure CreatePassword(strPassword:string;VAR arrPassword:array of int64;VAR arrOpenPassword:array of int64);
    var
    strKey:string;
    strTemp:array[1..52] of string[4];
    intStart,intCount:integer;
    begin
    strKey:=strPassword;                                                                                                                   //
    intCount:=1;
    intStart:=1;
    ...{--------------------产生52个16bit的加密子密钥部分-------------------}
    while (intCount<=52) do
     begin
      strTemp[intCount]:=BinToHex(Copy(strKey,intStart,16));
      intStart:=intStart+16;
      intCount:=intCount+1;
      if ((intCount mod 8) = 1) then
       begin
        strKey:=LeftMove(strKey,25);
        intStart:=1;
       end;
     end;
    intCount:=1;
    while (intCount<=52) do
     begin
      arrPassword[intCount-1]:=HexToTen(strTemp[intCount]);
      g_arr_Ten_Password[intCount]:=arrPassword[intCount-1];
      intCount:=intCount+1;
     end;
    CreateOpenPassword(arrOpenPassword);                       
    ...{--------------------产生52个16bit的加密子密钥部分-------------------}
    end;
    ...{--------------------------------------------------------------------}procedure GetOpenPassword(intSource:int64;VAR intResult:int64;Flag:integer);
    var
    int_Source,int_Result,int_Mod_Value:int64;
    int_Loop:integer;
    begin
    int_Source:=intSource;
    ...{--------------------求取每个加密子密钥相应的解密子密钥部分-------------------}
    Case Flag of
      0:    intResult:=int_Source;
      1:    intResult:=65536-int_Source;
      2:
        begin
          if int_Source=0 then
             intResult:=int_Source
          else
            for int_Loop:=1 to 65536 do
             begin
              int_Result:=Int64(int_Loop)*65537+1;
              int_Mod_Value:=int_Result mod int_Source;
              if int_Mod_Value = 0 then
                begin
                  int_Result:=int_Result div int_Source;
                  intResult:=int_Result;
                  break;
                end;
             end;
        end;
    end;
    ...{--------------------求取每个加密子密钥相应的解密子密钥部分-------------------}
    end;
    ...{--------------------------------------------------------------------}
      

  2.   

    procedure CreateKeyTable();
    var
    int_Count_CreatePassword,int_Count_OpenPassword,int_ExChange:integer;
    begin
    ...{----------------求取在产生解密子密钥时所用的参数标志对应表部分-------------}
    for int_Count_CreatePassword:=52 downto 1 do
      Case int_Count_CreatePassword mod 6 of
        0,5:begin g_arr_Flag[int_Count_CreatePassword]:=0; end;
        2,3:begin g_arr_Flag[int_Count_CreatePassword]:=1; end;
        1,4:begin g_arr_Flag[int_Count_CreatePassword]:=2; end;
      end;
    ...{----------------求取在产生解密子密钥时所用的参数标志对应表部分-------------}...{----------------求取每个加密子密钥与相应解密子密钥间的对应关系映射表部分-------------}
    int_Count_CreatePassword:=52;
    int_Count_OpenPassword:=1;
    while (int_Count_CreatePassword>=1) do
    begin
      Case int_Count_CreatePassword mod 6 of
        1,2,3,4:
        begin
          g_arr_Table[int_Count_OpenPassword]:=int_Count_CreatePassword-3;
          g_arr_Table[int_Count_OpenPassword+1]:=int_Count_CreatePassword-1;
          g_arr_Table[int_Count_OpenPassword+2]:=int_Count_CreatePassword-2;
          g_arr_Table[int_Count_OpenPassword+3]:=int_Count_CreatePassword;
          if (int_Count_CreatePassword >=48) or (int_Count_CreatePassword <=4 ) then  //首轮和末轮处理不需交换,故要再换回来
            begin
              int_ExChange:=g_arr_Table[int_Count_OpenPassword+1];
              g_arr_Table[int_Count_OpenPassword+1]:=g_arr_Table[int_Count_OpenPassword+2];
              g_arr_Table[int_Count_OpenPassword+2]:=int_ExChange;
            end;
          int_Count_CreatePassword:=int_Count_CreatePassword-4;
          int_Count_OpenPassword:=int_Count_OpenPassword+4;
        end;
        0,5:
        begin
          g_arr_Table[int_Count_OpenPassword]:=int_Count_CreatePassword-1;
          g_arr_Table[int_Count_OpenPassword+1]:=int_Count_CreatePassword;
          int_Count_CreatePassword:=int_Count_CreatePassword-2;
          int_Count_OpenPassword:=int_Count_OpenPassword+2;
        end;
      end;
    end;
    ...{----------------求取每个加密子密钥与相应解密子密钥间的对应关系映射表部分-------------}
    end;
    ...{--------------------------------------------------------------------}
    procedure CreateOpenPassword(VAR arrOpenPassKey:array of int64);
    var
    int_Loop:integer;
    arrTemp:array[1..52] of int64;
    begin
    ...{-------------通过调用产生加、解密子密钥对应关系函数产生对应关系表部分------------------}
    CreateKeyTable;
    ...{-------------通过调用求解解密子密钥函数产生解密子密钥部分------------------}
    for int_Loop:=1 to 52 do
     begin
      GetOpenPassword(g_arr_Ten_Password[int_Loop],arrTemp[g_arr_Table[int_Loop]],g_arr_Flag[int_Loop]);
     end;
    for int_Loop:=1 to 52 do
      arrOpenPassKey[int_Loop-1]:=arrTemp[int_Loop];
    ...{-------------通过调用求解解密子密钥函数产生解密子密钥部分------------------}
    end;
    ...{--------------------------------------------------------------------}procedure Riddle(arrPassword:array of int64;arrRiddleKey:array of int64;VAR arrOpenPassword:array of int64);
    var
    Count,i:integer;
    V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,C1,C2,C3,C4,ExChange:int64;
    P:array[1..4] of int64;
    begin
    ...{------------------------数据 "解密" 算法实现部分------------------}
    for i:=Low(arrPassword) to High(arrPassword) do
     P[i+1]:=arrPassword[i];
    Count:=0;
    while (Count<48) do
    begin
      V1:= ModMul(P[1],arrRiddleKey[Count],1);  //相乘    1
      Inc(Count);
      V2:= ModAdd(P[2],arrRiddleKey[Count]);  //相加    2
      Inc(Count);
      V3:= ModAdd(P[3],arrRiddleKey[Count]);  //相加    3
      Inc(Count);
      V4:= ModMul(P[4],arrRiddleKey[Count],1);  //相乘    4
      Inc(Count);
      V5:= ModXor(V1,V3);                                           //异或    5
      V6:= ModXor(V2,V4);                                           //异或    6
      V7:= ModMul(V5,arrRiddleKey[Count],1);    //相乘    7
      Inc(Count);
      V8:= ModAdd(V6,V7);                        //相加    8
      V9:= ModMul(V8,arrRiddleKey[Count],1);    //相乘    9
      Inc(Count);
      V10:=ModAdd(V7,V9);                      //相加    10
      V11:=ModXor(V1,V9);                      //异或    11
      V12:=ModXor(V2,V10);                     //异或    12
      V13:=ModXor(V3,V9);                      //异或    13
      V14:=ModXor(V4,V10);                     //异或    14
      P[1]:=V11;
      P[2]:=V13;                                //注意:交换中间两个输出结果
      P[3]:=V12;                                //注意:交换中间两个输出结果
      P[4]:=V14;
    end;    //结束8轮计算
    ExChange:=P[2];
    P[2]:=P[3];
    P[3]:=ExChange;                            //因为最后一轮无需转换,所以必须把P[2],P[3]再次转换回来
    C1:= ModMul(P[1],arrRiddleKey[48],1);  //相乘    1
    C2:= ModAdd(P[2],arrRiddleKey[49]);  //相加    2
    C3:= ModAdd(P[3],arrRiddleKey[50]);  //相加    3
    C4:= ModMul(P[4],arrRiddleKey[51],1);  //相乘    4
    ...{------------------------数据 "解密" 算法实现部分------------------}
    arrOpenPassword[Low(arrOpenPassword)]:=C1;
    arrOpenPassword[Low(arrOpenPassword)+1]:=C2;
    arrOpenPassword[Low(arrOpenPassword)+2]:=C3;
    arrOpenPassword[Low(arrOpenPassword)+3]:=C4;
    //数据解密成功!
    end;
    ...{--------------------------------------------------------------------}end.
      

  3.   

    ///////////////////////////////加密文件/////////////////////////////////////////////////////////////////////////////
    /获得被加密文件名
    string MyInFileName=this.textBox1.Text;
    //获得加密输出文件名
    string MyOutFileName=this.textBox2.Text;
    //设定初始向量
    byte[]  MyDESIV={0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
    byte[]  MyDESKey={};
    //根据密码设置密钥大小
    string MyKeyString=this.textBox3.Text;   
    if (MyKeyString.Length==6)
    {
    MyDESKey=new byte[]{(byte)MyKeyString[0],(byte)MyKeyString[1],(byte)MyKeyString[2],
     (byte)MyKeyString[3],(byte)MyKeyString[4],(byte)MyKeyString[5],
     0x07,0x08};
    }
    if (MyKeyString.Length==7)
    {
    MyDESKey=new byte[]{(byte)MyKeyString[0],(byte)MyKeyString[1],(byte)MyKeyString[2],
     (byte)MyKeyString[3],(byte)MyKeyString[4],(byte)MyKeyString[5],
     (byte)MyKeyString[6],0x07};
    }
    if (MyKeyString.Length>=8)
    {
    MyDESKey=new byte[]{(byte)MyKeyString[0],(byte)MyKeyString[1],(byte)MyKeyString[2],
       (byte)MyKeyString[3],(byte)MyKeyString[4],(byte)MyKeyString[5],
       (byte)MyKeyString[6],(byte)MyKeyString[7]};
    }
    //创建输入和输出文件流
    FileStream MyInFileStream = new FileStream(MyInFileName, FileMode.Open, FileAccess.Read);
    FileStream MyOutFileStream = new FileStream(MyOutFileName, FileMode.OpenOrCreate, FileAccess.Write);
    MyOutFileStream.SetLength(0);     
    //每次的中间流.
    byte[] InsertData = new byte[100]; 
    //代表已经加密流的大小
    int CompletedLength=0;
    //代表要加密文件总的大小
    long InFileSize = MyInFileStream.Length; 
    //创建DES对象
    DES MyDES = new DESCryptoServiceProvider();     
    //创建加密流
    CryptoStream EncryptStream = new CryptoStream(MyOutFileStream, MyDES.CreateEncryptor(MyDESKey, MyDESIV), CryptoStreamMode.Write);             
    //从输入文件中读取流,然后加密到输出文件中
    while(CompletedLength < InFileSize)
    { //每次写入加密文件的数据大小
    int Length= MyInFileStream.Read(InsertData, 0, 100);
    EncryptStream.Write(InsertData, 0, Length);
    CompletedLength = CompletedLength + Length;
    }     
    //关闭流
    EncryptStream.Close();  
    MyOutFileStream.Close();
    MyInFileStream.Close();                   
    MessageBox.Show("文件加密已经操作成功!","信息提示",MessageBoxButtons.OK,MessageBoxIcon.Information); ///////////////////////////////////////解密文件//////////////////////////////////////////////////////////////////////////////
    //获得要解密的文件名
    string MyInFileName=this.textBox8.Text;
    //获得要保存的文件名
    string MyOutFileName=this.textBox7.Text;
    //设定初始向量
    byte[]  MyDESIV={0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
    byte[]  MyDESKey={};
    //根据密码算出密钥
    string MyKeyString=this.textBox6.Text;     
    if (MyKeyString.Length==6)
    {
    MyDESKey=new byte[]{(byte)MyKeyString[0],(byte)MyKeyString[1],(byte)MyKeyString[2],
     (byte)MyKeyString[3],(byte)MyKeyString[4],(byte)MyKeyString[5],
     0x07,0x08};
    }
    if (MyKeyString.Length==7)
    {
    MyDESKey=new byte[]{(byte)MyKeyString[0],(byte)MyKeyString[1],(byte)MyKeyString[2],
     (byte)MyKeyString[3],(byte)MyKeyString[4],(byte)MyKeyString[5],
     (byte)MyKeyString[6],0x07};
    }
    if (MyKeyString.Length>=8)
    {
    MyDESKey=new byte[]{(byte)MyKeyString[0],(byte)MyKeyString[1],(byte)MyKeyString[2],
     (byte)MyKeyString[3],(byte)MyKeyString[4],(byte)MyKeyString[5],
     (byte)MyKeyString[6],(byte)MyKeyString[7]};
    }
       //创建输入和输出文件流
    FileStream MyInFileStream = new FileStream(MyInFileName, FileMode.Open, FileAccess.Read);
    FileStream MyOutFileStream = new FileStream(MyOutFileName, FileMode.OpenOrCreate, FileAccess.Write);
    MyOutFileStream.SetLength(0);       
    //每次的中间流.
    byte[] InsertData = new byte[100]; 
    //代表已经解密的流的大小
    int MyCompletedSize=0;
    //代表要解密文件总的大小
    long MyFileSize = MyInFileStream.Length; 
    //创建DES对象
    DES MyDES= new DESCryptoServiceProvider();     
    //创建解密流
    CryptoStream DecryptStream = new  CryptoStream(MyOutFileStream, MyDES.CreateDecryptor(MyDESKey,MyDESIV), CryptoStreamMode.Write);
    //从输入文件中读取流,然后解密到输出文件中
    while(MyCompletedSize < MyFileSize)
    { //每次写入解密流的大小
    int length = MyInFileStream.Read(InsertData, 0, 100);
    DecryptStream.Write(InsertData, 0, length);
    MyCompletedSize=MyCompletedSize+length;

    //关闭流
    DecryptStream.Close();  
    MyOutFileStream.Close();
    MyInFileStream.Close();     
    MessageBox.Show("文件解密操作成功!","信息提示",MessageBoxButtons.OK,MessageBoxIcon.Information);