當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀] 當(dāng)服務(wù)器和客戶(hù)端的握手是按照rtmp協(xié)議進(jìn)行,是不支持h264/aac的,有數(shù)據(jù),就是沒(méi)有視頻和聲音。 原因是adobe變更了握手的數(shù)據(jù)結(jié)構(gòu),標(biāo)準(zhǔn)rtmp協(xié)議的握手的包是隨機(jī)的1536字節(jié)(S

當(dāng)服務(wù)器和客戶(hù)端的握手是按照rtmp協(xié)議進(jìn)行,是不支持h264/aac的,有數(shù)據(jù),就是沒(méi)有視頻和聲音。

原因是adobe變更了握手的數(shù)據(jù)結(jié)構(gòu),標(biāo)準(zhǔn)rtmp協(xié)議的握手的包是隨機(jī)的1536字節(jié)(S1S2C1C2),變更后的是需要進(jìn)行摘要和加密。

rtmp協(xié)議定義的為simple handshake,變更后加密握手可稱(chēng)為complex handshake。

本文詳細(xì)分析了rtmpd(ccrtmpserver)中的處理邏輯,以及rtmpdump的處理邏輯,從一個(gè)全是魔法數(shù)字的世界找到他們的數(shù)據(jù)結(jié)構(gòu)和算法。

complex handshake C1S1結(jié)構(gòu)

complex handshake將C1S1分為4個(gè)部分,它們的順序(schema)一種可能是:

[plain]view plaincopy //c1s1schema0 time:4bytes version:4bytes key:764bytes digest:764bytes 其中,key和digest可能會(huì)交換位置,即schema可能是:

[plain]view plaincopy //c1s1schema1 time:4bytes version:4bytes digest:764bytes key:764bytes

客戶(hù)端來(lái)決定使用哪種schema,服務(wù)器端則需要先嘗試按照schema0解析,失敗則用schema1解析。如下圖所示:


無(wú)論key和digest位置如何,它們的結(jié)構(gòu)是不變的:

[plain]view plaincopy //764byteskey結(jié)構(gòu) random-data:(offset)bytes key-data:128bytes random-data:(764-offset-128-4)bytes offset:4bytes //764bytesdigest結(jié)構(gòu) offset:4bytes random-data:(offset)bytes digest-data:32bytes random-data:(764-4-offset-32)bytes 備注:發(fā)現(xiàn)FMS只認(rèn)識(shí)digest-key結(jié)構(gòu)。

如下圖所示:



crtmp中這些全是魔法數(shù)字。

complex handshake C2S2結(jié)構(gòu)

C2S2主要是提供對(duì)C1S1的驗(yàn)證。結(jié)構(gòu)如下:

[plain]view plaincopy //1536bytesC2S2結(jié)構(gòu) random-data:1504bytes digest-data:32bytes

C2S2的結(jié)構(gòu)相對(duì)比較簡(jiǎn)單。如下圖所示:


下面介紹C1S1C2S2的生成以及驗(yàn)證算法。

complex handshake C1S1算法

C1S1中都是包含32字節(jié)的digest,而且digest將C1S1分成兩部分:

[plain]view plaincopy //C1S1被digest分成兩部分 c1s1-part1:nbytes digest-data:32bytes c1s1-part2:(1536-n-32)bytes

如下圖所示:


在生成C1時(shí),需要用到c1s1-part1和c1s1-part2這兩個(gè)部分的字節(jié)拼接起來(lái)的字節(jié),定義為:

[plain]view plaincopy c1s1-joined=bytes_join(c1s1-part1,c1s1-part2)

也就是說(shuō),把1536字節(jié)的c1s1中的32字節(jié)的digest拿剪刀剪掉,剩下的頭和尾加在一起就是c1s1-joined。

用到的兩個(gè)常量FPKey和FMSKey:

[plain]view plaincopy u_int8_tFMSKey[]={ 0x47,0x65,0x6e,0x75,0x69,0x6e,0x65,0x20, 0x41,0x64,0x6f,0x62,0x65,0x20,0x46,0x6c, 0x61,0x73,0x68,0x20,0x4d,0x65,0x64,0x69, 0x61,0x20,0x53,0x65,0x72,0x76,0x65,0x72, 0x20,0x30,0x30,0x31,//GenuineAdobeFlashMediaServer001 0xf0,0xee,0xc2,0x4a,0x80,0x68,0xbe,0xe8, 0x2e,0x00,0xd0,0xd1,0x02,0x9e,0x7e,0x57, 0x6e,0xec,0x5d,0x2d,0x29,0x80,0x6f,0xab, 0x93,0xb8,0xe6,0x36,0xcf,0xeb,0x31,0xae };//68 u_int8_tFPKey[]={ 0x47,0x65,0x6E,0x75,0x69,0x6E,0x65,0x20, 0x41,0x64,0x6F,0x62,0x65,0x20,0x46,0x6C, 0x61,0x73,0x68,0x20,0x50,0x6C,0x61,0x79, 0x65,0x72,0x20,0x30,0x30,0x31,//GenuineAdobeFlashPlayer001 0xF0,0xEE,0xC2,0x4A,0x80,0x68,0xBE,0xE8, 0x2E,0x00,0xD0,0xD1,0x02,0x9E,0x7E,0x57, 0x6E,0xEC,0x5D,0x2D,0x29,0x80,0x6F,0xAB, 0x93,0xB8,0xE6,0x36,0xCF,0xEB,0x31,0xAE };//62 生成C1的算法如下:

[plain]view plaincopy calc_c1_digest(c1,schema){ getc1s1-joinedfromc1byspecifiedschema digest-data=HMACsha256(c1s1-joined,FPKey,30) returndigest-data; } randomfill1536bytesc1//alsofillthec1-128bytes-key time=time()//c1[0-3] version=[0x80,0x00,0x07,0x02]//c1[4-7] schema=chooseschema0orschema1 digest-data=calc_c1_digest(c1,schema) copydigest-datatoc1 生成S1的算法如下:

[plain]view plaincopy /*decodec1tryschema0thenschema1*/ c1-digest-data=get-c1-digest-data(schema0) ifc1-digest-dataequalstocalc_c1_digest(c1,schema0){ c1-key-data=get-c1-key-data(schema0) schema=schema0 }else{ c1-digest-data=get-c1-digest-data(schema1) ifc1-digest-datanotequalstocalc_c1_digest(c1,schema1){ switchtosimplehandshake. return } c1-key-data=get-c1-key-data(schema1) schema=schema1 } /*generates1*/ randomfill1536bytess1 time=time()//c1[0-3] version=[0x04,0x05,0x00,0x01]//s1[4-7] s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) getc1s1-joinedbyspecifiedschema s1-digest-data=HMACsha256(c1s1-joined,FMSKey,36) copys1-digest-dataands1-key-datatos1.

C1S1的算法完畢。

complex handshake C2S2

C2S2的生成算法如下:

[plain]view plaincopy randomfillc2s21536bytes //clientgenerateC2,orservervalidC2 temp-key=HMACsha256(s1-digest,FPKey,62) c2-digest-data=HMACsha256(c2-random-data,temp-key,32) //servergenerateS2,orclientvalidS2 temp-key=HMACsha256(c1-digest,FMSKey,68) s2-digest-data=HMACsha256(s2-random-data,temp-key,32) 驗(yàn)證的算法是一樣的。

代碼實(shí)現(xiàn)

[cpp]view plaincopy /* TheMITLicense(MIT) Copyright(c)2013-2014winlin Permissionisherebygranted,freeofcharge,toanypersonobtainingacopyof thissoftwareandassociateddocumentationfiles(the"Software"),todealin theSoftwarewithoutrestriction,includingwithoutlimitationtherightsto use,copy,modify,merge,publish,distribute,sublicense,and/orsellcopiesof theSoftware,andtopermitpersonstowhomtheSoftwareisfurnishedtodoso, subjecttothefollowingconditions: Theabovecopyrightnoticeandthispermissionnoticeshallbeincludedinall copiesorsubstantialportionsoftheSoftware. THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND,EXPRESSOR IMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOFMERCHANTABILITY,FITNESS FORAPARTICULARPURPOSEANDNONINFRINGEMENT.INNOEVENTSHALLTHEAUTHORSOR COPYRIGHTHOLDERSBELIABLEFORANYCLAIM,DAMAGESOROTHERLIABILITY,WHETHER INANACTIONOFCONTRACT,TORTOROTHERWISE,ARISINGFROM,OUTOFORIN CONNECTIONWITHTHESOFTWAREORTHEUSEOROTHERDEALINGSINTHESOFTWARE. */ #ifndefSRS_RTMP_PROTOCOL_HANDSHKAE_HPP #defineSRS_RTMP_PROTOCOL_HANDSHKAE_HPP /* #include */ #include classISrsProtocolReaderWriter; classSrsComplexHandshake; classSrsHandshakeBytes; classSrsStream; #ifdefSRS_AUTO_SSL //foropenssl. #include namespace_srs_internal { //thedigestkeygeneratesize. #define__SRS_OpensslHashSize512 externu_int8_tSrsGenuineFMSKey[]; externu_int8_tSrsGenuineFPKey[]; intopenssl_HMACsha256(constvoid*key,intkey_size,constvoid*data,intdata_size,void*digest); intopenssl_generate_key(char*public_key,int32_tsize); /** *theDHwrapper. */ classSrsDH { private: DH*pdh; public: SrsDH(); virtual~SrsDH(); public: /** *initializedh,generatethepublicandprivatekey. *@paramensure_128bytes_public_keywhetherensurepublickeyis128bytes, *sometimesopensslgenerate127bytespublickey. *defaulttofalsetodonotensure. */ virtualintinitialize(boolensure_128bytes_public_key=false); /** *copythepublickey. *@parampkeythebytestocopythepublickey. *@parampkey_sizethemaxpublickeysize,outputtheactualpublickeysize. *usershouldneverignorethissize. *@remark,whenensure_128bytes_public_key,thesizealways128. */ virtualintcopy_public_key(char*pkey,int32_t&pkey_size); /** *generateandcopythesharedkey. *generatethesharedkeywithpeerpublickey. *@paramppkeypeerpublickey. *@paramppkey_sizethesizeofppkey. *@paramskeythecomputedsharedkey. *@paramskey_sizethemaxsharedkeysize,outputtheactualsharedkeysize. *usershouldneverignorethissize. */ virtualintcopy_shared_key(constchar*ppkey,int32_tppkey_size,char*skey,int32_t&skey_size); private: virtualintdo_initialize(); }; /** *theschematype. */ enumsrs_schema_type { srs_schema_invalid=2, /** *key-digestsequence */ srs_schema0=0, /** *digest-keysequence *@remark,FMSrequirestheschema1(digest-key),orconnectfailed. */ // srs_schema1=1, }; /** *764byteskeystructure *random-data:(offset)bytes *key-data:128bytes *random-data:(764-offset-128-4)bytes *offset:4bytes *@seealso:http://blog.csdn.net/win_lin/article/details/13006803 */ classkey_block { public: //(offset)bytes char*random0; intrandom0_size; //128bytes charkey[128]; //(764-offset-128-4)bytes char*random1; intrandom1_size; //4bytes int32_toffset; public: key_block(); virtual~key_block(); public: //parsekeyblockfromc1s1. //ifcreated,usermustfreeitbysrs_key_block_free //@streamcontainsc1s1_key_bytesthekeystartbytes intparse(SrsStream*stream); private: //calctheoffsetofkey, //thekey->offsetcannotbeusedastheoffsetofkey. intcalc_valid_offset(); }; /** *764bytesdigeststructure *offset:4bytes *random-data:(offset)bytes *digest-data:32bytes *random-data:(764-4-offset-32)bytes *@seealso:http://blog.csdn.net/win_lin/article/details/13006803 */ classdigest_block { public: //4bytes int32_toffset; //(offset)bytes char*random0; intrandom0_size; //32bytes chardigest[32]; //(764-4-offset-32)bytes char*random1; intrandom1_size; public: digest_block(); virtual~digest_block(); public: //parsedigestblockfromc1s1. //ifcreated,usermustfreeitbysrs_digest_block_free //@streamcontainsc1s1_digest_bytesthedigeststartbytes intparse(SrsStream*stream); private: //calctheoffsetofdigest, //thekey->offsetcannotbeusedastheoffsetofdigest. intcalc_valid_offset(); }; classc1s1; /** *thec1s1strategy,useschema0orschema1. *thetemplatemethodclasstodefinescommonbehaviors, *whiletheconcreteclasstoimplementsinschema0orschema1. */ classc1s1_strategy { protected: key_blockkey; digest_blockdigest; public: c1s1_strategy(); virtual~c1s1_strategy(); public: /** *getthescema. */ virtualsrs_schema_typeschema()=0; /** *getthedigest. */ virtualchar*get_digest(); /** *getthekey. */ virtualchar*get_key(); /** *copytobytes. *@paramsizemustbe1536. */ virtualintdump(c1s1*owner,char*_c1s1,intsize); /** *server:parsethec1s1,discoverythekeyanddigestbyschema. *usethec1_validate_digest()tovalidthedigestofc1. */ virtualintparse(char*_c1s1,intsize)=0; public: /** *client:createandsignc1byschema. *signthec1,generatethedigest. *calc_c1_digest(c1,schema){ *getc1s1-joinedfromc1byspecifiedschema *digest-data=HMACsha256(c1s1-joined,FPKey,30) *returndigest-data; *} *randomfill1536bytesc1//alsofillthec1-128bytes-key *time=time()//c1[0-3] *version=[0x80,0x00,0x07,0x02]//c1[4-7] *schema=chooseschema0orschema1 *digest-data=calc_c1_digest(c1,schema) *copydigest-datatoc1 */ virtualintc1_create(c1s1*owner); /** *server:validatetheparsedc1schema */ virtualintc1_validate_digest(c1s1*owner,bool&is_valid); /** *server:createandsignthes1fromc1. *//decodec1tryschema0thenschema1 *c1-digest-data=get-c1-digest-data(schema0) *ifc1-digest-dataequalstocalc_c1_digest(c1,schema0){ *c1-key-data=get-c1-key-data(schema0) *schema=schema0 *}else{ *c1-digest-data=get-c1-digest-data(schema1) *ifc1-digest-datanotequalstocalc_c1_digest(c1,schema1){ *switchtosimplehandshake. *return *} *c1-key-data=get-c1-key-data(schema1) *schema=schema1 *} * *//generates1 *randomfill1536bytess1 *time=time()//c1[0-3] *version=[0x04,0x05,0x00,0x01]//s1[4-7] *s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) *getc1s1-joinedbyspecifiedschema *s1-digest-data=HMACsha256(c1s1-joined,FMSKey,36) *copys1-digest-dataands1-key-datatos1. *@paramc1,togetthepeer_pub_keyofclient. */ virtualints1_create(c1s1*owner,c1s1*c1); /** *server:validatetheparseds1schema */ virtualints1_validate_digest(c1s1*owner,bool&is_valid); public: /** *calcthedigestforc1 */ virtualintcalc_c1_digest(c1s1*owner,char*&c1_digest); /** *calcthedigestfors1 */ virtualintcalc_s1_digest(c1s1*owner,char*&s1_digest); /** *copywholec1s1tobytes. *@paramsizemustalwaysbe1536withdigest,and1504withoutdigest. */ virtualintcopy_to(c1s1*owner,char*bytes,intsize,boolwith_digest)=0; /** *copytimeandversiontostream. */ virtualvoidcopy_time_version(SrsStream*stream,c1s1*owner); /** *copykeytostream. */ virtualvoidcopy_key(SrsStream*stream); /** *copydigesttostream. */ virtualvoidcopy_digest(SrsStream*stream,boolwith_digest); }; /** *c1s1schema0 *key:764bytes *digest:764bytes */ classc1s1_strategy_schema0:publicc1s1_strategy { public: c1s1_strategy_schema0(); virtual~c1s1_strategy_schema0(); public: virtualsrs_schema_typeschema(); virtualintparse(char*_c1s1,intsize); public: virtualintcopy_to(c1s1*owner,char*bytes,intsize,boolwith_digest); }; /** *c1s1schema1 *digest:764bytes *key:764bytes */ classc1s1_strategy_schema1:publicc1s1_strategy { public: c1s1_strategy_schema1(); virtual~c1s1_strategy_schema1(); public: virtualsrs_schema_typeschema(); virtualintparse(char*_c1s1,intsize); public: virtualintcopy_to(c1s1*owner,char*bytes,intsize,boolwith_digest); }; /** *c1s1schema0 *time:4bytes *version:4bytes *key:764bytes *digest:764bytes *c1s1schema1 *time:4bytes *version:4bytes *digest:764bytes *key:764bytes *@seealso:http://blog.csdn.net/win_lin/article/details/13006803 */ classc1s1 { public: //4bytes int32_ttime; //4bytes int32_tversion; //764bytes+764bytes c1s1_strategy*payload; public: c1s1(); virtual~c1s1(); public: /** *getthescema. */ virtualsrs_schema_typeschema(); /** *getthedigestkey. */ virtualchar*get_digest(); /** *getthekey. */ virtualchar*get_key(); public: /** *copytobytes. *@paramsize,mustalwaysbe1536. */ virtualintdump(char*_c1s1,intsize); /** *server:parsethec1s1,discoverythekeyanddigestbyschema. *@paramsize,mustalwaysbe1536. *usethec1_validate_digest()tovalidthedigestofc1. *usethes1_validate_digest()tovalidthedigestofs1. */ virtualintparse(char*_c1s1,intsize,srs_schema_type_schema); public: /** *client:createandsignc1byschema. *signthec1,generatethedigest. *calc_c1_digest(c1,schema){ *getc1s1-joinedfromc1byspecifiedschema *digest-data=HMACsha256(c1s1-joined,FPKey,30) *returndigest-data; *} *randomfill1536bytesc1//alsofillthec1-128bytes-key *time=time()//c1[0-3] *version=[0x80,0x00,0x07,0x02]//c1[4-7] *schema=chooseschema0orschema1 *digest-data=calc_c1_digest(c1,schema) *copydigest-datatoc1 */ virtualintc1_create(srs_schema_type_schema); /** *server:validatetheparsedc1schema */ virtualintc1_validate_digest(bool&is_valid); public: /** *server:createandsignthes1fromc1. *//decodec1tryschema0thenschema1 *c1-digest-data=get-c1-digest-data(schema0) *ifc1-digest-dataequalstocalc_c1_digest(c1,schema0){ *c1-key-data=get-c1-key-data(schema0) *schema=schema0 *}else{ *c1-digest-data=get-c1-digest-data(schema1) *ifc1-digest-datanotequalstocalc_c1_digest(c1,schema1){ *switchtosimplehandshake. *return *} *c1-key-data=get-c1-key-data(schema1) *schema=schema1 *} * *//generates1 *randomfill1536bytess1 *time=time()//c1[0-3] *version=[0x04,0x05,0x00,0x01]//s1[4-7] *s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) *getc1s1-joinedbyspecifiedschema *s1-digest-data=HMACsha256(c1s1-joined,FMSKey,36) *copys1-digest-dataands1-key-datatos1. */ virtualints1_create(c1s1*c1); /** *server:validatetheparseds1schema */ virtualints1_validate_digest(bool&is_valid); }; /** *thec2s2complexhandshakestructure. *random-data:1504bytes *digest-data:32bytes *@seealso:http://blog.csdn.net/win_lin/article/details/13006803 */ classc2s2 { public: charrandom[1504]; chardigest[32]; public: c2s2(); virtual~c2s2(); public: /** *copytobytes. *@paramsize,mustalwaysbe1536. */ virtualintdump(char*_c2s2,intsize); /** *parsethec2s2 *@paramsize,mustalwaysbe1536. */ virtualintparse(char*_c2s2,intsize); public: /** *createc2. *randomfillc2s21536bytes * *//clientgenerateC2,orservervalidC2 *temp-key=HMACsha256(s1-digest,FPKey,62) *c2-digest-data=HMACsha256(c2-random-data,temp-key,32) */ virtualintc2_create(c1s1*s1); /** *validatethec2fromclient. */ virtualintc2_validate(c1s1*s1,bool&is_valid); public: /** *creates2. *randomfillc2s21536bytes * *//servergenerateS2,orclientvalidS2 *temp-key=HMACsha256(c1-digest,FMSKey,68) *s2-digest-data=HMACsha256(s2-random-data,temp-key,32) */ virtualints2_create(c1s1*c1); /** *validatethes2fromserver. */ virtualints2_validate(c1s1*c1,bool&is_valid); }; } #endif /** *simplehandshake. *usercantrycomplexhandshakefirst, *rollbacktosimplehandshakeiferrorERROR_RTMP_TRY_SIMPLE_HS */ classSrsSimpleHandshake { public: SrsSimpleHandshake(); virtual~SrsSimpleHandshake(); public: /** *simplehandshake. */ virtualinthandshake_with_client(SrsHandshakeBytes*hs_bytes,ISrsProtocolReaderWriter*io); virtualinthandshake_with_server(SrsHandshakeBytes*hs_bytes,ISrsProtocolReaderWriter*io); }; /** *rtmpcomplexhandshake, *@seealsocrtmp(crtmpserver)orlibrtmp, *@seealso:http://blog.csdn.net/win_lin/article/details/13006803 */ classSrsComplexHandshake { public: SrsComplexHandshake(); virtual~SrsComplexHandshake(); public: /** *complexhanshake. *@returnusermust: *continueconnectappifsuccess, *trysimplehandshakeiferrorisERROR_RTMP_TRY_SIMPLE_HS, *otherwise,disconnect */ virtualinthandshake_with_client(SrsHandshakeBytes*hs_bytes,ISrsProtocolReaderWriter*io); virtualinthandshake_with_server(SrsHandshakeBytes*hs_bytes,ISrsProtocolReaderWriter*io); }; #endif /* TheMITLicense(MIT) Copyright(c)2013-2014winlin Permissionisherebygranted,freeofcharge,toanypersonobtainingacopyof thissoftwareandassociateddocumentationfiles(the"Software"),todealin theSoftwarewithoutrestriction,includingwithoutlimitationtherightsto use,copy,modify,merge,publish,distribute,sublicense,and/orsellcopiesof theSoftware,andtopermitpersonstowhomtheSoftwareisfurnishedtodoso, subjecttothefollowingconditions: Theabovecopyrightnoticeandthispermissionnoticeshallbeincludedinall copiesorsubstantialportionsoftheSoftware. THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND,EXPRESSOR IMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOFMERCHANTABILITY,FITNESS FORAPARTICULARPURPOSEANDNONINFRINGEMENT.INNOEVENTSHALLTHEAUTHORSOR COPYRIGHTHOLDERSBELIABLEFORANYCLAIM,DAMAGESOROTHERLIABILITY,WHETHER INANACTIONOFCONTRACT,TORTOROTHERWISE,ARISINGFROM,OUTOFORIN CONNECTIONWITHTHESOFTWAREORTHEUSEOROTHERDEALINGSINTHESOFTWARE. */ #include #include #include #include #include #include #include #include #include #ifdefSRS_AUTO_SSL usingnamespace_srs_internal; //foropenssl_HMACsha256 #include #include //for__openssl_generate_key #include namespace_srs_internal { //68bytesFMSkeywhichisusedtosigntheseverpacket. u_int8_tSrsGenuineFMSKey[]={ 0x47,0x65,0x6e,0x75,0x69,0x6e,0x65,0x20, 0x41,0x64,0x6f,0x62,0x65,0x20,0x46,0x6c, 0x61,0x73,0x68,0x20,0x4d,0x65,0x64,0x69, 0x61,0x20,0x53,0x65,0x72,0x76,0x65,0x72, 0x20,0x30,0x30,0x31,//GenuineAdobeFlashMediaServer001 0xf0,0xee,0xc2,0x4a,0x80,0x68,0xbe,0xe8, 0x2e,0x00,0xd0,0xd1,0x02,0x9e,0x7e,0x57, 0x6e,0xec,0x5d,0x2d,0x29,0x80,0x6f,0xab, 0x93,0xb8,0xe6,0x36,0xcf,0xeb,0x31,0xae };//68 //62bytesFPkeywhichisusedtosigntheclientpacket. u_int8_tSrsGenuineFPKey[]={ 0x47,0x65,0x6E,0x75,0x69,0x6E,0x65,0x20, 0x41,0x64,0x6F,0x62,0x65,0x20,0x46,0x6C, 0x61,0x73,0x68,0x20,0x50,0x6C,0x61,0x79, 0x65,0x72,0x20,0x30,0x30,0x31,//GenuineAdobeFlashPlayer001 0xF0,0xEE,0xC2,0x4A,0x80,0x68,0xBE,0xE8, 0x2E,0x00,0xD0,0xD1,0x02,0x9E,0x7E,0x57, 0x6E,0xEC,0x5D,0x2D,0x29,0x80,0x6F,0xAB, 0x93,0xB8,0xE6,0x36,0xCF,0xEB,0x31,0xAE };//62 int__openssl_HMACsha256(HMAC_CTX*ctx,constvoid*data,intdata_size,void*digest,unsignedint*digest_size) { intret=ERROR_SUCCESS; if(HMAC_Update(ctx,(unsignedchar*)data,data_size)<0){ ret=ERROR_OpenSslSha256Update; returnret; } if(HMAC_Final(ctx,(unsignedchar*)digest,digest_size)<0){ ret=ERROR_OpenSslSha256Final; returnret; } returnret; } /** *sha256digestalgorithm. *@paramkeythesha256key,NULLtouseEVP_Digest,forinstance, *hashlib.sha256(data).digest(). */ intopenssl_HMACsha256(constvoid*key,intkey_size,constvoid*data,intdata_size,void*digest) { intret=ERROR_SUCCESS; unsignedintdigest_size=0; unsignedchar*__key=(unsignedchar*)key; unsignedchar*__digest=(unsignedchar*)digest; if(key==NULL){ //usedatatodigest. //@see./crypto/sha/sha256t.c //@see./crypto/evp/digest.c if(EVP_Digest(data,data_size,__digest,&digest_size,EVP_sha256(),NULL)<0) { ret=ERROR_OpenSslSha256EvpDigest; returnret; } }else{ //usekey-datatodigest. HMAC_CTXctx; //@remark,ifnokey,useEVP_Digesttodigest, //forinstance,inpython,hashlib.sha256(data).digest(). HMAC_CTX_init(&ctx); if(HMAC_Init_ex(&ctx,__key,key_size,EVP_sha256(),NULL)<0){ ret=ERROR_OpenSslSha256Init; returnret; } ret=__openssl_HMACsha256(&ctx,data,data_size,__digest,&digest_size); HMAC_CTX_cleanup(&ctx); if(ret!=ERROR_SUCCESS){ returnret; } } if(digest_size!=32){ ret=ERROR_OpenSslSha256DigestSize; returnret; } returnret; } #defineRFC2409_PRIME_1024 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" "FFFFFFFFFFFFFFFF" SrsDH::SrsDH() { pdh=NULL; } SrsDH::~SrsDH() { if(pdh!=NULL){ if(pdh->p!=NULL){ BN_free(pdh->p); pdh->p=NULL; } if(pdh->g!=NULL){ BN_free(pdh->g); pdh->g=NULL; } DH_free(pdh); pdh=NULL; } } intSrsDH::initialize(boolensure_128bytes_public_key) { intret=ERROR_SUCCESS; for(;;){ if((ret=do_initialize())!=ERROR_SUCCESS){ returnret; } if(ensure_128bytes_public_key){ int32_tkey_size=BN_num_bytes(pdh->pub_key); if(key_size!=128){ srs_warn("regenerate128Bkey,current=%dB",key_size); continue; } } break; } returnret; } intSrsDH::copy_public_key(char*pkey,int32_t&pkey_size) { intret=ERROR_SUCCESS; //copypublickeytobytes. //sometimes,thekey_sizeis127,seemsok. int32_tkey_size=BN_num_bytes(pdh->pub_key); srs_assert(key_size>0); //maybethekey_sizeis127,butdhwillwriteall128bytespkey, //so,donotneedtoset/initializethepkey. //@seehttps://github.com/winlinvip/simple-rtmp-server/issues/165 key_size=BN_bn2bin(pdh->pub_key,(unsignedchar*)pkey); srs_assert(key_size>0); //outputthesizeofpublickey. //@seehttps://github.com/winlinvip/simple-rtmp-server/issues/165 srs_assert(key_size<=pkey_size); pkey_size=key_size; returnret; } intSrsDH::copy_shared_key(constchar*p
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話(huà)語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉