使用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 = aescbc128_decrypt (tmp_buf, tmp_len, key, iv,tmp_buf);
memcpy(iv,tmp_iv,SUMA_KEY_AND_IV_LEN);
}
if(processed_len != tmp_len)