正确处理Node.js TLS服务器和C TLS客户端(openSSL)连接的方法

am3

目标:客户端应将数据发送到受信任的服务器(通过自签名证书),并且服务器应相同。

我正在运行Node.js TLS服务器,并且有许多嵌入式客户端,它们在C中运行openSSL TLS客户端。我已经完成了整个设置,可以看到数据已加密(通过Wireshark),但是我不相信自己以正确的方式(尤其是我处理证书的方式)进行操作。

到目前为止我有什么

  1. 在服务器上,我生成了2048个私钥(private-key.pem)和一个自签名证书(public-cert.pem)
  2. 将自签名证书(public-cert.pem)复制到客户端

Node.js服务器代码段

var tls = require('tls');
var fs = require('fs');

var options = {
    key: fs.readFileSync('private-key.pem'),
    cert: fs.readFileSync('public-cert.pem')
};
tls.createServer(options, function (socket) {

socket.on('data', function(data) {
    // do something
});

socket.on('close', function() {
    socket.destroy();
});

}).listen(PORT);

C客户端代码段

     SSL_library_init(); 
     SSL_load_error_strings();
     ERR_load_BIO_strings();
     OpenSSL_add_all_algorithms();

     // create new context object
     ctx = SSL_CTX_new(TLSv1_2_client_method());

    //load trust cert

    if(! SSL_CTX_load_verify_locations(ctx, "public-cert.pem", NULL)){

          printf("sslInitialize() Error: Cannot load certificate\n");
          ERR_print_errors_fp(stderr);

          if(ctx != NULL) {

            SSL_CTX_free(ctx);

          }


          return;
    } 

    bio = BIO_new_ssl_connect(ctx);

    BIO_get_ssl(bio, & ssl);


    if (ssl == NULL) {

         printf("sslInitialize() Error: Can't locate SSL pointer\n");
         ERR_print_errors_fp(stderr);

         if(ctx != NULL){

            SSL_CTX_free(ctx);

        } 


        if(bio != NULL){

         BIO_free_all(bio);

        }
         return;
    }

    BIO_set_conn_hostname(bio, HOST);

   int connectStatus;                            

   if((connectStatus = BIO_do_connect(bio)) <= 0) {

    printf("Connect Status: %d",connectStatus);
     printf("sslInitialize() Error: Cannot connect to server\n");
     ERR_print_errors_fp(stderr);

    sslCloseConnection();

     return;
   }

观察结果

  1. 我将客户端上的证书更改为相同的随机证书,并且仍然可以使用(ServerHello TLS握手期间服务器发送的证书和使用SSL_CTX_load_verify_locations()加载的客户端的证书不同)。这使我想知道客户端如何信任证书。我该如何解决呢?
  2. 到目前为止,我已经以客户端验证服务器(尽管它无法正常工作)并发送数据并且服务器盲目地接受它的方式进行了设置。如何使客户端发送证书(由客户端自行签名),并且服务器仅在文件中包含该特定证书的情况下才接受该证书。
  3. 在客户端,我使用SSL_CTX_load_verify_locations(ctx, cert, NULL)该文件说

指定ctx的位置,用于验证的CA证书位于该位置。通过CAfile和CApath可用的证书是受信任的。

这是否意味着客户端ServerHello将根据TLS握手消息中收到的证书对它进行检查如果是这样,我应该调用另一个函数来执行此检查吗?

  1. 和往常一样,在问这个问题之前,我已经在线浏览了很多资源(SO帖子和openSSL手册页)。Node.js_TLSOpenSSL的SO_1二氧化硫仅举几例。我还省略了头文件和其他样板代码。

任何帮助将不胜感激。谢谢!

卡斯塔利亚天气

对于C客户端,您可能希望通过显式调用OpenSSL的函数确保客户端正在验证服务器证书SSL_CTX_set_verify()

SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);

打电话之前BIO_new_ssl_connect()请注意,这可能不是必需的。

是的,您通过设置的证书SSL_CTX_load_verify_locations()是用于验证服务器证书的证书(属于的一部分ServerHello)。根据这些验证证书检查服务器证书是默认的OpenSSL验证回调的一部分。

每对的NodeJS TLScreateServer文档,您可能需要提供一对夫妇为你的TLS服务器更多的选择,特别是ca阵列requestCertrejectUnauthorized布尔值:

var options = {
    key: fs.readFileSync('private-key.pem'),
    cert: fs.readFileSync('public-cert.pem'),
    ca: [ fs.readFileSync('ca-cert.pem') ],
    requestCert: true,
    rejectUnauthorized: true
};
tls.createServer(options, function (socket) {

requestCert布尔指示服务器请求客户端的证书。在TLS中,服务器必须向客户端明确请求证书;除非服务器要求,否则客户端不会提供一个。如果不设置rejectUnauthorizedtrue,您的TLS服务器将请求证书,但忽略任何验证错误并允许连接继续进行,这是不希望的。然后,ca阵列配置验证证书列表(类似于SSL_CTX_load_verify_locations()Node.js用于验证客户端证书的OpenSSL )。

理想情况下,您将没有三个证书,而不是为服务器使用自签名证书,也不为客户端使用单独的自签名证书,而是拥有三个证书:CA证书(按定义是自签名的),服务器证书(即已定义的证书)。由该CA签发/签名),以及单独的客户端证书(也由CA签发/签名)。由于您同时控制客户端服务器,因此不需要从公共CA购买这些证书。浏览器需要这些证书(因为公共CA的证书在浏览器的信任库中),但这听起来并不像您的用例所需要的(因此,您可以通过生成/使用自己的CA来节省一些钱)。这个网站 提供了用于执行此操作的示例命令。

这样,您的服务器将拥有证书(和私钥)以及CA证书;您的客户将拥有证书(和私钥)以及CA证书。那么,CA证书将是在SSL_CTX_load_verify_locations()路径/文件中以及ca选项中配置的证书tls.createServer

作为奖励,描述你可以考虑添加支持TLS会话缓存,在这里

希望这可以帮助!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何正确处理 Node.js gRPC 客户端和服务器之间的回调

Node.js,简单的TLS客户端/服务器

Socket.io Node Js服务器和React js客户端未连接

如何正确处理HTTP文件服务器上的客户端“连接:关闭”请求?

从Node.js客户端连接到C服务器

建立安全TLS连接之前客户端网络套接字已断开连接Node.js v13.0.1

使用TLS的node.js mqtt客户端

在Node.js上使用soket.io进行服务器和客户端之间的连接

当minVersion设置为1.3并使用1.3与客户端连接时,Node.js表示正在使用tls1.2

Node.js:通过socketio将客户端与服务器断开连接

将Node.js作为客户端连接到Common Lisp服务器

用于客户端TLS连接的OpenSSL或LibreSSL C ++示例

Node.js服务器(移动客户端)

在Linux服务器上处理多个客户端连接的正确方法是什么

在客户端和Node.js服务器上使用静态JavaScript文件

Node.js服务器和android客户端

Node.js:服务器和客户端之间的数据交换

Node.js服务器和客户端之间的变量

具有Node.js的服务器和具有XMLHttpRequest的客户端

客户端javascript与服务器node.js通信的简单方法

Node.js设计方法。定期从客户端轮询服务器

Windows上的TLS客户端和服务器[openssl,sspi和cryptlib]

使用OpenSSL服务器和SChannel客户端进行TLS会话恢复

客户端断开连接并再次连接服务器后,是否在Socket.io和node.js上重新发布了Socket ID?

客户端无法连接到Azure应用服务上托管的Node.js Websocket服务器吗?

Node.js服务器向Windows C#客户端发出命令

GRPC Golang服务器和NodeJS客户端。TLS连接失败

将Node.js Web客户端连接到Java gRPC服务器时出错

将前端本机Websocket客户端连接到Node.js Socket.io服务器