如何調用介面實現RTMP推送和播放端AES或SM4加解密

  • 2019 年 10 月 4 日
  • 筆記

首先介紹下AES演算法和SM4演算法:

AES演算法

密碼學中的高級加密標準(AdvancedEncryptionStandard,AES),又稱Rijndael加密演算法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,高級加密標準由美國國家標準與技術研究院(NIST)於2001年11月26日發佈於FIPSPUB197,並在2002年5月26日成為有效的標準。2006年,高級加密標準已然成為對稱密鑰加密中最流行的演算法之一。AES有一個固定的128位的塊大小和128,192或256位大小的密鑰大小。

該演算法為比利時密碼學家JoanDaemen和VincentRijmen所設計,結合兩位作者的名字,以Rijndael命名之。AES在軟體及硬體上都能快速地加解密,相對來說較易於操作,且只需要很少的存儲空間。作為一個新的加密標準,目前正被部署應用到更廣大的範圍。

SM4演算法

SM4演算法全稱為SM4分組密碼演算法,是國家密碼管理局2012年3月發布的第23號公告中公布的密碼行業標準。SM4演算法是一個分組對稱密鑰演算法,明文、密鑰、密文都是16位元組,加密和解密密鑰相同。加密演算法與密鑰擴展演算法都採用32輪非線性迭代結構。解密過程與加密過程的結構相似,只是輪密鑰的使用順序相反。

SM4演算法的優點是軟體和硬體實現容易,運算速度快。

大多開發者對大牛直播SDK RTMP AES或SM4加解密介面還不太熟悉,本文以Windows RTMP推送和RTMP播放為例,介紹下相關的介面:

Windows RTMP推送端:

1. SetRtmpEncryptionOption:設置RTMP推送加密選項,比如可只加密音頻或影片,也可同時加密;

2. SetRtmpEncryptionAlgorithm:設置RTMP加密演算法,可選的演算法為AES或SM4,如不設定,默認選擇AES;

3. SetRtmpEncryptionKey:設置rtmp推送加密密鑰,key:加密密鑰,key_size: 如果加密演算法是aes, key_size必須是16, 24, 32 這三個值, 其他返回錯誤; 如果加密演算法是sm4, key_size必須是16, 其他值返回錯誤;

4. SetRtmpEncryptionIV:設置rtmp推送加密IV(初始化向量), 這個介面不調用的話, 將使用默認IV。

詳細的介面描述如下:

		/*  		設置rtmp推送加密選項  		url: 考慮到可能推送到多個伺服器,可以根據推送url配置不同的加密選項, 請確保url和SetURL一致  		is_encrypt_video: 1:表示影片加密, 0:表示影片不加密, 默認不加密, 其他值返回錯誤  		is_encrypt_audio: 1:表示音頻加密, 0:表示音頻不加密, 默認不加密, 其他值返回錯誤  		成功返回 NT_ERC_OK  		*/  		NT_UINT32(NT_API *SetRtmpEncryptionOption)(NT_HANDLE handle, NT_PCSTR url, NT_INT32 is_encrypt_video, NT_INT32 is_encrypt_audio);      		/*  		設置rtmp加密演算法  		url: 考慮到可能推送到多個伺服器,可以根據推送url配置不同的加密選項, 請確保url和SetURL一致  		encryption_algorithm: 加密演算法, 當前支援aes和國標sm4. 1為aes, 2為sm4, 默認為aes.  		*/  		NT_UINT32(NT_API *SetRtmpEncryptionAlgorithm)(NT_HANDLE handle, NT_PCSTR url, NT_INT32 encryption_algorithm);      		/*  		設置rtmp推送加密密鑰  		url: 考慮到可能推送到多個伺服器,可以根據推送url配置不同的加密選項, 請確保url和SetURL一致  		key:加密密鑰  		key_size: 如果加密演算法是aes, key_size必須是16, 24, 32 這三個值, 其他返回錯誤; 如果加密演算法是sm4, key_size必須是16, 其他值返回錯誤.  		成功返回 NT_ERC_OK  		*/  		NT_UINT32(NT_API *SetRtmpEncryptionKey)(NT_HANDLE handle, NT_PCSTR url, const NT_BYTE* key, NT_UINT32 key_size);      		/*  		設置rtmp推送加密IV(初始化向量), 這個介面不調用的話, 將使用默認IV  		url: 考慮到可能推送到多個伺服器,可以根據推送url配置不同的加密選項, 請確保url和SetURL一致  		iv: 初始化向量  		iv_size: 當前必須是16, 其他值返回錯誤  		成功返回 NT_ERC_OK  		*/  		NT_UINT32(NT_API *SetRtmpEncryptionIV)(NT_HANDLE handle, NT_PCSTR url, const NT_BYTE* iv, NT_UINT32 iv_size);

Windows RTMP播放端:

1. 設置加密的AES或SM4的Key和IV初始化向量:

		/*  		*  		* 設置解密key,目前只用來解密rtmp加密流  		* key: 解密密鑰  		* size: 密鑰長度  		* 成功返回NT_ERC_OK  		*/  		NT_UINT32(NT_API *SetKey)(NT_HANDLE handle, const NT_BYTE* key, NT_UINT32 size);      		/*  		*  		* 設置解密向量,目前只用來解密rtmp加密流  		* iv:  解密向量  		* size: 向量長度  		* 成功返回NT_ERC_OK  		*/  		NT_UINT32(NT_API *SetDecryptionIV)(NT_HANDLE handle, const NT_BYTE* iv, NT_UINT32 size);

2. 相關Event ID:如檢測到推送的RTMP流系AES或SM4加密,會回調上來NT_SP_E_EVENT_ID_NEED_KEY事件,彈出輸入Key和IV框,如輸入的Key和IV不正確,播放端會收到NT_SP_E_EVENT_ID_KEY_ERROR事件。

NT_SP_E_EVENT_ID_NEED_KEY = NT_SP_E_EVENT_ID_BASE | 0xC, /*需要輸入解密key才能播放*/ NT_SP_E_EVENT_ID_KEY_ERROR = NT_SP_E_EVENT_ID_BASE | 0xD, /*解密key不正確*/

/*事件ID*/  typedef enum _NT_SP_E_EVENT_ID  {  	NT_SP_E_EVENT_ID_BASE = NT_EVENT_ID_SMART_PLAYER_SDK,    	NT_SP_E_EVENT_ID_CONNECTING				= NT_SP_E_EVENT_ID_BASE | 0x2,	/*連接中*/  	NT_SP_E_EVENT_ID_CONNECTION_FAILED		= NT_SP_E_EVENT_ID_BASE | 0x3,	/*連接失敗*/  	NT_SP_E_EVENT_ID_CONNECTED				= NT_SP_E_EVENT_ID_BASE | 0x4,	/*已連接*/  	NT_SP_E_EVENT_ID_DISCONNECTED			= NT_SP_E_EVENT_ID_BASE | 0x5,	/*斷開連接*/  	NT_SP_E_EVENT_ID_NO_MEDIADATA_RECEIVED	= NT_SP_E_EVENT_ID_BASE | 0x8,	/*收不到RTMP數據*/  	NT_SP_E_EVENT_ID_RTSP_STATUS_CODE       = NT_SP_E_EVENT_ID_BASE | 0xB,  /*rtsp status code上報, 目前只上報401, param1表示status code*/  	NT_SP_E_EVENT_ID_NEED_KEY               = NT_SP_E_EVENT_ID_BASE | 0xC,  /*需要輸入解密key才能播放*/  	NT_SP_E_EVENT_ID_KEY_ERROR              = NT_SP_E_EVENT_ID_BASE | 0xD,  /*解密key不正確*/      	/* 接下來請從0x81開始*/  	NT_SP_E_EVENT_ID_START_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x81, /*開始緩衝*/  	NT_SP_E_EVENT_ID_BUFFERING		 = NT_SP_E_EVENT_ID_BASE | 0x82, /*緩衝中, param1 表示百分比進度*/  	NT_SP_E_EVENT_ID_STOP_BUFFERING  = NT_SP_E_EVENT_ID_BASE | 0x83, /*停止緩衝*/    	NT_SP_E_EVENT_ID_DOWNLOAD_SPEED  = NT_SP_E_EVENT_ID_BASE | 0x91, /*下載速度, param1表示下載速度,單位是(Byte/s)*/    	NT_SP_E_EVENT_ID_PLAYBACK_REACH_EOS		= NT_SP_E_EVENT_ID_BASE | 0xa1, /*播放結束, 直播流沒有這個事件,點播流才有*/  	NT_SP_E_EVENT_ID_RECORDER_REACH_EOS		= NT_SP_E_EVENT_ID_BASE | 0xa2, /*錄像結束, 直播流沒有這個事件, 點播流才有*/  	NT_SP_E_EVENT_ID_PULLSTREAM_REACH_EOS   = NT_SP_E_EVENT_ID_BASE | 0xa3, /*拉流結束, 直播流沒有這個事件,點播流才有*/    	NT_SP_E_EVENT_ID_DURATION				= NT_SP_E_EVENT_ID_BASE | 0xa8, /*影片時長,如果是直播,則不上報,如果是點播的話, 若能從影片源獲取影片時長的話,則上報, param1表示影片時長,單位是毫秒(ms)*/    } NT_SP_E_EVENT_ID;

Demo使用:

Windows RTMP推送端(以採集推送螢幕為例):

Windows RTMP播放端,如檢測到是加密流,會自動彈出輸入Key和IV的框,輸入正確的資訊即可正常播放RTMP音影片流:

​

Tags: