You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加密发送至Azure SignalR Service支持的SignalR群组的消息

实现方案

核心思路:端到端加密,Azure Function仅做转发

不让Azure Function接触明文消息和密钥,所有加密、解密操作都在客户端完成,密钥仅在群组合法成员之间共享。

1. 群组共享密钥协商

  • 每个客户端生成自己的RSA密钥对,加入群组时将公钥发送给群组内其他成员(可通过SignalR的用户点对点消息传递,或经过Azure Function转发但Function不解析内容)。
  • 由群组内指定成员(比如第一个加入的用户)生成AES对称密钥,用每个群组成员的公钥分别加密该密钥,发送给对应成员;成员用自身私钥解密得到AES密钥。
  • 若有成员离开群组,剩余成员需重新协商新的AES密钥,防止已离开成员继续解密后续消息。

2. 客户端侧消息加密/解密

发送消息时加密

// 假设已通过协商获取到群组共享AES密钥aesKey
byte[] plainTextBytes = Encoding.UTF8.GetBytes(message);
byte[] encryptedBytes = AesEncrypt(plainTextBytes, aesKey);
string encryptedMessage = Convert.ToBase64String(encryptedBytes);

// 发送加密后的密文到SignalR Hub
await hubConnection.SendAsync("msgSent", username, encryptedMessage);

接收消息时解密

hubConnection.On<string>("msgReceived", (encryptedMessage) =>
{
    byte[] encryptedBytes = Convert.FromBase64String(encryptedMessage);
    byte[] plainTextBytes = AesDecrypt(encryptedBytes, aesKey);
    string message = Encoding.UTF8.GetString(plainTextBytes);
    // 处理明文消息逻辑
});

3. 调整Azure Function代码

Function无需任何加密/解密逻辑,仅负责转发密文:

[Function("SendMessageToGroup")]
[SignalROutput(HubName = "MyHub")]
public SignalRMessageAction SendMessageToGroup(
    [SignalRTrigger("MyHub", "Category", "msgSent", "username", "encryptedMessage")] 
    SignalRInvocationContext invocationContext, 
    string username, 
    string encryptedMessage)
{
    // 直接转发密文,不接触明文内容
    return new SignalRMessageAction() { Arguments = [encryptedMessage], GroupName = "MyGroup" };
}

4. 辅助加密工具示例(AES实现)

private static byte[] AesEncrypt(byte[] plainText, byte[] key)
{
    using (Aes aesAlg = Aes.Create())
    {
        aesAlg.Key = key;
        aesAlg.GenerateIV();
        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        using (MemoryStream msEncrypt = new MemoryStream())
        {
            msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                csEncrypt.Write(plainText, 0, plainText.Length);
                csEncrypt.FlushFinalBlock();
            }
            return msEncrypt.ToArray();
        }
    }
}

private static byte[] AesDecrypt(byte[] cipherText, byte[] key)
{
    using (Aes aesAlg = Aes.Create())
    {
        aesAlg.Key = key;
        byte[] iv = new byte[aesAlg.BlockSize / 8];
        Array.Copy(cipherText, 0, iv, 0, iv.Length);
        aesAlg.IV = iv;

        ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
        using (MemoryStream msDecrypt = new MemoryStream(cipherText, iv.Length, cipherText.Length - iv.Length))
        {
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                using (MemoryStream resultStream = new MemoryStream())
                {
                    csDecrypt.CopyTo(resultStream);
                    return resultStream.ToArray();
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Arash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 03:15:21