草庐IT

go - 未能在 grpc 上完成安全握手?

coder 2023-07-01 原文

我已经多次更改服务器和客户端上的端口号,但服务器总是获取不正确的端口号。

当我执行客户端时,服务器将记录如下: 2017/05/07 15:06:07 grpc:Server.Serve 无法完成来自“127.0.0.1:32763”的安全握手:远程错误:tls:证书错误 在客户端,我得到了这个: 2017/05/07 15:06:07 无法调用本地主机:8070:连接错误:desc =“传输:x509:证书对任何名称均无效,但希望匹配本地主机:8070”;请重试。 rpc 错误:code = Internal desc = connection error:desc = "transport: x509: certificate is not valid for any names, but wanted to match localhost:8070"

我有 server.go 的这段代码

func serve() {
    addr := "localhost:8070"
    crt, key := certificate.CreatePemKey()
    certificate, err := tls.X509KeyPair(crt, key)
    if err != nil {
        fmt.Println(err)
    }

    certPool := x509.NewCertPool()
    ca, err := ioutil.ReadFile("F:/GIAG3.crt")
    if err != nil {
        fmt.Println(err)
    }

    if ok := certPool.AppendCertsFromPEM(ca); !ok {
        fmt.Println("unable to append certificate")
    }

    lis, err := net.Listen("tcp", addr)
    if err != nil {
        fmt.Println("could not list on %s: %s", addr, err)
    }

    // Create the TLS credentials
    creds := credentials.NewTLS(&tls.Config{
        ClientAuth:   tls.RequireAndVerifyClientCert,
        Certificates: []tls.Certificate{certificate},
        ClientCAs:    certPool,
    })

    srv := grpc.NewServer(grpc.Creds(creds))
    pb.RegisterPingerServer(srv, &server{})

    if err := srv.Serve(lis); err != nil {
        fmt.Println("grpc serve error: %s", err)
    }
}

这是给客户端的.go

func testDial2() {
    addr := "localhost:8070"
    crt, key := certificate.CreatePemKey()
    certificate, err := tls.X509KeyPair(crt, key)
    if err != nil {
        fmt.Println(err)
    }

    certPool := x509.NewCertPool()
    ca, err := ioutil.ReadFile("F:/GIAG3.crt")
    if err != nil {
        fmt.Println(err)
    }

    if ok := certPool.AppendCertsFromPEM(ca); !ok {
        fmt.Println("unable to append certificate")
    }

    creds := credentials.NewTLS(&tls.Config{
        ServerName:   addr,
        Certificates: []tls.Certificate{certificate},
        RootCAs:      certPool,
    })

    conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(creds))
    if err != nil {
        fmt.Println(err)
    }

    defer conn.Close()
    c := pb.NewPingerClient(conn)
    r, err := c.Ping(context.Background(), &pb.Payload{Message: "Ping"})
    if err != nil {
        fmt.Println(err)
    }
    log.Printf("%s", r.Message)
}

这是针对 CreatePemKey 的,它基于此示例 https://golang.org/src/crypto/tls/generate_cert.go

func publicKey(priv interface{}) interface{} {
    switch k := priv.(type) {
    case *rsa.PrivateKey:
        return &k.PublicKey
    case *ecdsa.PrivateKey:
        return &k.PublicKey
    default:
        return nil
    }
}

func pemBlockForKey(priv interface{}) *pem.Block {
    switch k := priv.(type) {
    case *rsa.PrivateKey:
        return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
    case *ecdsa.PrivateKey:
        b, err := x509.MarshalECPrivateKey(k)
        if err != nil {
            fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err)
            os.Exit(2)
        }
        return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
    default:
        return nil
    }
}

func CreatePemKey() (certpem, keypem []byte) {
    priv, _ := rsa.GenerateKey(rand.Reader, 2048)
    notBefore := time.Now()
    notAfter := notBefore.AddDate(1, 0, 0)
    serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
    serialNumber, _ := rand.Int(rand.Reader, serialNumberLimit)

    template := x509.Certificate{
        SerialNumber: serialNumber,
        Subject: pkix.Name{
            Organization: []string{"Acme Co"},
        },
        NotBefore:             notBefore,
        NotAfter:              notAfter,
        KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
        ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
        BasicConstraintsValid: true,
    }
    // template.IPAddresses = append(template.IPAddresses, net.ParseIP("localhost"))
    template.IsCA = true
    derbytes, _ := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
    certpem = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derbytes})
    keypem = pem.EncodeToMemory(pemBlockForKey(priv))
    return certpem, keypem
}

顺便说一句,GIAG3.crt 来自这里 https://pki.goog/

请帮帮我,谢谢

最佳答案

如果您的服务器证书没有域定义并且没有由 GIAG3 签名(如您的示例),您应该添加 InsecureSkipVerify(这允许您跳过服务器名称和服务器证书),这将解决无效名称的问题。

creds := credentials.NewTLS(&tls.Config{
    ServerName:   addr,
    Certificates: []tls.Certificate{certificate},
    RootCAs:      certPool,
    InsecureSkipVerify: true,
})

但是你会遇到另一个问题,因为客户端使用的是自签名证书,而服务器需要 GIAG3 签名的证书来进行身份验证 (tls.RequireAndVerifyClientCert),所以你有一些选项,

  • 您使用 GIAG3 为客户端签名的证书。
  • 将身份验证类型减少为tls.RequireAnyClientCert,这允许您在身份验证时使用任何证书(它可以由 GIAG3 签名或不签名),客户端只需要使用任何证书连接时。
  • 删除带有证书的客户端身份验证。

关于go - 未能在 grpc 上完成安全握手?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43829022/

有关go - 未能在 grpc 上完成安全握手?的更多相关文章

  1. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  2. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  3. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

  4. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  5. ruby-on-rails - 安全地显示使用回形针 gem 上传的图像 - 2

    默认情况下:回形针gem将所有附件存储在公共(public)目录中。出于安全原因,我不想将附件存储在公共(public)目录中,所以我将它们保存在应用程序根目录的uploads目录中:classPost我没有指定url选项,因为我不希望每个图像附件都有一个url。如果指定了url:那么拥有该url的任何人都可以访问该图像。这是不安全的。在user#show页面中:我想实际显示图像。如果我使用所有回形针默认设置,那么我可以这样做,因为图像将在公共(public)目录中并且图像将具有一个url:Someimage:看来,如果我将图像附件保存在公共(public)目录之外并且不指定url(同

  6. Ruby:行 "m = Hash.new {|h,k| h[k] = []}"完成了什么而 "Hash.new"没有完成? - 2

    一边学习thisRailscast我从Rack中看到了以下源代码:defself.middleware@middleware||=beginm=Hash.new{|h,k|h[k]=[]}m["deployment"].concat[[Rack::ContentLength],[Rack::Chunked],logging_middleware]m["development"].concatm["deployment"]+[[Rack::ShowExceptions],[Rack::Lint]]mendend我的问题是关于第三行。什么是传递block{|h,k|h[k]=[]}到Has

  7. ruby - 使写入文件线程安全 - 2

    我在一个ruby​​文件中有一个函数可以像这样写入一个文件File.open("myfile",'a'){|f|f.puts("#{sometext}")}这个函数在不同的线程中被调用,使得像上面这样的文件写入不是线程安全的。有谁知道如何以最简单的方式使这个文件写入线程安全?更多信息:如果重要的话,我正在使用rspec框架。 最佳答案 您可以通过File#flock给锁File.open("myfile",'a'){|f|f.flock(File::LOCK_EX)f.puts("#{sometext}")}

  8. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  9. ruby-on-rails - 最灵活的 Rails 密码安全实现 - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭8年前。Improvethisquestion我需要实现具有各种灵活需求的密码安全。这些要求基本上取自Sanspasswordpolicy:Strongpasswordshavethefollowingcharacteristics:Containatleastthreeofthe

  10. 常见网络安全产品汇总(私信发送思维导图) - 2

    安全产品安全网关类防火墙Firewall防火墙防火墙主要用于边界安全防护的权限控制和安全域的划分。防火墙•信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。防火墙是一个由软件和硬件设备组合而成,在内外网之间、专网与公网之间的界面上构成的保护屏障。下一代防火墙•下一代防火墙,NextGenerationFirewall,简称NGFirewall,是一款可以全面应对应用层威胁的高性能防火墙,提供网络层应用层一体化安全防护。生产厂家•联想网御、CheckPoint、深信服、网康、天融信、华为、H3C等防火墙部署部署于内、外网编辑额,用于权限访问控制和安全域划分。UTM统一威胁管理(Un

随机推荐