您的位置:首页 > 运维架构

Openssl command到API转换--password和key、iv转化以及openssl进行gdb调试

2013-12-26 12:45 447 查看
1、首先openssl命令行如下

#openssl enc -d -aes192 -pass "pass:3eDc#9ujN" -p -in hfb1062.enc -out a.cpio

salt=28C7761EE45FFB06

key=00297EE7F640FB3545C9466583B9D008A4EB3CF24A4EFF65

iv =F4F137201648930D6BA620806691EF71

2、passwor转化成key和iv

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

//openssl  enc -d  -aes192 -pass "pass:3eDc#9ujN"  -p -in  hfb1062.enc -out a.cpio
//openssl password to key,iv
int main(int argc, char *argv[])
{
    const EVP_CIPHER *cipher;
    static const char magic[]="Salted__";
	char mbuf[sizeof magic-1];
    
    const EVP_MD *dgst = NULL;
    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
    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,argv[1]) <= 0)
		{
            perror(argv[1]);
            return;
		}
        printf("her BIO_read_filename argv[1]=%s \n",argv[1]);
    }
     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;
}
3,利用key和iv转化openssl命令行成API

#include <openssl/evp.h>
#include <openssl/err.h>
#include <string.h>
#include <stdio.h>
/*
#openssl  enc -d  -aes192 -pass "pass:3eDc#9ujN"  -p -in  hfb1062.enc -out a.cpio
salt=28C7761EE45FFB06
key=00297EE7F640FB3545C9466583B9D008A4EB3CF24A4EFF65
iv =F4F137201648930D6BA620806691EF71
*/

int set_hex(char *in, unsigned char *out, int size)
{
	int i,n;
	unsigned char j;

	n=strlen(in);
	if (n > (size*2))
		{
		printf("hex string is too long\n");
		return(0);
		}
	memset(out,0,size);
	for (i=0; i<n; i++)
		{
		j=(unsigned char)*in;
		*(in++)='\0';
		if (j == 0) break;
		if ((j >= '0') && (j <= '9'))
			j-='0';
		else if ((j >= 'A') && (j <= 'F'))
			j=j-'A'+10;
		else if ((j >= 'a') && (j <= 'f'))
			j=j-'a'+10;
		else
			{
			printf("non-hex digit\n");
			return(0);
			}
		if (i&1)
			out[i/2]|=j;
		else
			out[i/2]=(j<<4);
		}
	return(1);
}

int do_crypt(FILE *in, FILE *out, int do_encrypt)
{
//do_encrypt:1 for encryption,0 for decryption
    char inbuf[1024]={0}, outbuf[1024 + EVP_MAX_BLOCK_LENGTH]={0};
    int inlen, outlen;

    const char password[] ="3eDc#9ujN";
    
    unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
    unsigned char salt[PKCS5_SALT_LEN];
    
    char hkey[]="00297EE7F640FB3545C9466583B9D008A4EB3CF24A4EFF65",hiv[]="F4F137201648930D6BA620806691EF71";
    
    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init(&ctx);
    
    set_hex(hkey,key,sizeof(key));
    set_hex(hiv,iv,sizeof(iv));
   /* if (!EVP_BytesToKey(cipher,dgst,salt,(unsigned char *)password,strlen(password),1,key,iv)){
        printf("EVP_BytesToKey\n");
    }

    printf("%s\n",EVP_CIPHER_name(cipher));
    printf("%s\n",EVP_MD_name(dgst));
    printf("is pass? %s %d\n",password,strlen(password));
	int iii=0;
    printf("Key: "); for(iii=0; iii<EVP_MAX_KEY_LENGTH; ++iii) { printf(",%d", key[iii]); } printf("\n");
    printf("IV: "); for(iii=0; iii<EVP_MAX_IV_LENGTH; ++iii) { printf(",%d", iv[iii]); } printf("\n");
    printf("%s\n",EVP_CIPHER_name(cipher));
    printf("%s\n",EVP_MD_name(dgst));*/

    EVP_CipherInit_ex(&ctx, EVP_aes_192_cbc(), NULL, key, iv, do_encrypt);
    for(;;)
    {
        inlen = fread(inbuf, 1, 1024, in);
        if(inlen <= 0) break;
        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],"r");
    FILE *out=fopen(argv[2],"w");
    if (NULL ==in){
        printf("error fopen\n");
        return 0;
    }
    do_crypt(in,out,atoi(argv[3]));
    fclose(in);
    fclose(out);
    return 0;
}
4,Openssl源码加入debug信息

首先安装:efence
编译参考: http://stackoverflow.com/questions/11129826/build-openssl-on-linux-with-g-for-debugging


修改openssl-1.0.0的Makefile66行:66 EX_LIBS= -lefence -ldl -lpthread

编译:./config -d
调试:#gdb openssl

(gdb) r enc -d -aes192 -pass "pass:3eDc#9ujN" -p -in /pub/hf/patch1.enc -out a.cpio

5,完整的code,记得要去掉默认的padding data:

#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源码openssl-1.0.0/apps/enc.c

linux efence内存调试工具使用:http://blog.sina.com.cn/s/blog_9151e7300101krxh.html

efence下载: http://perens.com/FreeSoftware/ElectricFence/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: