当前位置:首页 > 芯闻号 > 充电吧
[导读] 当服务器和客户端的握手是按照rtmp协议进行,是不支持h264/aac的,有数据,就是没有视频和声音。 原因是adobe变更了握手的数据结构,标准rtmp协议的握手的包是随机的1536字节(S

当服务器和客户端的握手是按照rtmp协议进行,是不支持h264/aac的,有数据,就是没有视频和声音。

原因是adobe变更了握手的数据结构,标准rtmp协议的握手的包是随机的1536字节(S1S2C1C2),变更后的是需要进行摘要和加密。

rtmp协议定义的为simple handshake,变更后加密握手可称为complex handshake。

本文详细分析了rtmpd(ccrtmpserver)中的处理逻辑,以及rtmpdump的处理逻辑,从一个全是魔法数字的世界找到他们的数据结构和算法。

complex handshake C1S1结构

complex handshake将C1S1分为4个部分,它们的顺序(schema)一种可能是:

[plain]view plaincopy //c1s1schema0 time:4bytes version:4bytes key:764bytes digest:764bytes 其中,key和digest可能会交换位置,即schema可能是:

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

客户端来决定使用哪种schema,服务器端则需要先尝试按照schema0解析,失败则用schema1解析。如下图所示:


无论key和digest位置如何,它们的结构是不变的:

[plain]view plaincopy //764byteskey结构 random-data:(offset)bytes key-data:128bytes random-data:(764-offset-128-4)bytes offset:4bytes //764bytesdigest结构 offset:4bytes random-data:(offset)bytes digest-data:32bytes random-data:(764-4-offset-32)bytes 备注:发现FMS只认识digest-key结构。

如下图所示:



crtmp中这些全是魔法数字。

complex handshake C2S2结构

C2S2主要是提供对C1S1的验证。结构如下:

[plain]view plaincopy //1536bytesC2S2结构 random-data:1504bytes digest-data:32bytes

C2S2的结构相对比较简单。如下图所示:


下面介绍C1S1C2S2的生成以及验证算法。

complex handshake C1S1算法

C1S1中都是包含32字节的digest,而且digest将C1S1分成两部分:

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

如下图所示:


在生成C1时,需要用到c1s1-part1和c1s1-part2这两个部分的字节拼接起来的字节,定义为:

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

也就是说,把1536字节的c1s1中的32字节的digest拿剪刀剪掉,剩下的头和尾加在一起就是c1s1-joined。

用到的两个常量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) 验证的算法是一样的。

代码实现

[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
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭