gpt4 book ai didi

c - 我如何让它解码(Perl cbc-crypt 到 C cbc_crypt 转换)

转载 作者:太空宇宙 更新时间:2023-11-04 00:03:55 24 4
gpt4 key购买 nike

我正在尝试能够解码使用 perl 脚本编码的编码字符串。我不能只更改 perl 脚本的原因是因为已经存在许多通过 perl 脚本保存的重要数据,用 perl 解码并以其他方式重新编码会太多。把东西放在原地(现在)更容易。然而,编译后的 perl 代码是 2MB。我想用 C 语言编写它,这样可执行文件的大小会更小。

我目前所拥有的如下。虽然它不会工作。它基本上给了我垃圾输出。我认为问题在于 perl 脚本使用了基于十六进制的加密。我该如何解码呢?谁能指出我哪里出错了?

/*
Test to decode perl-encrypted string.
NOTE: Not all code written by me. Function code is either written by or derived
from code from other people in response to similar questions found on the
internet.

Required Lib: crypt (-lcrypt)

Perl Code from existing script (that is being converted to C):

use Crypt::CBC;
use Crypt::DES;
my $text = "thisisalongtest";
my $salt_key = "fOagmJOKu2SF";
my $cipher = Crypt::CBC->new( -key => $salt_key, -cipher => 'DES' -header => 'none');
my $enc_text = $cipher->encrypt_hex($text);
Perl crypt functions require libcrypt-cbc-perl & libcrypt-des-perl

Data:

Original Text: thisisalongtest
Salt Key: fOagmJOKu2SF
Resulting Encrypted String: 53616c7465645f5f167ebac84042fe7ceac836e1d3e7d3aa1dfc27e0e8cad0f1

Resulting output:

Decrypted: (unprintable junk characters)
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/des_crypt.h>

#define BUFFSIZE 420

int encrypt(char key[9], char salt[9], char pass[BUFFSIZE], int mode);
void enc_from_hex(const char* st, char ret_result[BUFFSIZE]);
int hex_to_int(char c);
int hex_to_ascii(char c, char d);

int main (int argc, char *argv[]) {

int err;
char passwd[BUFFSIZE];
char result[BUFFSIZE];
char key[13];

sprintf(key,"fOagmJOKu2SF");

/* Change this from hex pairs to ASCII */
sprintf(passwd, "53616c7465645f5f167ebac84042fe7ceac836e1d3e7d3aa1dfc27e0e8cad0f1");
enc_from_hex(passwd, result);

/* Decrypt */
err = encrypt(key, "", result, 1); /* DO NOT use 'NULL' for 2nd parameter! */
if(err != 0) {
printf("Error.\n");
} else {
printf("Decrypted: %s\n", result);
}

return 0;
}

/* Encryption */
int encrypt(char key[13], char salt[13], char pass[BUFFSIZE], int mode){
char temp[13];
strcpy(temp, salt);
int buffsize;
int errcode;

des_setparity(key);
buffsize = strlen(pass);

/* Pad pass to ensure size is divisable by 8.*/
while (buffsize % 8 && buffsize<BUFFSIZE) {
pass[buffsize++] = '\0';
}

/* Determine Function */
if(mode == 1) {
errcode = cbc_crypt(key, pass, buffsize, DES_DECRYPT | DES_SW, temp);
} else {
errcode = cbc_crypt(key, pass, buffsize, DES_ENCRYPT | DES_SW, temp);
}

if (DES_FAILED(errcode) || strcmp(pass, "") == 0) {
return errcode;
}

return errcode;
}

/* Hex conversion functions */
void enc_from_hex(const char* st, char ret_result[BUFFSIZE]) {
char temp[2];

int length = strlen(st);
int i;
char buf = 0;
for(i = 0; i < length; i++) {
if(i % 2 != 0) {
sprintf(temp, "%c", hex_to_ascii(buf, st[i]));
strcat(ret_result, temp);
} else {
buf = st[i];
}
}

}

int hex_to_int(char c) {
int first = c / 16 - 3;
int second = c % 16;
int result = first*10 + second;
if(result > 9) result--;
return result;
}

int hex_to_ascii(char c, char d) {
int high = hex_to_int(c) * 16;
int low = hex_to_int(d);
return high+low;
}

最佳答案

正如@ikegami 在评论中指出的那样,传递给 key Crypt::CBC 的值并不是真正的 key 。该值被传递给另一个函数,该函数将它与随机盐结合,然后对其进行哈希处理以生成真正的 key 和初始化 vector 。随机盐与密码文本一起保存,其想法是,如果您使用相同的 key 多次加密相同的数据,每次的输出都会不同。

如果将加密字符串转换为 ascii,您会注意到前八个字符拼写为 Salted__,这对应于 OpenSSL 使用的格式。

下面是一个使用 OpenSSL 的 EVP api 的粗略示例:

//
// compile with: gcc -o crypt crypt.c -lssl -lcrypto
//
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>

int main(int argc, char *argv[]){
char pass[]="fOagmJOKu2SF";
char text[]="53616c7465645f5f167ebac84042fe7ceac836e1d3e7d3aa1dfc27e0e8cad0f1";

int i = 0;
char *pos=text;
while(*pos){ // converts hex string to binary in place
sscanf(pos, "%2hhx", &text[i++]);
pos += 2;
} text[i]=0;

EVP_CIPHER_CTX ctx;
unsigned char key[8] = {0};
unsigned char iv[8] = {0};

int len;
char *clear = malloc(strlen(text));

// v-> First Charicter after 'Salted__'
EVP_BytesToKey(EVP_des_cbc(), EVP_md5(), &text[8], pass, strlen(pass), 1, key, iv);

EVP_DecryptInit(&ctx, EVP_des_cbc(), key, iv);
// v-> Cypertext starts after salt
EVP_DecryptUpdate(&ctx, clear, &len, &text[16], strlen(text)-15);
EVP_DecryptFinal(&ctx, clear, &len);

printf("%s\n", clear);
return 0;
}

http://www.ict.griffith.edu.au/anthony/info/crypto/openssl.hints https://www.openssl.org/docs/manmaster/crypto/EVP_BytesToKey.html https://www.openssl.org/docs/manmaster/crypto/EVP_EncryptInit.html

关于c - 我如何让它解码(Perl cbc-crypt 到 C cbc_crypt 转换),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31678983/

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