Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我使用openssl API替换该命令,但解密的数据头是错误的。为什么?_Api_Openssl_Command - Fatal编程技术网

我使用openssl API替换该命令,但解密的数据头是错误的。为什么?

我使用openssl API替换该命令,但解密的数据头是错误的。为什么?,api,openssl,command,Api,Openssl,Command,我使用openssl API替换下面的命令行。但是取消键入的文件头是错误的。有人能帮我吗 #openssl enc -d -aes192 -pass "pass:3eDc#9ujN" -p -in hfb1062.enc -out a.cpio salt=28C7761EE45FFB06 key=00297EE7F640FB3545C9466583B9D008A4EB3CF24A4EFF65 iv =F4F137201648930D6BA620806691EF71 salf、key和i

我使用openssl API替换下面的命令行。但是取消键入的文件头是错误的。有人能帮我吗

#openssl  enc -d  -aes192 -pass "pass:3eDc#9ujN"  -p -in  hfb1062.enc -out a.cpio
salt=28C7761EE45FFB06
key=00297EE7F640FB3545C9466583B9D008A4EB3CF24A4EFF65
iv =F4F137201648930D6BA620806691EF71
salf、key和iv与openssl命令行输出相同。 下面是实现about openssl命令行的代码:

#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
#include <stdio.h>
#include <openssl/bio.h>


unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
const EVP_CIPHER *cipher=NULL;
int pass2keyiv(char *infile)
{
    const char magic[]="Salted__";
    char mbuf[sizeof magic-1];

    const EVP_MD *dgst = NULL;
    unsigned char salt[PKCS5_SALT_LEN];
    const char *password = "3eDc#9ujN";
    int i;

    BIO *in=NULL;
    in=BIO_new(BIO_s_file());

    printf("Please specify openssl enc -in arg [file]\n");
    {
    //argv[1] openssl enc -in 
        if (BIO_read_filename(in,infile) <= 0)
        {
            perror(infile);
            return;
        }
        printf("her BIO_read_filename argv[1]=%s \n",infile);
    }
     printf("her in %p \n",in);

     if((BIO_read(in,mbuf,sizeof mbuf) != sizeof mbuf
                      || BIO_read(in,
                              (unsigned char *)salt,
                    sizeof salt) != sizeof salt)){
      perror("read salt error");
      return;
    }
    OpenSSL_add_all_algorithms();

    cipher = EVP_get_cipherbyname("aes192");//"aes-192-cbc");
    if(!cipher) { fprintf(stderr, "no such cipher\n"); return 1; }

    dgst=EVP_get_digestbyname("md5");
    if(!dgst) { fprintf(stderr, "no such digest\n"); return 1; }

    if(!EVP_BytesToKey(cipher, dgst, salt,
        (unsigned char *) password,
        strlen(password), 1, key, iv))
    {
        fprintf(stderr, "EVP_BytesToKey failed\n");
        return 1;
    }
    printf("salt: "); for(i=0; i<PKCS5_SALT_LEN; ++i) { printf("%02x", salt[i]); } printf("\n");
    printf("Key: "); for(i=0; i<cipher->key_len; ++i) { printf("%02x", key[i]); } printf("\n");
    printf("IV: "); for(i=0; i<cipher->iv_len; ++i) { printf("%02x", iv[i]); } printf("\n");

    return 0;
}

int do_crypt(FILE *in, FILE *out)
{
    #define BSIZE   (8*1024)
    char inbuf[BSIZE]={0}, outbuf[BSIZE + EVP_MAX_BLOCK_LENGTH]={0};
    const char magic[]="Salted__";
    char mbuf[sizeof magic-1];

    int inlen, outlen;

    char * needle =NULL;


    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);

    if(fread(mbuf,1,sizeof mbuf,in) != sizeof mbuf)//If I skip the magic size or remove this code line, the decryped data is also wrong.
        printf("bad magic number\n");
    printf("Magic number %s\n",mbuf); 

    //do_encrypt:1 for encryption,0 for decryption
    EVP_CipherInit_ex(&ctx,cipher, NULL, key, iv, 0);

    for(;;)
    {
        bzero(inbuf,sizeof inbuf);
        inlen = fread(inbuf, 1, BSIZE, in);
        if(inlen <= 0) break;
        bzero(outbuf,sizeof outbuf);
        if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
        {
            /* Error */
            EVP_CIPHER_CTX_cleanup(&ctx);
            return 0;
        }


        fwrite(outbuf, 1, outlen, out);
    }
    if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
    {
        /* Error */
        EVP_CIPHER_CTX_cleanup(&ctx);
        return 0;
    }
    fwrite(outbuf, 1, outlen, out);
    EVP_CIPHER_CTX_cleanup(&ctx);
    return 1;
}

int main(int argc,char**argv)
{
    FILE *in=fopen(argv[1],"rb");
    FILE *out=fopen(argv[2],"wb");
    if ( argc != 3){
        printf("Usage: in_file_to_be_decryped out_file%d\n",argc);
        return;
    }
    if (NULL ==in){
        printf("error fopen\n");
        return 0;
    }
    pass2keyiv(argv[1]);
    do_crypt(in,out);
    fclose(in);
    fclose(out);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
无符号字符键[EVP_MAX_key_LENGTH],iv[EVP_MAX_iv_LENGTH];
const EVP_CIPHER*CIPHER=NULL;
int pass2keyiv(字符*填充)
{
const char magic[]=“盐渍”;
char mbuf[sizeof magic-1];
const EVP_MD*dgst=NULL;
未签名的半焦盐[PKCS5_salt_LEN];
const char*password=“3eDc#9ujN”;
int i;
BIO*in=NULL;
in=BIO_new(BIO_s_file());
printf(“请在arg[文件]\n中指定openssl enc-in”);
{
//argv[1]openssl enc-in

如果(BIO_read_filename(in,infle)我有一个类似的问题,我必须用perl脚本解决它,你可以很容易地将它转换成Java

注意我使用DES,因此盐的大小和位置与您的不同。我也使用
DES_EDE
,您需要使用
AES

my $salt = substr($data, 8, 8);
my $ct = substr($data, 16);

my $rounds = 3;
my $data00 = $Key.$salt;
my @md5_hash;
$md5_hash[0] = md5($data00);
my $result = $md5_hash[0];
for (my $i = 1; $i < $rounds; $i++) {
 $md5_hash[$i] = md5($md5_hash[$i - 1].$data00);
 $result .= $md5_hash[$i];
}

my $key = substr($result, 0, 24);
my $iv  = substr($result, 24, 8);

my $m = Crypt::Mode::CFB->new('DES_EDE');
my $plaintext = $m->decrypt($ct, $key, $iv);

return $plaintext;
my$salt=substr($data,8,8);
my$ct=substr($data,16);
我的$rounds=3;
我的$data00=$Key.$salt;
我的@md5_散列;
$md5_hash[0]=md5($data00);
我的$result=$md5_散列[0];
对于(我的$i=1;$i<$rounds;$i++){
$md5_散列[$i]=md5($md5_散列[$i-1].$data00);
$result.=$md5_散列[$i];
}
my$key=substr($result,0,24);
my$iv=substr($result,24,8);
我的$m=Crypt::Mode::CFB->new('DES_EDE');
my$plaintext=$m->decrypt($ct,$key,$iv);
返回$plaintext;

对于您的
AES
,我相信盐的长度将是
16
,因此
ct
(密文)将从位置
24
开始。我还认为AES使用
SHA
而不是
MD5
,但我不是100%确定。以下是我的解决方案:我认为我们应该跳过块大小,这是加密时的默认填充

#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
#include <stdio.h>
#include <openssl/bio.h>

/*
#openssl  enc -d  -aes192 -pass "pass:3eDc#9ujN"  -p -in  hfb1062.enc -out a.cpio
salt=28C7761EE45FFB06
key=00297EE7F640FB3545C9466583B9D008A4EB3CF24A4EFF65
iv =F4F137201648930D6BA620806691EF71
*/

unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
const EVP_CIPHER *cipher=NULL;
int pass2keyiv(char *infile)
{
    const char magic[]="Salted__";
    char mbuf[sizeof magic-1];

    const EVP_MD *dgst = NULL;
    unsigned char salt[PKCS5_SALT_LEN];
    const char *password = "3eDc#9ujN";
    int i;

    BIO *in=NULL;
    in=BIO_new(BIO_s_file());

    printf("Please specify openssl enc -in arg [file]\n");
    {
    //argv[1] openssl enc -in 
        if (BIO_read_filename(in,infile) <= 0)
        {
            perror(infile);
            return;
        }
        printf("her BIO_read_filename argv[1]=%s \n",infile);
    }
     printf("her in %p \n",in);

     if((BIO_read(in,mbuf,sizeof mbuf) != sizeof mbuf
                      || BIO_read(in,
                              (unsigned char *)salt,
                    sizeof salt) != sizeof salt)){
      perror("read salt error");
      return;
    }
    OpenSSL_add_all_algorithms();

    cipher = EVP_get_cipherbyname("aes192");//"aes-192-cbc");
    if(!cipher) { fprintf(stderr, "no such cipher\n"); return 1; }

    dgst=EVP_get_digestbyname("md5");
    if(!dgst) { fprintf(stderr, "no such digest\n"); return 1; }

    if(!EVP_BytesToKey(cipher, dgst, salt,
        (unsigned char *) password,
        strlen(password), 1, key, iv))
    {
        fprintf(stderr, "EVP_BytesToKey failed\n");
        return 1;
    }
    printf("salt: "); for(i=0; i<PKCS5_SALT_LEN; ++i) { printf("%02x", salt[i]); } printf("\n");
    printf("Key: "); for(i=0; i<cipher->key_len; ++i) { printf("%02x", key[i]); } printf("\n");
    printf("IV: "); for(i=0; i<cipher->iv_len; ++i) { printf("%02x", iv[i]); } printf("\n");

    if (in != NULL) BIO_free(in);

    return 0;
}

int do_crypt(FILE *in, FILE *out)
{
    #define BSIZE   (8*1024)
    char inbuf[BSIZE]={0}, outbuf[BSIZE + EVP_MAX_BLOCK_LENGTH]={0};

    int inlen, outlen;
    char * needle =NULL;
    char mblock[1024];
    int blocksize=0;

    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);

    blocksize = EVP_CIPHER_block_size(cipher);
    printf("block size %d\n",blocksize);

    fread(mblock,1,blocksize,in);//skip the magic size

    //EVP_CIPHER_CTX_set_padding(&ctx, 1);
    //do_encrypt:1 for encryption,0 for decryption
    EVP_CipherInit_ex(&ctx,cipher, NULL, key, iv, 0);


    for(;;)
    {
        bzero(inbuf,sizeof inbuf);
        inlen = fread(inbuf, 1, BSIZE, in);
        if(inlen <= 0) break;
        bzero(outbuf,sizeof outbuf);
        if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
        {
            /* Error */
            EVP_CIPHER_CTX_cleanup(&ctx);
            return 0;
        }

        fwrite(outbuf, 1, outlen, out);
    }
    if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
    {
        /* Error */
        EVP_CIPHER_CTX_cleanup(&ctx);
        return 0;
    }
    fwrite(outbuf, 1, outlen, out);
    EVP_CIPHER_CTX_cleanup(&ctx);
    return 1;
}

int main(int argc,char**argv)
{
    FILE *in=fopen(argv[1],"rb");
    FILE *out=fopen(argv[2],"wb");
    if ( argc != 3){
        printf("Usage: in_file_to_be_decryped out_file%d\n",argc);
        return;
    }
    if (NULL ==in){
        printf("error fopen\n");
        return 0;
    }
    pass2keyiv(argv[1]);
    do_crypt(in,out);
    fclose(in);
    fclose(out);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
/*
#openssl enc-d-aes192-pass“pass:3eDc#9ujN”-p-in-hfb1062.enc-out a.cpio
盐=28C7761EE45FFB06
键=00297EE7F640FB3545C9466583B9D008A4EB3CF24A4EFF65
iv=F4F137201648930D6BA620806691EF71
*/
无符号字符键[EVP_MAX_key_LENGTH],iv[EVP_MAX_iv_LENGTH];
const EVP_CIPHER*CIPHER=NULL;
int pass2keyiv(字符*填充)
{
const char magic[]=“盐渍”;
char mbuf[sizeof magic-1];
const EVP_MD*dgst=NULL;
未签名的半焦盐[PKCS5_salt_LEN];
const char*password=“3eDc#9ujN”;
int i;
BIO*in=NULL;
in=BIO_new(BIO_s_file());
printf(“请在arg[文件]\n中指定openssl enc-in”);
{
//argv[1]openssl enc-in

如果(BIO_read_filename,in,infle)OpenSSL封装数据,而您不这样做,即直接调用函数不会为您封装。如果您查看OpenSSL生成的内容,您会注意到如果我尝试跳过“Salted_”,它的标题为
\u Slated
输入文件的大小,但它也是错误的。你不能跳过它,它是一个重要的部分,你需要处理它,在
\u Slated
,文件头之后,我想,是16字节的salt,后面是加密的数据。从salt你可以访问IV,然后它将被用来解密数据。你能更详细地描述它吗在解密输入数据时,我跳过了神奇的大小,但也出现了错误。我怀疑您使用了“my$ct=substr($data,16);”跳过盐的大小。我试过你的方法,它成功了。谢谢。块大小是16。所以跳过块大小,而不是盐的大小。听到它起作用很好,贴一个答案和你的解决方案,这样其他人就可以使用它了