如何調用介面實現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音影片流:
