使用弱密钥暴力破解 DES

2024-01-24

我正在学习密码学课程,但正在做一项作业。说明如下:

明文 plain6.txt 已使用 DES 加密为 encrypt6.dat,使用 64 位密钥作为 8 个字符的字符串给出 (64 位,其中每第 8 位被忽略),所有字符均为字母 (小写或大写)和数字(0 到 9)。

要完成作业,请在二月之前将加密密钥发送给我 12、23.59。

注意:我希望获得 8 字节(64 位)密钥。每个字节应该 与我的密钥中的相应字节一致,除了最少的 DES 中未使用的重要位,因此可以是任意的。

这是我第一次尝试使用 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 次尝试/秒。 8 个字节超过 62 个字符的密码提供了 13 万亿种可能性,这意味着按照这个速度,我需要 130 年才能解开。我知道这不是一个有效的实现,并且我可以使用更快的语言(例如 C 或其风格)获得更好的速度,但我从未用这些语言进行过编程。即使我获得 10 的加速,我们仍然距离每秒 10,000,000,000 小时范围有一个巨大的飞跃。

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

EDIT

由于作业存在一些含糊之处,这里是完整的描述和一些用于校准的测试文件:http://users.abo.fi/ipetre/crypto/assignment6.html http://users.abo.fi/ipetre/crypto/assignment6.html

EDIT 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 个字节后停止的几率为 99.9995%。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用弱密钥暴力破解 DES 的相关文章

随机推荐

  • 使用 Oracle 客户端和 Kerberos 与 Python 连接到数据库

    我有一个 python 脚本 它基本上使用x Oracleoracle 客户端连接到我的数据库服务器 连接后我可以运行 SQL 查询 现在 由于我的数据库凭据已过期 我被迫使用我不知道的 kerberos 身份验证 以前只需执行以下代码即可
  • Redis:可能使数组或排序集中的元素过期吗?

    目前是否只能使整个键 值对过期 如果我想将值添加到列表类型结构并让它们在插入后 1 小时自动删除 该怎么办 目前是否可行 或者是否需要运行 cron 作业来手动进行清除 有一个通用模式可以很好地解决这个问题 使用排序集 并使用时间戳作为分数
  • 取消透视从另一个表中获取的列

    我有超过 500 个列需要在取消透视时使用 select col1 col2 col3 from select from table unpivot col3 for col2 in value value2 value788 因此 我没有
  • Conv1D 层 Keras 的 input_shape

    我正在尝试制作一个用于非图像数据集二元分类的 CNN 模型 我的模型 代码正在运行并产生非常好的结果 准确性很高 但我无法理解input shape第一层参数Conv1D X 或输入的形状 此处x train df 为 2000 28 它有
  • 如何为 Nexus5 和 Nexus 5x 设置正确的边距

    我正在开发该应用程序 现在遇到了很大的问题 据我们所知 nexus 5 和 nexus 5x 使用相同的资源目录 xxhdpi 我的观点由于一些空白而被打破 即我必须为 nexus 5 设置 40dp 为 nexus5x 设置 65dp 那
  • 如何在 Eclipse PDE 中表达项目间依赖关系

    我正在寻找处理混合项目类型之间项目间依赖关系的最佳实践 其中一些项目是 eclipse 插件 OSGI 捆绑项目 RCP 应用程序 而其他项目只是普通的旧 java 项目 Web 服务模块 很少有 Eclipse 插件依赖于 Java 项目
  • Bootstrap 中占位符颜色变化

    如何更改 Bootstrap 中的占位符颜色 我尝试过以下代码 但不起作用 input webkit input placeholder color red input moz placeholder color red form cont
  • 异步 HttpHandler 和 WriteAsync

    我一直在 Ayende Rahien 的博客上尝试一些代码here http ayende com blog 72705 node cs它演示了使用异步 HttpHandler 来提高可以并发处理的请求数量 不幸的是我什至可以让基本的例子工
  • mapreduce 复合关键示例 - 未显示所需的输出

    作为mapreduce和hadoop世界的新手 在尝试了基本的mapreduce程序之后 我想尝试compositekey示例代码 输入数据集如下 国家 州 县 百万人口 美国 加利福尼亚州 阿拉米达 100 美国 加利福尼亚州 洛杉矶 2
  • 使用 List 类型的私有变量帮助 Java 中的抽象类

    自从我上次用 Java 编写代码以来已经有两年了 所以我的编码技能有点生疏了 我需要将数据 用户配置文件 保存在不同的数据结构中 ArrayList and LinkedList 并且他们都来自List 我希望尽可能避免代码重复 并且我还希
  • RabbitMQ 数据库文件

    我正在运行 RabbitMQ V 2 0 0 在 Linux 机器上 mnesia 库默认是当前的 但 Rabbit 在该目录中创建目录 例如 电子邮件受保护 cdn cgi l email protection 目录名称中的ip基于机器的
  • time.perf_counter() 或 time.process_time() 用于性能测量?

    我了解 time perf counter 测量经过的总时间 即使进程当前未运行 然而 time process time 仅测量进程实际运行的时间 如果我只是衡量一个功能的性能 这两个中哪一个是首选 由于我实际上对 CPU 花在处理其他进
  • 使用 python 的 eval() 与 ast.literal_eval()

    我遇到一些代码的情况eval 提出了一个可能的解决方案 现在我从来没有使用过eval 但在此之前 我已经了解到很多有关它可能造成的潜在危险的信息 也就是说 我对使用它非常谨慎 我的情况是我有用户提供的输入 datamap input Pro
  • Windows 进程什么时候会耗尽内存?

    在 Windows Server 2003 Enterprise Edition SP2 下 3GB 开关未启用 据我了解 一个进程的最大可寻址内存是 4GB 我可能是错的 那是 2GB 的私有字节和 2GB 的虚拟字节吗 当达到私有字节限
  • 如何使用 sqlalchemy 创建带有日期范围的排除约束

    我知道只需使用原始 sql 我就可以添加排除约束 如下所示 ADD CONSTRAINT unique daterange constraint EXCLUDE USING gist foo WITH daterange start dat
  • PyInstaller:模块未包含在 --onefile 中,但与 --onedir 一起工作正常

    我正在使用 PyInstaller 将我的应用程序捆绑到一个 exe 文件中 问题是它与 onedir 选项一起工作正常 但在使用 onefile 构建时找不到模块 onedir 和 onefile 在构建过程中都会说 lt gt INFO
  • 显示大型结果集

    这是我的问题 我需要存储一个lot日志消息 并认为将其保存在 SQLite3 数据库中以便能够轻松搜索和过滤它是明智的 我将在标准列表小部件中显示日志消息 使用 wxWidgets 该列表将有几列 并且可以由用户排序和过滤 现在 我不确定处
  • Excel 重命名其他计算机上的 Activex 控件

    我有一个带有 Activex 控件 组合框 命令按钮 选项按钮 复选框 的工作表 在我的计算机上 我已重命名所有控件 例如 CButtonPMR OButton Comp 等 但是当我在其他计算机上打开文件时 所有控件都被重命名为默认的默认
  • 在非 Windows 平台(Linux 或 Mac)上使用 Python 处理 Access 数据库

    我想访问 Microsoft Access 数据库中的数据 我有一些 accdb 和 mdb 文件 想用 Python 读取它们 根据我的研究 pyodbc只能在Windows平台上使用 但我正在Mac OS X上工作 我是Python新手
  • 使用弱密钥暴力破解 DES

    我正在学习密码学课程 但正在做一项作业 说明如下 明文 plain6 txt 已使用 DES 加密为 encrypt6 dat 使用 64 位密钥作为 8 个字符的字符串给出 64 位 其中每第 8 位被忽略 所有字符均为字母 小写或大写