一、首先openssl命令行以下html
#openssl enc -d -aes192 -pass "pass:3eDc#9ujN" -p -in hfb1062.enc -out a.cpio
salt=28C7761EE45FFB06
key=00297EE7F640FB3545C9466583B9D008A4EB3CF24A4EFF65
iv =F4F137201648930D6BA620806691EF71
二、passwor轉化成key和ivlinux
#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信息
5,完整的code,記得要去掉默認的padding data:git
#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; }
參考:c#
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/
app