gpt4 book ai didi

python - 使用弱 key 暴力破解 DES

转载 作者:太空狗 更新时间:2023-10-29 18:25:53 25 4
gpt4 key购买 nike

我正在学习密码学类(class),但被作业困住了。说明如下:

The plaintext plain6.txt has been encrypted with DES to encrypt6.dat using a 64-bit key given as a string of 8 characters (64 bits of which every 8th bit is ignored), all characters being letters (lower-case or upper-case) and digits (0 to 9).

To complete the assignment, send me the encryption key before February 12, 23.59.

Note: I expect to get an 8-byte (64-bits) key. Each byte should coincide with the corresponding byte in my key, except for the least significant bit which is not used in DES and thus, could be arbitrary.

这是我第一次尝试使用 Python 的代码:

import time
from Crypto.Cipher import DES

class BreakDES(object):
def __init__(self, file, passwordLength = 8, testLength = 8):
self.file = file
self.passwordLength = passwordLength
self.testLength = testLength
self.EncryptedFile = open(file + '.des')
self.DecryptedFile = open(file + '.txt')
self.encryptedChunk = self.EncryptedFile.read(self.testLength)
self.decryptedChunk = self.DecryptedFile.read(self.testLength)
self.start = time.time()
self.counter = 0
self.chars = range(48, 58) + range(65, 91) + range(97, 123)
self.key = False
self.broken = False

self.testPasswords(passwordLength, 0, '')

if not self.broken:
print "Password not found."

duration = time.time() - self.start

print "Brute force took %.2f" % duration
print "Tested %.2f per second" % (self.counter / duration)

def decrypt(self):
des = DES.new(self.key.decode('hex'))
if des.decrypt(self.encryptedChunk) == self.decryptedChunk:
self.broken = True
print "Password found: 0x%s" % self.key
self.counter += 1

def testPasswords(self, width, position, baseString):
for char in self.chars:
if(not self.broken):
if position < width:
self.testPasswords(width, position + 1, baseString + "%c" % char)
self.key = (baseString + "%c" % char).encode('hex').zfill(16)
self.decrypt()

# run it for password length 4
BreakDES("test3", 4)

我的速度为每秒 60.000 次尝试。一个超过 62 个字符的 8 个字节的密码给出了 13 万亿种可能性,这意味着以这种速度,我需要 130 年才能解决。我知道这不是一个有效的实现,而且我可以使用更快的语言(如 C 或它的风格)获得更快的速度,但我从来没有用这些语言编程过。即使我得到 10 倍的加速,我们仍然距离每秒 10,000,000,000 次有很大的飞跃以进入小时范围。

我错过了什么?这应该是一个弱键 :)。嗯,比完整的 256 个字符集弱。

编辑

由于关于分配的一些歧义,这里是完整的描述和一些用于校准的测试文件:http://users.abo.fi/ipetre/crypto/assignment6.html

编辑 2

这是一个粗略的 C 实现,在 i7 2600K 上每个内核每秒可获得大约 2.000.000 个密码。您必须指定密码的第一个字符,并且可以在不同的核心/计算机上手动运行多个实例。我设法在四台计算机上使用它在几个小时内解决了问题。

#include <stdio.h>      /* fprintf */
#include <stdlib.h> /* malloc, free, exit */
#include <unistd.h>
#include <string.h> /* strerror */
#include <signal.h>
#include <openssl/des.h>

static long long unsigned nrkeys = 0; // performance counter

char *
Encrypt( char *Key, char *Msg, int size)
{
static char* Res;
free(Res);
int n=0;
DES_cblock Key2;
DES_key_schedule schedule;
Res = ( char * ) malloc( size );
/* Prepare the key for use with DES_ecb_encrypt */
memcpy( Key2, Key,8);
DES_set_odd_parity( &Key2 );
DES_set_key_checked( &Key2, &schedule );
/* Encryption occurs here */
DES_ecb_encrypt( ( unsigned char (*) [8] ) Msg, ( unsigned char (*) [8] ) Res,
&schedule, DES_ENCRYPT );
return (Res);
}

char *
Decrypt( char *Key, char *Msg, int size)
{
static char* Res;
free(Res);
int n=0;
DES_cblock Key2;
DES_key_schedule schedule;
Res = ( char * ) malloc( size );
/* Prepare the key for use with DES_ecb_encrypt */
memcpy( Key2, Key,8);
DES_set_odd_parity( &Key2 );
DES_set_key_checked( &Key2, &schedule );
/* Decryption occurs here */
DES_ecb_encrypt( ( unsigned char (*) [8]) Msg, ( unsigned char (*) [8]) Res,
&schedule, DES_DECRYPT );
return (Res);
}

void ex_program(int sig);

int main(int argc, char *argv[])
{
(void) signal(SIGINT, ex_program);

if ( argc != 4 ) /* argc should be 2 for correct execution */
{
printf( "Usage: %s ciphertext plaintext keyspace \n", argv[0] );
exit(1);
}

FILE *f, *g;
int counter, i, prime = 0, len = 8;
char cbuff[8], mbuff[8];
char letters[] = "02468ACEGIKMOQSUWYacegikmoqsuwy";
int nbletters = sizeof(letters)-1;
int entry[len];
char *password, *decrypted, *plain;

if(atoi(argv[3]) > nbletters-2) {
printf("The range must be between 0-%d\n", nbletters-2);
exit(1);
}
prime = atoi(argv[1])

// read first 8 bytes of the encrypted file
f = fopen(argv[1], "rb");
if(!f) {
printf("Unable to open the file\n");
return 1;
}
for (counter = 0; counter < 8; counter ++) cbuff[counter] = fgetc(f);
fclose(f);

// read first 8 bytes of the plaintext file
g = fopen(argv[2], "r");
if(!f) {
printf("Unable to open the file\n");
return 1;
}
for (counter = 0; counter < 8; counter ++) mbuff[counter] = fgetc(g);
fclose(g);

plain = malloc(8);
memcpy(plain, mbuff, 8);

// fill the keys
for(i=0 ; i<len ; i++) entry[i] = 0;
entry[len-1] = prime;

// loop until the length is reached
do {
password = malloc(8);
decrypted = malloc(8);

// build the pasword
for(i=0 ; i<len ; i++) password[i] = letters[entry[i]];
nrkeys++;

// end of range and notices
if(nrkeys % 10000000 == 0) {
printf("Current key: %s\n", password);
printf("End of range ");
for(i=0; i<len; i++) putchar(letters[lastKey[i]]);
putchar('\n');
}

// decrypt
memcpy(decrypted,Decrypt(password,cbuff,8), 8);

// compare the decrypted with the mbuff
// if they are equal, exit the loop, we have the password
if (strcmp(mbuff, decrypted) == 0)
{
printf("We've got it! The key is: %s\n", password);
printf("%lld keys searched\n", nrkeys);
exit(0);
}

free(password);
free(decrypted);

// spin up key until it overflows
for(i=0 ; i<len && ++entry[i] == nbletters; i++) entry[i] = 0;
} while(i<len);

return 0;
}

void ex_program(int sig) {
printf("\n\nProgram terminated %lld keys searched.\n", nrkeys);
(void) signal(SIGINT, SIG_DFL);
exit(0);
}

最佳答案

我假设所需的解决方案是实际实现算法。然后,由于您要自己解密,您可以提前退出,假设明文也是 A-Za-z0-9,那么您有 98% 的机会在解密单个字节后停止,即 99.97%解密 2 个字节后停止的机会,以及 99.9995% 的机会在解密 3 个字节后停止。

此外,使用 C 或 Ocaml 或类似的东西。与加密相比,您花在字符串操作上的时间可能要多得多。或者,至少使用多处理并启动所有内核...

关于python - 使用弱 key 暴力破解 DES,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9119046/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com