Das Problem hier ist aber, dass mein key am ende ein "00" Byte enthält, welches aber noch zum key gehört.
Ich will den Source umschreiben, dass er den Key im Hex format annimmt.
Also "6A68737375676900"
Allerdings finde ich nicht die stelle wo die Keylen ausgelesen wird.
Hoffe jemand kann mir helfen.
Hier der Source.
PHP Code:
#include <algorithm>
#include <stdio.h>
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
typedef unsigned char uchar;
typedef unsigned long ulong;
namespace linear_bit_setting {
// the following functions set, get or copies bits
// the represetion of the bits is: 0 1 2 3 4 5 6 7 8 9 .... x
uchar bitarr[8] = {128,64,32,16,8,4,2,1};
//
// This function sets a bit if the state is true(!=0) or clears it (==0)
//
inline void setbit(void* mem, unsigned bitnr, int state) {
if(state) ((uchar*)mem)[bitnr>>3] |= bitarr[bitnr&7];
else ((uchar*)mem)[bitnr>>3] &= ~bitarr[bitnr&7];
}
//
// returns a value != 0 if the bit is set, else 0
//
inline int getbit(void* mem, unsigned bitnr) {
return ((uchar*)mem)[bitnr>>3] & bitarr[bitnr&7];
}
inline void cpybit(void* dmem, unsigned dbitnr, void* smem, unsigned sbitnr) {
setbit(dmem, dbitnr, getbit(smem, sbitnr));
}
void cpybits(void* dmem, unsigned dbitnr, void* smem, unsigned sbitnr, int anz){
for(int i=0;i<anz;++i) cpybit(dmem, dbitnr+i, smem, sbitnr+i);
}
}
using namespace linear_bit_setting;
struct bit_struc { ulong bits[2]; };
//##############################################################################
/******************************************************************************/
/* Here come the tables for different permutations */
/******************************************************************************/
uchar initialP_table[64] = { // 64-64
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
};
uchar finalP_table[64] = { // 64-64
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
};
uchar keyP_table[56] = { // 64-56
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
};
uchar compressionP_table[48] = { // 56-48
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
};
uchar expansionP_table[48] = { // 32-48
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
};
uchar pbox_table[32] = { // 32-32
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
};
uchar sboxes_table[8][64] = { // 6-4 -> 48-32
14,0,4,15,13,7,1,4,2,14,15,2,11,13,8,1,3,10,10,6,6,12,12,11,5,9,9,5,0,3,7,8,
4,15,1,12,14,8,8,2,13,4,6,9,2,1,11,7,15,5,12,11,9,3,7,14,3,10,10,0,5,6,0,13,
15,3,1,13,8,4,14,7,6,15,11,2,3,8,4,14,9,12,7,0,2,1,13,10,12,6,0,9,5,11,10,5,
0,13,14,8,7,10,11,1,10,3,4,15,13,4,1,2,5,11,8,6,12,7,6,12,9,0,3,5,2,14,15,9,
10,13,0,7,9,0,14,9,6,3,3,4,15,6,5,10,1,2,13,8,12,5,7,14,11,12,4,11,2,15,8,1,
13,1,6,10,4,13,9,0,8,6,15,9,3,8,0,7,11,4,1,15,2,14,12,3,5,11,10,5,14,2,7,12,
7,13,13,8,14,11,3,5,0,6,6,15,9,0,10,3,1,4,2,7,8,2,5,12,11,1,12,10,4,14,15,9,
10,3,6,15,9,0,0,6,12,10,11,1,7,13,13,8,15,9,1,4,3,5,14,11,5,12,2,7,8,2,4,14,
2,14,12,11,4,2,1,12,7,4,10,7,11,13,6,1,8,5,5,0,3,15,15,10,13,3,0,9,14,8,9,6,
4,11,2,8,1,12,11,7,10,1,13,14,7,2,8,13,15,6,9,15,12,0,5,9,6,10,3,4,0,5,14,3,
12,10,1,15,10,4,15,2,9,7,2,12,6,9,8,5,0,6,13,1,3,13,4,14,14,0,7,11,5,3,11,8,
9,4,14,3,15,2,5,12,2,9,8,5,12,15,3,10,7,11,0,14,4,1,10,7,1,6,13,0,11,8,6,13,
4,13,11,0,2,11,14,7,15,4,0,9,8,1,13,10,3,14,12,3,9,5,7,12,5,2,10,15,6,8,1,6,
1,6,4,11,11,13,13,8,12,1,3,4,7,10,14,7,10,9,15,5,6,0,8,15,0,14,5,2,9,3,2,12,
13,1,2,15,8,13,4,8,6,10,15,3,11,7,1,4,10,12,9,5,3,6,14,11,5,0,0,14,12,9,7,2,
7,2,11,1,4,14,1,7,9,4,12,10,14,8,2,13,0,15,6,12,10,9,13,0,15,3,3,5,5,6,8,11
};
//uchar totrot_table[16] = { 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
uchar rotL_table[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
uchar rotR_table[16] = {0,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
void permutate(bit_struc& x, uchar* table, int size) {
bit_struc d=x;
for(int i=0;i<size;++i) cpybit(x.bits, i, d.bits, table[i]);
}
void permutate(ulong *in, ulong *out, uchar* table, int size) {
for(int i=0;i<size;++i) cpybit(out, i, in, table[i]);
}
/*
* This function rotates an index leftward, and returns the rotated index
* this is for the key-rotate function
*/
inline int iROTLx(int index, int shift, int size) {
index -= (shift%size); // bei 0,1,2 kann man das vergessen
return index>=0 ? index : index+size;
}
inline int iROTRx(int index, int shift, int size) {
index += (shift%size); // bei 0,1,2 kann man das vergessen
return index<size ? index : index-size;
}
enum des_mode { ENCRYPT, DECRYPT };
void shift_halfkeys(bit_struc& x, int round, des_mode mode) {
int n;
bit_struc d=x;
for(int i=0;i<28;++i) {
if(mode==ENCRYPT) n = iROTLx(i,rotL_table[round],28);
else n = iROTRx(i,rotR_table[round],28);
cpybit(x.bits,i, d.bits, n);
cpybit(x.bits,i+28, d.bits, n+28);
}
}
// 48 to 32 bit sbox substitution
void sbox_substitution(ulong *in, ulong *out) {
uchar index;
for(int s=0,i=0,o=0; s<8; ++s, i+=6, o+=4) {
index = 0; cpybits(&index,2, in,i, 6);
cpybits(out,o, &sboxes_table[s][index],4,4);
}
}
//
// the function shown in the diagram page 315
//
ulong f(ulong data32, ulong const* key48) {
ulong data48[2], d;
// Expansions-Permutation, expandiert 32-48
permutate(&data32,data48,expansionP_table,sizeof(expansionP_table));
// XOR-Verknüfung des Schlüssels mit Data
data48[0] ^= key48[0];
data48[1] ^= key48[1];
//S-Box Substitution
sbox_substitution(data48,&data32);
// P-Box Permutation
d=data32;
permutate(&d,&data32,pbox_table,sizeof(pbox_table));
return data32;
}
// transforms a given 64-bit key into a 56-bit key
inline void des_key_64_56(bit_struc& key) {
permutate(key,keyP_table,sizeof(keyP_table));
}
// The key had to be transformed to a 56bit key with the keyP_table-Permutation
void des_cryptBlock(bit_struc& datablock, bit_struc key56, des_mode mode) {
ulong key48[2], data48[2];
// Eingangs-Permutation
permutate(datablock, initialP_table, sizeof(initialP_table));
//---------------------------------------------------------------------------
for(int round=0;round<16;++round) {
// shifts the 2 28-bit halfs
shift_halfkeys(key56, round,mode);
// compresses the 56-bit key to an 48-bit key
permutate(key56.bits, key48, compressionP_table, sizeof(compressionP_table));
datablock.bits[0] ^= f(datablock.bits[1],key48);
if(round!=15) swap(datablock.bits[0],datablock.bits[1]);
}
//---------------------------------------------------------------------------
// Schluß-Permutation
permutate(datablock, finalP_table, sizeof(finalP_table));
}
int des_encryptFile(const char* filein, const char* fileout, bit_struc key) {
FILE *in, *out;
char buffer[8];
ulong flen,i;
bit_struc data, olddata;
des_key_64_56(key);
if( (in = fopen(filein,"rb")) == NULL) return -2;
if( (out= fopen(fileout,"wb")) == NULL) {fclose(in); return -3;}
// Filelänge ermitteln
fseek(in,0,SEEK_END);
flen = ftell(in);
fseek(in,0,SEEK_SET);
// IV bestimmen
rand(); // CBC
data.bits[0] = time(0); // CBC
data.bits[1] = rand(); // CBC
des_cryptBlock(data, key, ENCRYPT); // CBC
olddata=data; // CBC
fwrite(data.bits,8,1,out); // CBC
while(flen >= 8) {
fread(data.bits,8,1,in);
data.bits[0] ^= olddata.bits[0]; data.bits[1] ^= olddata.bits[1]; // CBC
des_cryptBlock(data,key,ENCRYPT);
fwrite(data.bits,8,1,out);
olddata=data;
flen -= 8;
}
fread(buffer,flen,1,in);
for(i=flen;i<=7;++i) buffer[i] = rand(); // ??? Random
data.bits[0] = ((ulong*) buffer)[0];
data.bits[1] = ((ulong*) buffer)[1];
data.bits[0] ^= olddata.bits[0]; data.bits[1] ^= olddata.bits[1]; // CBC
des_cryptBlock(data,key,ENCRYPT);
// ((ulong*) buffer)[0] = data.l;
// ((ulong*) buffer)[1] = data.r;
olddata=data;
fwrite(data.bits,8,1,out); //buffer
data.bits[0] = rand();
data.bits[1] = (rand()&0xFFFFFFF0)+flen;
data.bits[0] ^= olddata.bits[0]; data.bits[1] ^= olddata.bits[1]; // CBC
des_cryptBlock(data,key,ENCRYPT);
fwrite(data.bits,8,1,out);
fclose(in); fclose(out);
return 1;
}
int des_decryptFile(const char* filein, const char* fileout, bit_struc key) {
FILE *in, *out;
char buffer[8];
ulong flen,i;
bit_struc data,olddata,old2;
des_key_64_56(key);
if( (in = fopen(filein,"rb")) == NULL) return -2;
if( (out= fopen(fileout,"wb")) == NULL) {fclose(in); return -3;}
// Filelänge ermitteln
fseek(in,0,SEEK_END);
flen = ftell(in);
fseek(in,0,SEEK_SET);
flen >>= 3;
fread(olddata.bits,8,1,in); // IV (Initialisierungs Vektor)
for(i=0;i<flen-3;++i) { // -3 == CBC sonst -2
fread(data.bits,8,1,in);
old2=data; // CBC
des_cryptBlock(data,key,DECRYPT);
data.bits[0] ^= olddata.bits[0]; data.bits[1] ^= olddata.bits[1]; //CBC
olddata=old2; // CBC
fwrite(data.bits,8,1,out);
}
fread(data.bits,8,1,in);
old2=data; // CBC
des_cryptBlock(data,key,DECRYPT);
data.bits[0] ^= olddata.bits[0]; data.bits[1] ^= olddata.bits[1]; //CBC
olddata=old2; // CBC
((ulong*) buffer)[0] = data.bits[0];
((ulong*) buffer)[1] = data.bits[1];
fread(data.bits,8,1,in);
// old2=data; // CBC
des_cryptBlock(data,key,DECRYPT);
data.bits[0] ^= olddata.bits[0]; data.bits[1] ^= olddata.bits[1]; //CBC
// olddata=old2; // CBC
data.bits[1] &= 7;
fwrite(buffer,data.bits[1],1,out);
fclose(in); fclose(out);
return 1;
}
void main(int argc, char **argv) {
int err;
cout << "DES Copyright (c) 1998 by Michael Neumann" << endl;
if( argc != 5 ) {
cout << "USAGE: DES E/D key srcfile dstfile" << endl;
return;
}
bit_struc key;
{ // -start- key-calculating
char k[8], *x = argv[2];
int slen=strlen(x);
for(int i=0; i<max(slen,8); ++i) {
if(i<8) k[i] = x[i%slen];
else k[i%8] += x[i%slen];
}
memcpy(key.bits,k,8);
} // -end- key-calculating
if( argv[1][0] == 'e' || argv[1][0] == 'E' )
err=des_encryptFile(argv[3],argv[4],key);
else if( argv[1][0] == 'd' || argv[1][0] == 'D' )
err=des_decryptFile(argv[3],argv[4],key);
else { cout << "Error: E - for enrypt, D - for decrypt" << endl; return; }
if( err ) cout << "Sucessful done." << endl;
else cout << "Error occured with code: " << err << endl;
}