使用ffmpeg-3.3.3和openssl-1.0.2l对TS封装H264编码的文件进行NAL的加密,以下是我实现的接口代码:
//#include "StdAfx.h"
#include "TroubleShoot.h"
#ifdef __cplusplus //
extern "C"{
#endif
#include "TSEncrypt.h"
#include
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavutil/opt.h"
#include
#include
#include
#include
static FILE *fp_stream=NULL; //输出文件句柄 static unsigned char s_cp_key[SUMA_KEY_AND_IV_LEN]={0}; //cpck static unsigned char s_cp_iv[SUMA_KEY_AND_IV_LEN]={0}; //cpiv static int s_en_type=0; //读文件数据后是否要进行解密处理 static bool enable_encrypt_card=false; //是否启用硬件加密卡 #if 1 //加密 static int aescbc128_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext) { if((plaintext==NULL)||(plaintext_len==0)||(key==NULL)||(iv==NULL)||(ciphertext==NULL)) return -1; if(enable_encrypt_card) { bool status=false;// = AESEncryptInCBC(plaintext_len,(const BYTE *)plaintext,(const BYTE *)key,(const BYTE *)iv,(BYTE *)ciphertext); if(status) return plaintext_len; else return -1; } else { EVP_CIPHER_CTX *ctx=NULL; int len=0; int ciphertext_len=0; ctx = EVP_CIPHER_CTX_new(); if(ctx==NULL) return -1; EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv); EVP_CIPHER_CTX_set_padding(ctx, 0); EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len); ciphertext_len = len; EVP_EncryptFinal_ex(ctx, ciphertext + len, &len); ciphertext_len += len; EVP_CIPHER_CTX_free(ctx); return ciphertext_len; } } //解密 static int aescbc128_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext) { if((ciphertext==NULL)||(ciphertext_len==0)||(key==NULL)||(iv==NULL)||(plaintext==NULL)) return -1; if(enable_encrypt_card) { bool status=false;// = AESDecryptInCBC(ciphertext_len,(const BYTE *)ciphertext,(const BYTE *)key,(const BYTE *)iv,(BYTE *)plaintext); if(status) return ciphertext_len; else return -1; } else { EVP_CIPHER_CTX *ctx=NULL; int len=0; int plaintext_len=0; ctx = EVP_CIPHER_CTX_new(); if(ctx==NULL) return -1; EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv); EVP_CIPHER_CTX_set_padding(ctx, 0); EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len); plaintext_len = len; EVP_DecryptFinal_ex(ctx, plaintext + len, &len); plaintext_len += len; EVP_CIPHER_CTX_free(ctx); return plaintext_len; } } #endif /*全文件加解密接口*/ int Suma_full_file_encrypt_or_decrypt(char *in_path,char *out_path,unsigned char *key,unsigned char *iv,int flag) { struct stat sta_buff; int ret=0; unsigned char *tmp_buf=NULL; unsigned int tmp_buf_size=SUMA_READ_DATA_LEN; unsigned int read_len=0; unsigned int write_len=0; unsigned int total_write_len=0; unsigned int processed_len=0; unsigned int tmp_len=0; FILE* fp_r=NULL; FILE* fp_w=NULL; unsigned char tmp_iv[SUMA_KEY_AND_IV_LEN]={0}; DvtLog(DVT_MSG_TYPE_INFORMATION,"全文件加解密操作开始"); if((in_path==NULL)||(out_path==NULL)||(key==NULL)||(iv==NULL)) { DvtLog(DVT_MSG_TYPE_ERROR,"全文件加解密的参数错误!"); ret=-1; return ret; } ret = stat(in_path, &sta_buff); if(ret != 0) { DvtLog(DVT_MSG_TYPE_ERROR,"全文件加解密时输入文件不存在!"); return ret; } fp_r=fopen(in_path,"rb"); if(fp_r == NULL) { DvtLog(DVT_MSG_TYPE_ERROR,"全文件加解密时打开输入文件失败!"); ret=-1; goto end; } fp_w=fopen(out_path,"wb+"); if(fp_w == NULL) { DvtLog(DVT_MSG_TYPE_ERROR,"全文件加解密时打开输出文件失败!"); ret=-1; goto end; } tmp_buf = (unsigned char *)malloc(tmp_buf_size); if(tmp_buf == NULL) { DvtLog(DVT_MSG_TYPE_ERROR,"全文件加解密时分配缓存失败!"); ret=-1; goto end; } while(sta_buff.st_size>total_write_len) { read_len=fread(tmp_buf,1,tmp_buf_size,fp_r); tmp_len=read_len/SUMA_KEY_AND_IV_LEN*SUMA_KEY_AND_IV_LEN; if(flag == 0) { processed_len = aescbc128_encrypt (tmp_buf, tmp_len, key, iv,tmp_buf); memcpy(iv,tmp_buf+tmp_len-SUMA_KEY_AND_IV_LEN,SUMA_KEY_AND_IV_LEN); } else { memcpy(tmp_iv,tmp_buf+tmp_len-SUMA_KEY_AND_IV_LEN,SUMA_KEY_AND_IV_LEN); processed_len