乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Akka-CQRS(13)- SSL/TLS for gRPC and HTTPS:自簽名證書產(chǎn)生和使用

       印度阿三17 2019-06-24

        到現(xiàn)在,我們已經(jīng)完成了POS平臺和前端的網(wǎng)絡(luò)集成。不過,還是那句話:平臺系統(tǒng)的網(wǎng)絡(luò)安全是至關(guān)重要的。前一篇博客里我們嘗試實現(xiàn)了gRPC ssl/tls網(wǎng)絡(luò)連接,但測試時用的證書如何產(chǎn)生始終沒有搞清楚。現(xiàn)在akka-http開發(fā)的ws同樣面臨HTTPS的設(shè)置和使用問題。所以,特別抽出這篇博文討論一下數(shù)字證書的問題。

      在正式的生產(chǎn)環(huán)境里數(shù)字證書應(yīng)該是由第三方公證機構(gòu)CA簽發(fā)的,我們需要向CA提出申請。數(shù)字證書的申請、簽發(fā)和驗證流程如下:

      1) 服務(wù)? S 向第三?方機構(gòu)CA提交公鑰、組織信息、個?信息(域名)等資料提出認(rèn)證申請 (不需要提供私鑰)
      
      2) CA 通過各種手段驗證申請者所提供信息的真實性,如組織是否存在、 企業(yè)是否合法,是否擁有域名的所有權(quán)等
      
      3) 如信息審核通過,CA 會向申請者簽發(fā)認(rèn)證文件-證書。 證書包含以下信息:申請者公鑰、申請者的組織信息和個?信息、簽發(fā)機構(gòu) CA 信息、有效時間、證書序列號等信息的明?,同時包含一個簽名的產(chǎn)?生算法:首先,使用散列函數(shù)計算出證書中公開明文信息的信息摘要,然后, 采用 CA 的私鑰對信息摘要進?加密,這個密?就是簽名了
      
      4) 客戶端 C 向服務(wù)器 S 發(fā)出請求時,S 返回證書文件
      
      5) 客戶端 C 讀取證書中的相關(guān)的明?信息,采?相同的散列函數(shù)計算得到信息摘要, 然后,利用對應(yīng) CA 的公鑰解密簽名數(shù)據(jù),對比證書的信息摘要,如果一致,則可以確認(rèn)證書的合法性,即公鑰合法
      
      6) 客戶端 C 然后檢驗證書相關(guān)的域名信息、有效時間等信息
      
      7) 客戶端 C 應(yīng)內(nèi)置信任 CA 的證書信息(包含公鑰),如果 CA 不被信任,則找不到對應(yīng) CA 的證書,證書也會被判定非法
      
      8) 內(nèi)置 CA 對應(yīng)的證書稱為根證書,頒發(fā)者和使?者相同,用 CA ??的私鑰簽名,即?簽名證書(此證書中的公鑰即為 CA 的公鑰,可以使用這個公鑰對證書的簽名進行校驗,?需另外?份證書)

      服務(wù)器端在通信中建立SSL加密渠道過程如下:

      1)客戶端 C 發(fā)送請求到服務(wù)器端 S
      
      2) 服務(wù)器端 S 返回證書和公開密鑰到 C,公開密鑰作為證書的一部分傳送
      
      3)客戶端 C 檢驗證書和公開密鑰的有效性,如果有效,則?成共享密鑰并使?公開密鑰加密發(fā)送到服務(wù)器端 S
      
      4) 服務(wù)器端 S 使?私有密鑰解密數(shù)據(jù),并用收到的共享密鑰加密數(shù)據(jù),發(fā)送到客戶端 C 
      
      5) 客戶端 C 使?用共享密鑰解密數(shù)據(jù)
      
      6) SSL 加密通信渠道建立 ...

      應(yīng)該說,需要在客戶端進行認(rèn)證的應(yīng)用場景不多。這種情況需要在客戶端存放數(shù)字證書。像支付寶和一些銀行客戶端一般都需要安裝證書。

      好了,還是回到如何產(chǎn)生自簽名證書示范吧。下面是一個標(biāo)準(zhǔn)的用openssl命令產(chǎn)生自簽名證書流程:

      在產(chǎn)生證書和密鑰的過程中所有系統(tǒng)提問回答要一致。我們先假設(shè)密碼統(tǒng)一為:123456

      1、生成根證書私鑰: rootCA.key:  openssl genrsa -des3 -out rootCA.key 2048 

      2、根證書申請 rootCA.csr:openssl req -new -key rootCA.key -out rootCA.csr

      3、用申請rootCA.csr生成根證書 rootCA.crt:openssl x509 -req -days 365 -sha256 -extensions v3_ca -signkey rootCA.key -in rootCA.csr -out rootCA.crt

      4、pem根證書 rootCA.pem:openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem

      5、創(chuàng)建?個v3.ext?件,目的是產(chǎn)生X509 v3證書,主要目的是指定subjectAltName選項:

        authorityKeyIdentifier=keyid,issuer
        basicConstraints=CA:FALSE
        keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
        subjectAltName = @alt_names
        [alt_names]
        DNS.1 = localhost
        IP.1 = "192.168.11.189"  
        IP.5 = "192.168.0.189"
        IP.2 = "132.232.229.60"
        IP.3 = "118.24.165.225"
        IP.4 = "129.28.108.238"

      注意subjectAltName,這些都是可以信任的域名或地址。

      6、構(gòu)建證書密鑰 server.key:openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key

      7、用根證書rootCA產(chǎn)生自簽證書 server.crt:openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 500 -sha256 -extfile v3.ext

      上面這個過程需要不斷重復(fù)回答同樣的問題,很煩??梢杂门渲梦募硪淮涡援a(chǎn)生:

      先構(gòu)建一個ssl.cnf文件:

        [req]
        prompt = no
        default_bits = 4096
        default_md = sha256
        distinguished_name = dn
        x509_extensions = v3_req
        [dn]
        C=CN
        ST=GuangDong
        L=ShenZhen
        O=Bayakala
        OU=POS
        CN=www.bayakala.com
        emailAddress=admin@localhost
        [v3_req]
        keyUsage=keyEncipherment, dataEncipherment
        extendedKeyUsage=serverAuth
        subjectAltName=@alt_names
        [alt_names]
        DNS.1 = localhost
        IP.1 = "192.168.11.189"  
        IP.5 = "192.168.0.189"
        IP.2 = "132.232.229.60"
        IP.3 = "118.24.165.225"
        IP.4 = "129.28.108.238"

      然后:openssl req -new -newkey rsa:2048 -sha1 -days 3650 -nodes -x509 -keyout server.key -out server.crt -config ssl.cnf

      一個指令同時產(chǎn)生需要的server.crt,server.key。

      除aubjectAltName外還要關(guān)注CN這個字段,它就是我們經(jīng)常會遇到系統(tǒng)提問:你確定信任“域名”嗎?中這個域名,也就是對外界開放的一個使用了數(shù)字證書的域名。

      把crt,key抄寫到main/resources目錄下,然后在gRPC服務(wù)器配置證書:

      trait gRPCServer {
        
        val serverCrtFile = new File(getClass.getClassLoader.getResource("server.crt").getPath)
        val serverKeyFile = new File(getClass.getClassLoader.getResource("server.key").getPath)
      
        def runServer(service: ServerServiceDefinition): Unit = {
          val server = NettyServerBuilder
            .forPort(50051)
            .addService(service)
            .useTransportSecurity(serverCrtFile,serverKeyFile)
            .build
            .start
          // make sure our server is stopped when jvm is shut down
          Runtime.getRuntime.addShutdownHook(new Thread() {
            override def run(): Unit = {
              server.shutdown()
              server.awaitTermination()
            }
          })
        }
      
      }

      啟動gRPC服務(wù),運作正常。在看看客戶端代碼:

          val clientCrtFile = new File(getClass.getClassLoader.getResource("server.crt").getPath)
       //或者   val clientCrtFile = new File(getClass.getClassLoader.getResource("rootCA.pem").getPath)
      
      //這樣也行 val clientCrtFile: InputStream = getClass.getClassLoader.getResourceAsStream("rootCA.pem")
      
          val sslContextBuilder = GrpcSslContexts.forClient().trustManager(clientCrtFile)
      
          //build connection channel
          val channel = NettyChannelBuilder
            .forAddress("192.168.11.189",50051)
            .negotiationType(NegotiationType.TLS)
            .sslContext(sslContextBuilder.build())
      //      .overrideAuthority("192.168.1.3")
            .build()

      測試連接,gRPC SSL/TLS成功!

      現(xiàn)在開始了解一下https證書的配置使用方法吧??戳艘幌耡kka-http關(guān)于server端HTTPS設(shè)置的例子,證書是嵌在HttpsConnectionContext類型里面的。還有就是akka-http使用的https證書格式只支持pkcs12,所以需要把上面用openssl產(chǎn)生的自簽名證書server.crt轉(zhuǎn)成server.p12。這個轉(zhuǎn)換又需要先產(chǎn)生證書鏈certificate-chain chain.pem:

      1)產(chǎn)生certificate-chain:  cat server.crt rootCA.crt > chain.pem

      2) server.crt轉(zhuǎn)換成server.p12: openssl pkcs12 -export -name servercrt -in chain.pem -inkey server.key -out server.p12

      https server 測試代碼:

      //#imports
      import java.io.InputStream
      import java.security.{ SecureRandom, KeyStore }
      import javax.net.ssl.{ SSLContext, TrustManagerFactory, KeyManagerFactory }
      
      import akka.actor.ActorSystem
      import akka.http.scaladsl.server.{ Route, Directives }
      import akka.http.scaladsl.{ ConnectionContext, HttpsConnectionContext, Http }
      import akka.stream.ActorMaterializer
      import akka.http.scaladsl.Http
      import akka.http.scaladsl.server.Directives._
      
      //#imports
      
      
      object HttpsDemo extends App {
      
        implicit val httpSys = ActorSystem("httpSystem")
        implicit val httpMat = ActorMaterializer()
        implicit val httpEC = httpSys.dispatcher
        
      
          val password: Array[Char] = "123456".toCharArray // do not store passwords in code, read them from somewhere safe!
      
          val ks: KeyStore = KeyStore.getInstance("PKCS12")
          val keystore: InputStream = getClass.getClassLoader.getResourceAsStream("server.p12")
          ks.load(keystore, password)
      
          val keyManagerFactory: KeyManagerFactory = KeyManagerFactory.getInstance("SunX509")
          keyManagerFactory.init(ks, password)
      
          val tmf: TrustManagerFactory = TrustManagerFactory.getInstance("SunX509")
          tmf.init(ks)
      
          val sslContext: SSLContext = SSLContext.getInstance("TLS")
          sslContext.init(keyManagerFactory.getKeyManagers, tmf.getTrustManagers, new SecureRandom)
          val https: HttpsConnectionContext = ConnectionContext.https(sslContext)
      
      
        val route = get { complete("Hello world!") }
      
        val (port, host) = (50081,"192.168.11.189")
      
        val bindingFuture = Http().bindAndHandle(route,host,port,connectionContext = https)
      
        println(s"Https Server running at $host $port. Press any key to exit ...")
      
        scala.io.StdIn.readLine()
      
      
        bindingFuture.flatMap(_.unbind())
          .onComplete(_ => httpSys.terminate())
      
      }

      用safari連接https://192.168.11.189:50081/, 彈出窗口一堆廢話后還是成功連接上了。

      來源:https://www./content-4-263401.html

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多