当前位置: 首页 > 后端技术 > PHP

引入gRPC:基于CA的TLS证书认证

时间:2023-03-30 05:24:00 PHP

鍘熸枃鍦板潃锛氬紩鍏RPC锛氬熀浜嶤A鐨凾LS璇佷功璁よ瘉椤圭洰鍦板潃锛歨ttps://github.com/EDDYCJY/go...鍓嶈█鍦ㄤ笂涓€绔狅紝鎴戜滑闂簡涓€涓棶棰樸€傚嵆濡備綍淇濊瘉璇佷功鐨勫彲闈犳€у拰鏈夋晥鎬э紵浣犲浣曠‘淇濅綘鐨勬湇鍔″櫒鍜屽鎴风鐨勮瘉涔︽槸姝g‘鐨勶紵涓轰簡淇濊瘉璇佷功鐨勫彲闈犳€у拰鏈夋晥鎬э紝CA鍙互鍦ㄨ繖閲屽紩鍏A棰佸彂鐨勬牴璇佷功鐨勬蹇点€傜鍚圶.509鏍囧噯鏍硅瘉涔︺€傛牴璇佷功锛坮ootcertificate锛夋槸灞炰簬鏍硅瘉涔﹂鍙戞満鏋勶紙CA锛夌殑鍏挜璇佷功銆傛垜浠彲浠ラ€氳繃楠岃瘉CA鐨勭鍚嶆潵淇′换CA銆備换浣曚汉閮藉彲浠ヨ幏寰桟A鐨勮瘉涔︼紙鍖呮嫭鍏挜锛夋潵楠岃瘉瀹冮鍙戠殑璇佷功锛堝鎴风銆佹湇鍔″櫒锛夈€傚叾涓寘鍚殑鏂囦欢濡備笅锛歱ublickeykeyGenerateKeyopensslgenrsa-outca.key2048Generatekeyopensslreq-new-x509-days7200-keyca.key-outca.pem濉啓淇℃伅CountryName(2lettercode)[]锛氬窞鎴栫渷鍚嶇О锛堝叏鍚嶏級[]锛氬湴鏂瑰悕绉帮紙渚嬪鍩庡競锛塠]锛氱粍缁囧悕绉帮紙渚嬪鍏徃锛塠]锛氱粍缁囧崟浣嶅悕绉帮紙渚嬪閮ㄩ棬锛塠]锛氶€氱敤鍚嶇О锛堜緥濡?瀹屽叏鍚堟牸鐨勪富鏈哄悕)[]:go-grpc-exampleEmailAddress[]:ServergeneratesCSRopensslreq-new-keyserver.key-outserver.csr濉啓淇℃伅CountryName(2lettercode)[]:Stateor鐪佷唤鍚嶇О锛堝叏鍚嶏級[]锛氬湴鏂瑰悕绉帮紙渚嬪锛屽煄甯傦級[]锛氱粍缁囧悕绉帮紙渚嬪锛屽叕鍙革級[]锛氱粍缁囧崟浣嶅悕绉帮紙渚嬪锛岄儴闂級[]锛氶€氱敤鍚嶇О锛堜緥濡傦紝瀹屽叏闄愬畾鐨勪富鏈哄悕锛塠]:go-grpc-exampleEmailAddress[]:Pleaseenterthefollowing'extra'attributestobesendwithyourcertificaterequestAchallengepassword[]:CSR鏄疌erificateSigningRequest鐨勮嫳鏂囩缉鍐欙紝鏄竴涓瘉涔︾敵璇锋枃浠?涓昏浣滅敤鏄疌A浼氫娇鐢–SR鏂囦欢杩涜绛惧悕锛屼娇寰楁敾鍑昏€呮棤娉曚吉瑁呮垨绡℃敼鍘熷璇佷功銆傚熀浜嶤A鐨刼pensslx509-req-sha256-CAca.pem-CAkeyca.key-CAcreateserial-days3650-inserver.csr-outserver.pemClient鐢熸垚Keyopensslecparam-genkey-namesecp384r1-outclient.key鐢熸垚CSRopensslreq-new-keyclient.key-outclient.csr鏄熀浜嶤A棰佸彂鐨刼pensslx509-req-sha256-CAca.pem-CAkeyca銆俴ey-CAcreateserial-days3650-inclient.csr-outclient.pem鑷虫鎴戜滑鐢熸垚浜嗕竴鍫嗘枃浠讹紝璇锋寜濡備笅鐩綍缁撴瀯瀛樻斁锛?treeconfconf鈹溾攢鈹€ca.key鈹溾攢鈹€ca.pem鈹溾攢鈹€ca.srl鈹溾攢鈹€client鈹傗敎鈹€鈹€client.csr鈹傗敎鈹€鈹€client.key鈹傗敂鈹€鈹€client.pem鈹斺攢鈹€server鈹溾攢鈹€server.csr鈹溾攢鈹€server.key鈹斺攢鈹€server浠撳簱涓繕鏈夊叾浠栦笉搴斿嚭鐜扮殑.pem鏂囦欢锛屽簲淇濆瘑鎴栧垹闄ゃ€備絾鏄负浜嗙湡姝g殑婕旂ず锛屾垜淇濈暀浜嗭紙鏁查粦鏉匡級gRPC锛岀劧鍚庢寮忓紑濮媑RPC鐨勭紪鐮侊紝鏀归€犱簡涓婁竴绔犵殑浠g爜銆傜洰鏍囨槸鍩轰簬CA杩涜TLS璁よ瘉馃かServerpackagemainimport("context""log""net""crypto/tls""crypto/x509""io/ioutil""google.golang.org/grpc""google.golang.org/grpc/credentials"pb"github.com/EDDYCJY/go-grpc-example/proto")...constPORT="9001"funcmain(){cert,err:=tls.LoadX509KeyPair("../../conf/server/server.pem","../../conf/server/server.key")iferr!=nil{log.Fatalf("tls.LoadX509KeyPairerr:%v",err)}certPool:=x509.NewCertPool()ca,err:=ioutil.ReadFile("../../conf/ca.pem")濡傛灉閿欒锛?nil{log.Fatalf("ioutil.ReadFileerr:%v",err)}濡傛灉姝e父:=certPool.AppendCertsFromPEM(ca);!ok{log.Fatalf("certPool.AppendCertsFromPEMerr")}c:=credentials.NewTLS(&tls.Config{Certificates:[]tls.Certificate{cert},ClientAuth:tls.RequireAndVerifyClientCert,ClientCAs:certPool,})鏈嶅姟鍣?=grpc.NewServer(grpc.Creds(c))pb.RegisterSearchServiceServer(server,&SearchService{})lis,err:=net.Listen("tcp",":"+PORT)iferr!=nil{log.Fatalf("net.Listen閿欒:%v",閿欒)}server.Serve(lis)}tls.LoadX509KeyPair()锛氫粠璇佷功鐩稿叧鏂囦欢涓鍙栧苟瑙f瀽淇℃伅锛岃幏鍙栬瘉涔﹀叕閽ュ拰瀵嗛挜瀵筬uncLoadX509KeyPair(certFile,keyFilestring)(Certificate,error){certPEMBlock,err:=ioutil.ReadFile(certFile)iferr!=nil{returnCertificate{},err}keyPEMBlock,err:=ioutil.ReadFile(keyFile)iferr!=nil{returnCertificate{},err}杩斿洖X509KeyPair(certPEMBlock,keyPEMBlock)}x509.NewCertPool()锛氬垱寤轰竴涓柊鐨勭┖CertPoolcertPool.AppendCertsFromPEM()锛氬皾璇曡В鏋愪紶鍏ョ殑PEM缂栫爜璇佷功銆傚鏋滆В鏋愭垚鍔燂紝灏嗘坊鍔犲埌CertPool涓紝渚涗互鍚庝娇鐢ㄥ嚟鎹€侼ewTLS锛氭瀯寤哄熀浜嶵LS鐨凾ransportCredentials閫夐」tls.Config锛欳onfig缁撴瀯鐢ㄤ簬鍦⊿erver涓婇厤缃甌LS瀹㈡埛绔垨鏈嶅姟鍣ㄣ€備竴鍏变娇鐢ㄤ簡涓変釜Config閰嶇疆椤癸細(1)Certificates锛氳缃瘉涔﹂摼锛屽厑璁镐竴涓垨澶氫釜(2)ClientAuth锛氶渶瑕侀獙璇佸鎴风鐨勮瘉涔︺€傚彲浠ユ牴鎹疄闄呮儏鍐甸€夋嫨浠ヤ笅鍙傛暟锛歝onst(NoClientCertClientAuthType=iotaRequestClientCertRequireAnyClientCertVerifyClientCertIfGivenRequireAndVerifyClientCert)(3)ClientCAs锛氳缃牴璇佷功鐨勯泦鍚堬紝楠岃瘉鏂瑰紡浣跨敤ClientAuthClientpackagemainimport("context""crypto/tls""crypto/x509""io/ioutil""log""google.golang.org/grpc""google.golang.org/grpc/credentials"pb"github.com/EDDYCJY/go-grpc-example/proto")constPORT="9001"funcmain(){cert,err:=tls.LoadX509KeyPair("../../conf/client/client.pem","../../conf/client/client.key")iferr!=nil{log.Fatalf("tls.LoadX509KeyPairerr:%v",err)}certPool:=x509.NewCertPool()ca,err:=ioutil.ReadFile("../../conf/ca.pem")iferr!=nil{log.Fatalf("ioutil.ReadFileerr:%v",err)}ifok:=certPool.AppendCertsFromPEM(ca);!ok{log.Fatalf("certPool.AppendCertsFromPEMerr")}c:=credentials.NewTLS(&tls.Config{Certificates:[]tls.Certificate{cert},ServerName:"go-grpc-example",RootCAs:certPool,})conn,err:=grpc.Dial(":"+PORT,grpc.WithTransportCredentials(c))濡傛灉err!=nil{log.Fatalf("grpc.Dialerr:%v",err)}deferconn.Close()client:=pb.NewSearchServiceClient(conn)resp,err:=client.Search(context.Background(),&pb.SearchRequest{Request:"gRPC",})iferr!=nil{log.Fatalf("client.Searcherr:%v",err)}log.Printf("resp:%s",resp.GetResponse())}涓嶤lient涓殑Server澶ч儴鍒嗘槸涓€鑷寸殑锛屼笉鍚岀殑鏄綋Client璇锋眰Server鏃讹紝Client浼氫娇鐢ㄦ牴璇佷功鍜孲erverName鏉ラ獙璇丼erver銆傜畝鍗曠殑杩囩▼澶ц嚧濡備笅锛氬鎴风閫氳繃璇锋眰鏈嶅姟鍣ㄧ璇佷功浣跨敤CA璁よ瘉鐨勬牴璇佷功楠岃瘉鏈嶅姟鍣ㄧ璇佷功鐨勫彲闈犳€у拰鏈夋晥鎬ч獙璇丼erverName鏄惁鍙敤鍜屾湁鏁堝綋鐒讹紝濡傛灉tls.璁剧疆浜哛equireAndVerifyClientCert鏂瑰紡锛屾湇鍔$涔熶細浣跨敤CA璁よ瘉鐨勬牴璇佷功鏉ラ獙璇佸鎴风璇佷功鐨勫彲闈犳€у拰鏈夋晥鎬э紝鍗冲弻鏂归兘浼氶獙璇侊紝鏋佸ぇ鐨勪繚璇佷簡瀹夊叏鎬с€傪煈嶉獙璇侀噸鍚痵erver.go锛屾墽琛宑lient.go锛屾鏌ュ搷搴旂粨鏋滄槸鍚︽甯告€荤粨鏈珷鎴戜滑浣跨敤CA棰佸彂鐨勬牴璇佷功鏉ラ鍙戝鎴风鍜屾湇鍔$璇佷功銆傝繘涓€姝ユ彁楂樹袱鑰呬箣闂寸殑閫氫俊瀹夊叏杩欎笅鍙湡鏄ぇ鍔熷憡鎴愬暒锛佸弬鑰冩湰绯诲垪绀轰緥浠g爜銆俫o-grpc-example绯诲垪鐩綍寮曞叆gRPC锛歡RPC鍙婄浉鍏充粙缁嶅紩鍏RPC锛歡RPCClientandServer寮曞叆gRPC锛歡RPCStreaming,ClientandServer寮曞叆gRPC锛歍LS璇佷功璁よ瘉寮曞叆gRPC锛氬熀浜嶤A鐨凾LS璇佷功璁よ瘉寮曞叆寮曞叆gRPC锛歎naryandStreaminterceptor寮曞叆gRPC锛氳浣犵殑鏈嶅姟鍚屾椂鎻愪緵HTTP鎺ュ彛寮曞叆gRPC锛氬RPC鏂规硶鍋氳嚜瀹氫箟璁よ瘉寮曞叆gRPC锛歡RPCDeadlines寮曞叆gRPC锛氬垎甯冨紡閾捐矾杩借釜gRPC+Opentracing+Zipkin