Tôi đang tham gia một khóa học về Mật mã học và bị kẹt trong một bài tập. Các hướng dẫn như sau:Brute buộc DES với khóa yếu
các plain6.txt bản rõ đã được mã hóa với DES để encrypt6.dat sử dụng một chìa khóa 64-bit được coi là một chuỗi 8 ký tự (64 bit trong đó mỗi bit thứ 8 được bỏ qua), tất cả các ký tự là chữ cái (chữ thường hoặc chữ thường) và chữ số (0 đến 9).
Để hoàn thành bài tập, hãy gửi cho tôi khóa mã hóa trước ngày 12, 23.59.
Lưu ý: Tôi hy vọng sẽ nhận được khóa 8 bit (64 bit). Mỗi byte cần trùng với byte tương ứng trong khóa của tôi, ngoại trừ ít nhất bit quan trọng không được sử dụng trong DES và do đó, có thể tùy ý.
Đây là đoạn mã để nỗ lực đầu tiên của tôi bằng 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)
Tôi nhận được một tốc độ 60.000 cố gắng/giây. Mật khẩu 8 byte trên 62 ký tự cho 13 nghìn tỷ khả năng, có nghĩa là ở tốc độ này, tôi sẽ mất 130 năm để giải quyết. Tôi biết rằng đây không phải là một việc thực hiện hiệu quả và tôi có thể có được tốc độ tốt hơn trong một ngôn ngữ nhanh hơn như C hoặc hương vị của nó, nhưng tôi chưa bao giờ được lập trình trong đó. Ngay cả khi tôi tăng tốc độ 10, chúng tôi vẫn là một bước nhảy vọt lớn từ 10.000.000.000 mỗi giây để có được trong phạm vi giờ.
Tôi đang thiếu gì? Điều này được coi là một khóa yếu :). Vâng, yếu hơn bộ 256 ký tự đầy đủ.
EDIT
Do một số mơ hồ về nhiệm vụ, đây là mô tả đầy đủ và một số tác phẩm thử nghiệm cho hiệu chuẩn: http://users.abo.fi/ipetre/crypto/assignment6.html
EDIT 2
Đây là một thực hiện thô C có khoảng 2.000.000 mật khẩu/s trên mỗi lõi trên i7 2600K. Bạn phải chỉ định ký tự đầu tiên của mật khẩu và có thể chạy thủ công nhiều phiên bản trên các lõi/máy tính khác nhau. Tôi đã giải quyết vấn đề bằng cách sử dụng điều này trong vòng một vài giờ trên bốn máy tính.
#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);
}
Có thể đọc về cấu trúc của DES. Có những khai thác dựa trên cách thông tin truyền bá thông qua các đường chuyền. – Marcin
Bravo vì không đợi đến đêm hôm trước. – roken
Nếu bạn có tiền nằm xung quanh, và bạn thực sự muốn bạo lực này, hãy xem xét rằng bạn có thể tạo 10^16 amazon ec2 công việc, mỗi trong số đó chỉ mã hóa bản rõ đã cho với khóa được cấp phát của nó. – Marcin