当前位置:首页 > 芯闻号 > 充电吧
[导读] 当服务器和客户端的握手是按照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
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

近日,一则有关“砺算科技濒临破产”的消息在业内不胫而走。虽然东芯股份有意收购其40%的股权,帮助砺算科技渡过难关,但这一投资事项能否最终完成仍存在不确定性。

关键字: GPU

May 14, 2024 ---- TrendForce集邦咨询研究最新显示,OLED桌上型显示器(Monitor)2024年第一季出货总量约为20万台,年成长率121%。第二季在品牌新机陆续上市后,当季成长幅度预估将达...

关键字: OLED 显示器

业内消息,近日日本软件银行集团(SoftBank Group)旗下安谋国际科技公司(Arm)计划研发人工智能(AI)芯片,先成立一个AI芯片部门,目标是明年春季建立AI芯片原型产品,然后将量产工作交由代工厂制造,预估20...

关键字: ARM AI芯片

《芯片与科学法案》(CHIPS)为美国芯片研究、开发、制造和劳动力发展提供了527亿美元的资助。

关键字: 美国芯片法案 芯片与科学法案 芯片

援引彭博社消息,近日新当选的熊本县知事木村隆(Takashi Kimura)表示,他已准备好确保获得广泛的支持,以吸引台积电在当地建立第三家日本芯片工厂。

关键字: 日本 台积电 芯片工厂

5 月 13 日消息,从“上海临港”微信公众号获悉,特斯拉上海储能超级工厂建设项目已完成施工许可证核发。这是特斯拉在美国本土以外的首个储能超级工厂项目,工厂计划于今年 5 月开工,明年一季度实现量产。

关键字: 特斯拉 储能

据消息源 jasonwill101 透露,高通公司目前正在重新设计骁龙 8 Gen 4 处理器,新的目标频率为 4.26GHz,这一变化主要是为了应对苹果 M4 / A18 / Pro 处理器。

关键字: 高通 骁龙 8 Gen 4 芯片

最新消息,今天凌晨 OpenAI 在春季更新直播官宣发布最新旗舰生成式 AI 模型 GPT-4o,GPT-4o 将 ChatGPT 变成一名带有文本、「视觉」与语音互动的实时语音助手。OpenAI 表示升级版的 Chat...

关键字: OpenAI 生成式 AI大模型 GPT-4o

三星电子最近进行了重大的组织重组,以增强其在下一代机器人业务方面的能力,并将其视为关键增长领域。作为重组的一部分,该公司解散了负责开发三星首款可穿戴机器人“Bot Fit”的机器人业务团队。

关键字: 三星电子 解散 Bot Fit 机器人

NAS这些年可吸引了不少数码发烧友的注意,但也渐渐在家庭用户中风靡。究其原因,大概还是因为太多人因为现在数据过于庞大,而一个NAS基本上就能解决一个家庭的数据存储难题。在这一背景下,铁威马F4-424 Pro凭借其出色的...

关键字: NAS 数据存储 处理器
关闭
关闭