2014-02-12 74 views
0

嘗試從主密鑰生成DES子密鑰。到目前爲止,我有這個。不知道爲什麼會產生不正確的結果。我已經查看了所有內容,並且我非常肯定我有正確的想法,但這對於正確性來說是一件困難的事情。我從根本上誤解了一些東西,還是隻是馬虎編碼?從64b主密鑰生成DES子密鑰

def main(): 
master = input("Hexidecimal key (omit 0x): ") 

# Convert to binary 
scale = 16 
num_of_bits = 64 
master_bin = bin(int(master, scale))[2:].zfill(num_of_bits) 

PC1 = [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] 

PC2 = [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] 

# Do PC1 
key_after_PC1 = [] 
for bit in PC1: 
    key_after_PC1.append(master_bin[bit-1]) 

CL = [] 
CR = [] 

for j in range(28): 
    CL.append(key_after_PC1[j]) 
    CR.append(key_after_PC1[j+28]) 

# Do 16 Rounds 
for i in range(16): 

    # Do Shifts 
    if (i == 0 or i == 1 or i == 8 or i == 15): 
     CL.append(CL[0]) 
     CL.pop(0) 
     CR.append(CR[0]) 
     CR.pop(0) 
    else: 
     CL.append(CL[0]) 
     CL.append(CL[1]) 
     CL.pop(0) 
     CL.pop(0) 
     CR.append(CR[0]) 
     CR.append(CR[1]) 
     CR.pop(0) 
     CR.pop(0) 

    # Put Lists Back Together 
    SK = [] 
    for bit in CL: 
     SK.append(bit) 
    for bit in CR: 
     SK.append(bit) 

    # Do PC2 
    subkey_after_PC2 = [] 
    for bit in PC2: 
     subkey_after_PC2.append(SK[bit-1]) 


    # Print Subkey as String 
    subkey = "" 
    for bit in subkey_after_PC2: 
     subkey += bit 
    hex_subkey = hex(int(subkey, 2)) 
    print ("Subkey " + str(i+1) + ": " + hex_subkey)  

    if __name__ == '__main__': 
     main() 

回答

0

我不是蟒蛇編碼器,但是如果您填寫與輸入塊位索引值的整數數組,而不是使用一些二進制位值,你可以生成一些驗證。

keytab -b 

Table of Input Block selected key bits 


    Bit 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 
KS 
    1 10 51 34 60 49 17 33 57 2 9 19 42 3 35 26 25 44 58 59 1 36 27 18 41 
    2 2 43 26 52 41 9 25 49 59 1 11 34 60 27 18 17 36 50 51 58 57 19 10 33 
    3 51 27 10 36 25 58 9 33 43 50 60 18 44 11 2 1 49 34 35 42 41 3 59 17 
    4 35 11 59 49 9 42 58 17 27 34 44 2 57 60 51 50 33 18 19 26 25 52 43 1 
    5 19 60 43 33 58 26 42 1 11 18 57 51 41 44 35 34 17 2 3 10 9 36 27 50 
    6 3 44 27 17 42 10 26 50 60 2 41 35 25 57 19 18 1 51 52 59 58 49 11 34 
    7 52 57 11 1 26 59 10 34 44 51 25 19 9 41 3 2 50 35 36 43 42 33 60 18 
    8 36 41 60 50 10 43 59 18 57 35 9 3 58 25 52 51 34 19 49 27 26 17 44 2 
    9 57 33 52 42 2 35 51 10 49 27 1 60 50 17 44 43 26 11 41 19 18 9 36 59 
    10 41 17 36 26 51 19 35 59 33 11 50 44 34 1 57 27 10 60 25 3 2 58 49 43 
    11 25 1 49 10 35 3 19 43 17 60 34 57 18 50 41 11 59 44 9 52 51 42 33 27 
    12 9 50 33 59 19 52 3 27 1 44 18 41 2 34 25 60 43 57 58 36 35 26 17 11 
    13 58 34 17 43 3 36 52 11 50 57 2 25 51 18 9 44 27 41 42 49 19 10 1 60 
    14 42 18 1 27 52 49 36 60 34 41 51 9 35 2 58 57 11 25 26 33 3 59 50 44 
    15 26 2 50 11 36 33 49 44 18 25 35 58 19 51 42 41 60 9 10 17 52 43 34 57 
    16 18 59 42 3 57 25 41 36 10 17 27 50 11 43 34 33 52 1 2 9 44 35 26 49 

    Bit 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 
KS 
    1 22 28 39 54 37 4 47 30 5 53 23 29 61 21 38 63 15 20 45 14 13 62 55 31 
    2 14 20 31 46 29 63 39 22 28 45 15 21 53 13 30 55 7 12 37 6 5 54 47 23 
    3 61 4 15 30 13 47 23 6 12 29 62 5 37 28 14 39 54 63 21 53 20 38 31 7 
    4 45 55 62 14 28 31 7 53 63 13 46 20 21 12 61 23 38 47 5 37 4 22 15 54 
    5 29 39 46 61 12 15 54 37 47 28 30 4 5 63 45 7 22 31 20 21 55 6 62 38 
    6 13 23 30 45 63 62 38 21 31 12 14 55 20 47 29 54 6 15 4 5 39 53 46 22 
    7 28 7 14 29 47 46 22 5 15 63 61 39 4 31 13 38 53 62 55 20 23 37 30 6 
    8 12 54 61 13 31 30 6 20 62 47 45 23 55 15 28 22 37 46 39 4 7 21 14 53 
    9 4 46 53 5 23 22 61 12 54 39 37 15 47 7 20 14 29 38 31 63 62 13 6 45 
    10 55 30 37 20 7 6 45 63 38 23 21 62 31 54 4 61 13 22 15 47 46 28 53 29 
    11 39 14 21 4 54 53 29 47 22 7 5 46 15 38 55 45 28 6 62 31 30 12 37 13 
    12 23 61 5 55 38 37 13 31 6 54 20 30 62 22 39 29 12 53 46 15 14 63 21 28 
    13 7 45 20 39 22 21 28 15 53 38 4 14 46 6 23 13 63 37 30 62 61 47 5 12 
    14 54 29 4 23 6 5 12 62 37 22 55 61 30 53 7 28 47 21 14 46 45 31 20 63 
    15 38 13 55 7 53 20 63 46 21 6 39 45 14 37 54 12 31 5 61 30 29 15 4 47 
    16 30 5 47 62 45 12 55 38 13 61 31 37 6 29 46 4 23 28 53 22 21 7 63 39 

這實際上顯示了C寄存器作爲輸入塊位,後面跟着16個選定鍵(PC2)的輸入塊位的D寄存器。本表來自Meyers/Metyas的書加密法由我在90年代編寫的C程序生成,驗證了本書中的各種表格。

還有另一個由-s選項生成的表格,它將選定的鍵顯示爲C和D寄存器位的函數。

keytab -s 

Table of CD Reg selected key bits 


    Bit 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 
KS 
    1 15 18 12 25 2 6 4 1 16 7 22 11 24 20 13 5 27 9 17 8 28 21 14 3 
    2 16 19 13 26 3 7 5 2 17 8 23 12 25 21 14 6 28 10 18 9 1 22 15 4 
    3 18 21 15 28 5 9 7 4 19 10 25 14 27 23 16 8 2 12 20 11 3 24 17 6 
    4 20 23 17 2 7 11 9 6 21 12 27 16 1 25 18 10 4 14 22 13 5 26 19 8 
    5 22 25 19 4 9 13 11 8 23 14 1 18 3 27 20 12 6 16 24 15 7 28 21 10 
    6 24 27 21 6 11 15 13 10 25 16 3 20 5 1 22 14 8 18 26 17 9 2 23 12 
    7 26 1 23 8 13 17 15 12 27 18 5 22 7 3 24 16 10 20 28 19 11 4 25 14 
    8 28 3 25 10 15 19 17 14 1 20 7 24 9 5 26 18 12 22 2 21 13 6 27 16 
    9 1 4 26 11 16 20 18 15 2 21 8 25 10 6 27 19 13 23 3 22 14 7 28 17 
    10 3 6 28 13 18 22 20 17 4 23 10 27 12 8 1 21 15 25 5 24 16 9 2 19 
    11 5 8 2 15 20 24 22 19 6 25 12 1 14 10 3 23 17 27 7 26 18 11 4 21 
    12 7 10 4 17 22 26 24 21 8 27 14 3 16 12 5 25 19 1 9 28 20 13 6 23 
    13 9 12 6 19 24 28 26 23 10 1 16 5 18 14 7 27 21 3 11 2 22 15 8 25 
    14 11 14 8 21 26 2 28 25 12 3 18 7 20 16 9 1 23 5 13 4 24 17 10 27 
    15 13 16 10 23 28 4 2 27 14 5 20 9 22 18 11 3 25 7 15 6 26 19 12 1 
    16 14 17 11 24 1 5 3 28 15 6 21 10 23 19 12 4 26 8 16 7 27 20 13 2 

    Bit 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 
KS 
    1 42 53 32 38 48 56 31 41 52 46 34 49 45 50 40 29 35 54 47 43 51 37 30 33 
    2 43 54 33 39 49 29 32 42 53 47 35 50 46 51 41 30 36 55 48 44 52 38 31 34 
    3 45 56 35 41 51 31 34 44 55 49 37 52 48 53 43 32 38 29 50 46 54 40 33 36 
    4 47 30 37 43 53 33 36 46 29 51 39 54 50 55 45 34 40 31 52 48 56 42 35 38 
    5 49 32 39 45 55 35 38 48 31 53 41 56 52 29 47 36 42 33 54 50 30 44 37 40 
    6 51 34 41 47 29 37 40 50 33 55 43 30 54 31 49 38 44 35 56 52 32 46 39 42 
    7 53 36 43 49 31 39 42 52 35 29 45 32 56 33 51 40 46 37 30 54 34 48 41 44 
    8 55 38 45 51 33 41 44 54 37 31 47 34 30 35 53 42 48 39 32 56 36 50 43 46 
    9 56 39 46 52 34 42 45 55 38 32 48 35 31 36 54 43 49 40 33 29 37 51 44 47 
    10 30 41 48 54 36 44 47 29 40 34 50 37 33 38 56 45 51 42 35 31 39 53 46 49 
    11 32 43 50 56 38 46 49 31 42 36 52 39 35 40 30 47 53 44 37 33 41 55 48 51 
    12 34 45 52 30 40 48 51 33 44 38 54 41 37 42 32 49 55 46 39 35 43 29 50 53 
    13 36 47 54 32 42 50 53 35 46 40 56 43 39 44 34 51 29 48 41 37 45 31 52 55 
    14 38 49 56 34 44 52 55 37 48 42 30 45 41 46 36 53 31 50 43 39 47 33 54 29 
    15 40 51 30 36 46 54 29 39 50 44 32 47 43 48 38 55 33 52 45 41 49 35 56 31 
    16 41 52 31 37 47 55 30 40 51 45 33 48 44 49 39 56 34 53 46 42 50 36 29 32 

你可能會注意到KS16恰好反映了PC2。它告訴我們何時將C和D轉換爲解密以反轉所選擇的鍵順序轉換,而在加密期間(並且如您所示),在使用圓鍵之前應用左移。如果您選擇了圓鍵,則傾向於使用編碼方法,並向後選擇它們以進行解密。

區別keytab程序和你的區別似乎只在於PC1和PC2排列分別用於C和D寄存器。

keytab.c:(應該是相當高便攜性)

#include <stdlib.h> 
#include <stdio.h> 

/* PC1 maps input bytes to C and D registers */ 

static int PC1_C[] = {  
       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 
}; 

static int PC1_D[] = {  
       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 
}; 

/* key shift schedule */ 

static int shifts[] = { 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1 }; 


/* PC2 selects CD bits to generate selected key */ 

static int PC2_C[] = { 
    14,17,11,24, 1, 5, 
    3,28,15, 6,21,10, 
    23,19,12, 4,26, 8, 
    16, 7,27,20,13, 2 
}; 

static int PC2_D[] = { 
    41,52,31,37,47,55, 
    30,40,51,45,33,48, 
    44,49,39,56,34,53, 
    46,42,50,36,29,32 
}; 

/* The C and D arrays used to calculate the key schedule */ 

static int C[28]; 
static int D[28]; 

static int input[16][64]; /* Input key bits used in each KS */ 
static int corre[16][16]; /* correlation between keys */ 
static int c[28]; 
static int d[28]; 
static int cd_bits[16][48]; 

/* The scheduled keys, indexed by round */ 

static int KS[16][48]; 

/* Fill the key schedule */ 

void key_sched() { 

register int index, round, shift_sched; 
int temp; 
int  tempcd; 

/* Load C and D with input block bit values */ 

    for(index = 0; index < 28; index++) { 
    C[index] = PC1_C[index]; 
    c[index] = index+1; 
    D[index] = PC1_D[index]; 
    d[index] = index+28+1; 
    } 

/* Rotate C and D according to key schedule apply PC2 */ 

    for(round = 0; round < 16; round++) { 

    /* first rotate */ 

    for(shift_sched=0;shift_sched < shifts[round];shift_sched++) { 
     temp = C[0]; 
     tempcd = c[0]; 
     for(index = 0; index < 28-1; index++) { 
     C[index] = C[index+1]; 
     c[index] = c[index+1]; 
     } 
     C[27] = temp; 
     c[27] = tempcd; 
     temp = D[0]; 
     tempcd = d[0]; 
     for(index = 0; index < 28-1; index++) { 
     D[index] = D[index+1]; 
     d[index] = d[index+1]; 
     } 
     D[27] = temp; 
     d[27] = tempcd; 
    } 

    /* Apply PC2 and store in selected key */ 

    for(index = 0; index < 24; index++) { 
     KS[round][index] = C[PC2_C[index]-1]; 
     cd_bits[round][index] = c[PC2_C[index]-1];; 
     KS[round][index+24] = D[PC2_D[index]-28-1]; 
     cd_bits[round][index+24] = d[PC2_D[index]-28-1]; 
    } 
    } 
} 

void key_input() { 
int index; 
int round; 

    for (round = 0; round < 16; round++) 
     for (index = 0; index < 48; index++) { 
      input[round][KS[round][index]] = 1; /* mark those used */ 
     } 
} 

void key_core() { 
int key1,key2; 
int keybit; 
    for (key1 = 0; key1 < 16; key1++) 
     for (key2 = 0; key2 < 16; key2++) { 
      corre[key1][key2] = 0; 
     for (keybit = 0; keybit < 64; keybit++) 
      if (input[key1][keybit] & input[key2][keybit]) 
       corre[key1][key2]+= 1; 
     } 
    printf("\n\nKS "); 
    for (key1 = 0; key1 < 16; key1++) 
     printf("%2d ",key1+1); 
    printf("\n\n"); 

    for (key1 = 0; key1 < 16; key1++) { 
     printf("%2d ",key1+1); 
     for (key2 = 0; key2 < 16; key2++) { 
      if (corre[key1][key2] == 48) 
       printf(" "); 
      else 
       printf("%2d ",corre[key1][key2]); 
     } 
     printf("\n"); 
    } 
    printf("\n"); 
} 

#define MAX_STR 2048 
int main (argc,argv) 
int argc; 
char *argv[]; 
{ 
int round; 
int keybit; 
extern int getopt(); 
extern char *optarg; 
extern int optind, opterr; 
char *ofile; 
int input_block = 0; 
int input_bit = 0; 
int input_corre = 0; 
int cd_bit = 0; 
int i; 

    while ((i=getopt(argc,argv,"cibso:")) != -1) { 
     switch (i) { 
     case 'c': 
      input_corre = 1; 
    break; 
     case 'i': 
      input_bit = 1; 
    break; 
     case 'b': 
      input_block = 1; 
    break; 
    case 's': 
     cd_bit = 1; 
    break; 
     case 'o': 
      ofile = optarg; 
      if(freopen(optarg,"w",stdout) == NULL) { 
       fprintf(stderr,"ERROR:%s, can't open %s for output\n", 
         argv[0],optarg); 
       exit(-1); 
      } 
     break; 
     case '?': 
      fprintf(stderr,"usage: %s [-i][-c][-b][-o outfile] \n",argv[0]); 
      fprintf(stderr,"\t-i shows which input block bits are used in each round\n"); 
      fprintf(stderr,"\t-c shows number of key bits in common between rounds\n"); 
      fprintf(stderr,"\t-b outputs key tables shown as input block bits\n"); 
      fprintf(stderr,"\t-s outputs key tables shown as CD reg bits\n"); 
      exit (-1); 
     break; 
     } 
    } 

    key_sched(); 

    if (cd_bit) { 
     printf("\nTable of CD Reg selected key bits\n\n"); 
     printf("\n Bit "); 
     for (keybit = 0; keybit < 24 ; keybit++) 
      printf("%2d ",keybit+1); 

     printf("\nKS\n"); 

     for (round = 0; round < 16; round++) { 
      printf(" %2d ",round+1); 
      for (keybit = 0; keybit < 24; keybit++) 
       printf("%2d ",cd_bits[round][keybit]); 
     printf("\n"); 
     } 

     printf("\n Bit "); 
     for (keybit = 24; keybit < 48 ; keybit++) 
      printf("%2d ",keybit+1); 

     printf("\nKS\n"); 

     for (round = 0; round < 16; round++) { 
      printf(" %2d ",round+1); 
      for (keybit = 24; keybit < 48; keybit++) 
       printf("%2d ",cd_bits[round][keybit]); 
      printf("\n"); 
     } 
     printf("\n%c",'\014'); 
    } 


    if (input_block) { 
     printf("\nTable of Input Block selected key bits\n\n"); 
     printf("\n Bit "); 
     for (keybit = 0; keybit < 24 ; keybit++) 
      printf("%2d ",keybit+1); 

     printf("\nKS\n"); 

     for (round = 0; round < 16; round++) { 
      printf(" %2d ",round+1); 
      for (keybit = 0; keybit < 24; keybit++) 
       printf("%2d ",KS[round][keybit]); 
     printf("\n"); 
     } 

     printf("\n Bit "); 
     for (keybit = 24; keybit < 48 ; keybit++) 
      printf("%2d ",keybit+1); 

     printf("\nKS\n"); 

     for (round = 0; round < 16; round++) { 
      printf(" %2d ",round+1); 
      for (keybit = 24; keybit < 48; keybit++) 
       printf("%2d ",KS[round][keybit]); 
      printf("\n"); 
     } 
     printf("\n%c",'\014'); 
    } 

    key_input(); 

    if (input_bit) { 
     printf("\n Bit "); 
     for (keybit = 0; keybit < 24 ; keybit++) 
      printf("%2d ",keybit+1); 

     printf("\nKey\n"); 

     for (round = 0; round < 16; round++) { 
      printf(" %2d ",round+1); 
      for (keybit = 0; keybit < 24; keybit++) 
       printf(" %c ",(input[round][keybit])?'X':'.'); 
     printf("\n"); 
     } 

     printf("\n Bit "); 
     for (keybit = 24; keybit < 48 ; keybit++) 
      printf("%2d ",keybit+1); 

     printf("\nKey\n"); 

     for (round = 0; round < 16; round++) { 
      printf(" %2d ",round+1); 
      for (keybit = 24; keybit < 48; keybit++) 
       printf(" %c ",(input[round][keybit])?'X':'.'); 
      printf("\n"); 
     } 
     printf("\n"); 
     printf("\n Bit "); 
     for (keybit = 48; keybit < 64 ; keybit++) 
      printf("%2d ",keybit+1); 

     printf("\nKey\n"); 

     for (round = 0; round < 16; round++) { 
      printf(" %2d ",round+1); 
      for (keybit = 48; keybit < 64; keybit++) 
       printf(" %c ",(input[round][keybit])?'X':'.'); 
     printf("\n"); 
     } 
    }  
    if (input_corre) 
     key_core(); 
    exit (0); 
} 

還有一個javascript DES實現浮動周圍已被停用,以防止它在教育環境中使用任意鍵。捕獲頁面,你可以實際撤銷禁用,允許它使用任意鍵。請參閱http://people.eku.edu/styere/Encrypt/JS-DES.html。這裏的價值是展示每一輪的內部價值。

[JS-DES.html與可寫密鑰的副本可在http://dpades.googlecode.com/svn/trunk/simu_js/JS-DES.html可以發現,項目主頁(http://code.google.com/p/dpades/)說,這是在GPLv2]

+0

太謝謝你了。您發佈的網站使我能夠檢查現有的代碼。事實證明這是對的! – AFoolInTheRain

+0

它看起來沒有理解關於python'pop'和'append'這個看起來一致的位。 DES中任何實現中最難的部分是瞭解你的錯誤。我曾經使用原始BSD libcrypt DES的源代碼副本輸出相同的東西。 – user1155120