rust angular 自签名证书 wss

本文介绍了如何使用OpenSSL生成私钥和证书,然后在Rust服务器端通过rustls库实现TLS加密WebSocket服务,并在Angular客户端进行连接。同时提到如何在谷歌浏览器中设置忽略证书错误以测试自签名证书的应用。
摘要由CSDN通过智能技术生成

1. 生成私钥, 证书:

请查看: 使用 openssl 安装和生成证书 - 书源 - 博客园 (cnblogs.com)

2. 代码实现:

2.1 Rust 服务端:

依赖:

[dependencies]
rustls = "0.19.0"
tokio-rustls = "0.22.0"
tokio = { version = "1", features = ["full"] }
tokio-tungstenite = "0.20"
futures-util = "0.3"

代码:

use futures_util::sink::SinkExt;
use futures_util::stream::{Stream, StreamExt};
use rustls::ServerConfig;
use std::fs::File;
use std::io::BufReader;
use std::sync::Arc;
use tokio::net::{TcpListener, TcpStream};
use tokio_rustls::TlsAcceptor;
use tokio_tungstenite::accept_async;
use tokio_tungstenite::tungstenite::protocol::Message;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 加载SSL keys
    let certs = rustls::internal::pemfile::certs(&mut BufReader::new(File::open(
        "d:\\User\\Desktop\\wss\\openssl\\server.crt",
    )?))
    .unwrap();
    let key = rustls::internal::pemfile::pkcs8_private_keys(&mut BufReader::new(File::open(
        "d:\\User\\Desktop\\wss\\openssl\\server.key",
    )?))
    .unwrap()[0]
        .clone();






    let tls_cfg = {
        let mut cfg = ServerConfig::new(rustls::NoClientAuth::new());
        cfg.set_single_cert(certs, key).expect("error setting cert");
        Arc::new(cfg)
    };
    let tls_acceptor = TlsAcceptor::from(tls_cfg);






    // 设置TCP监听器
    let addr = "127.0.0.1:10096";
    let listener = TcpListener::bind(&addr).await?;
    println!("Listening on: {}", addr);






    while let Ok((stream, _)) = listener.accept().await {
        let acceptor = tls_acceptor.clone();






        tokio::spawn(async move {
            if let Ok(tls_stream) = acceptor.accept(stream).await {
                let websocket_result = accept_async(tls_stream).await;






                match websocket_result {
                    Ok(mut ws_stream) => {
                        println!("WebSocket connection established");
                        while let Some(message_result) = ws_stream.next().await {
                            match message_result {
                                Ok(message) => {
                                    if message.is_text() || message.is_binary() {
                                        // 对接收到的消息进行处理
                                        println!("接收到消息: {}", message);
                                        // 回传消息
                                        println!("回传消息: {}", message);
                                        if let Err(_) = ws_stream.send(message).await {
                                            // 处理错误
                                            break;
                                        }
                                    }
                                }
                                Err(e) => {
                                    // 处理错误
                                    println!("Error: {}", e);
                                    break;
                                }
                            }
                        }
                    }
                    Err(e) => {
                        println!("Error during the websocket handshake occurred: {}", e);
                    }
                }
            }
        });
    }






    Ok(())
}

2.2 Angular 客户端:

Angular 配置:

将生成的 

client.crt 和 client.key 放到和 package.json 同级文件夹下.

package.json 

"scripts": {
"start": "ng serve --host 0.0.0.0 --port 443 --ssl true --ssl-cert ./client.crt --ssl-key ./client.key",}

// 补充
./client.crt 和 ./client.key 是相对路径,表示这些证书文件位于当前工作目录。当前工作目录指的是你在运行 ng serve 命令时所在的目录,也就是命令行提示符下的目录。如果你在项目的根目录下运行这个命令(通常是包含 package.json 文件的目录),./ 就表示这个项目的根目录

 angular 代码:

import {webSocket} from "rxjs/webSocket";
  ngOnInit() {
    this.websocketTest();
  }  

websocketTest() {
    const url: string = 'wss://127.0.0.1:10096';
    const myWebSocket = webSocket({
      url: url,
      openObserver: {
        next: () => {
          console.info('WebSocket 连接已建立: ' + url);
        },
        error: (err) => {
          console.error('WebSocket 连接出错: ' + url);
          console.error(err);
        },
      },
    });
    const data = JSON.stringify({name: '张三', age: 18, sex: '男'});
    myWebSocket.next(data);

    console.log('客户端发送请求: ', data);
    myWebSocket.subscribe(
      next => {
        console.log('客户端收到响应: ', next);
      },
      error => {
        console.error('WebSocket 出错: ' + url);
        console.error(error);
      }
    );
  }

3. 谷歌浏览器设置

谷歌浏览器图标右击 属性 -> 快捷方式 -> 目标(修改其中字符串, )

  原来类似 "C:\Program Files\Google\Chrome\Application\chrome.exe"

  修改为 "C:\Program Files\Google\Chrome\Application\chrome.exe" --ignore-certificate-errors

这个命令会忽略证书错误。正常情况下,当你访问一个使用自签名或无效证书的网站时,Chrome 会显示一个警告页面,指示你有潜在的安全风险。然而,使用 --ignore-certificate-errors 参数可以忽略这些证书错误,并允许你继续访问网站,而不会受到浏览器的证书警告页面的干扰。

4. 结果展示:

前端项目使用 npm start 启动:

前端控制台:

后端控制台:

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Rust 中,可以使用 `ethers-rs` crate 来实现 EIP712 签名。以下是一个示例代码: 首先,你需要在 `Cargo.toml` 文件中添加 `ethers-rs` crate 的依赖: ``` [dependencies] ethers = "0.3.0-alpha.5" ``` 接下来,你可以使用以下代码实现 EIP712 签名: ```rust use ethers::types::{Address, Name, TypedData}; use ethers::utils::{keccak256, hash_message, bytes_to_hex_str}; use ethers::signers::{LocalWallet, Signer}; fn main() { // 创建钱包 let wallet = LocalWallet::new(&mut rand::thread_rng()); // EIP712 消息 let message = TypedData { types: Default::default(), domain: Default::default(), message: vec![ ( "name".to_string(), "Hello".to_string(), ), ( "value".to_string(), 42u64.into(), ), ], }; // 计算消息哈希 let message_hash = keccak256(&message.to_bytes()).to_fixed_bytes(); // 签名 let signature = wallet.sign_message(&message_hash).unwrap(); // 打印签名结果 println!("Signature: {}", bytes_to_hex_str(&signature)); // 验证签名 let signer_address = Address::from(wallet.address()); let recovered_address = hash_message(&message.to_bytes(), &signature).unwrap(); assert_eq!(signer_address, recovered_address); } ``` 在这个示例中,我们首先创建了一个本地钱包。然后,我们定义了一个 EIP712 消息,包含一个名为 `name` 的字符串和一个名为 `value` 的整数。我们计算了消息哈希,并使用钱包的 `sign_message` 方法对其进行签名。最后,我们打印签名结果,并验证签名。 请注意,这个示例中的 EIP712 消息是一个自定义的示例消息。如果你要使用真实的 EIP712 消息,请参考对应协议的文档,以获取正确的类型定义和域名设置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值