从64b主密钥生成DES子密钥

时间:2014-02-12 02:48:38

标签: python encryption des

尝试从主密钥生成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()

1 个答案:

答案 0 :(得分:0)

我不是python编码器,但是如果使用输入块位索引值填充整数数组而不是使用某些二进制位值,则可以生成可验证的内容。

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寄存器显示为输入块位,然后是D寄存器,用于16个所选键的输入块位(通过PC2)。这张表来自我在90年代写的一个C程序生成的Meyers / Metyas书籍 Cryptography ,验证了书中的各种表格。

-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

你可以注意到KS 16恰好反映了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。这里的值是显示每轮的内部值。

[可以在http://dpades.googlecode.com/svn/trunk/simu_js/JS-DES.html找到带有可写密钥的JS-DES.html副本,项目主页(http://code.google.com/p/dpades/)表示它是GPLv2。]