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

两个程序计算的X25519共享密钥不一致,求排查解决方法

X25519跨语言密钥交换共享密钥不匹配问题修复

问题描述

编写了Dart和.NET Core两个X25519密钥交换程序,通过PEM文件交换公钥,手动触发计算共享密钥,但最终输出的Base64编码共享密钥不一致。

Dart程序依赖cryptography和pem库生成密钥对并写入PEM,读取对方PEM后计算共享密钥;.NET程序使用X25519-CSharp库生成密钥对,手动处理对方PEM后计算共享密钥。

核心问题分析

  • .NET端PEM解析方式错误:手动通过Replace去除PEM标签和换行的操作不可靠,容易因换行符差异(如\n/\r\n)、多余空格或PEM格式细节(如标签行的大小写、末尾换行)导致Base64字符串损坏,解码出错误的公钥字节,最终计算出错误的共享密钥。
  • 潜在格式兼容性风险:虽两端都使用"PUBLIC KEY"标签,但需确保双方的PEM都对应裸32字节X25519公钥(而非ASN.1包装的SPKI格式),不过此问题在当前代码中概率较低,核心矛盾仍在手动解析PEM的操作。

修复方案

修改.NET程序的PEM解析逻辑

删除手动替换标签和换行的代码,改用PemEncoding.Read方法正确解析PEM文件,确保获取准确的公钥字节:

using System.Security.Cryptography;
using X25519;

internal class Program
{
    private static void Main(string[] args)
    {
        var keyPair = X25519KeyAgreement.GenerateKeyPair();
        File.WriteAllText("/home/razj/sharpPublic.txt", new string(PemEncoding.Write("PUBLIC KEY", keyPair.PublicKey)));

        Console.WriteLine("PRESS AFTER DART PROGRAM GENERATES KEYPAIR");
        Console.ReadKey(true);

        // 正确解析PEM文件
        string remotePem = File.ReadAllText("/home/razj/dartPublic.txt");
        var pemData = PemEncoding.Read(remotePem);
        // 可选:增加标签校验提升鲁棒性
        if (pemData.Label != "PUBLIC KEY")
        {
            throw new InvalidOperationException("Invalid PEM label for public key");
        }
        byte[] remotePublicKeyBytes = pemData.Data;
        
        byte[] sharedKeyBytes = X25519KeyAgreement.Agreement(keyPair.PrivateKey, remotePublicKeyBytes);
    
        Console.WriteLine(Convert.ToBase64String(sharedKeyBytes));
    }
}

验证Dart端PEM生成的正确性(可选)

确认Dart程序生成的公钥是标准32字节:可以打印await keyPair.extractPublicKeyBytes()的长度,确保输出为32。当前cryptography库的X25519实现默认输出裸32字节公钥,无需额外修改。

验证结果

修改后,两端程序交换PEM公钥后计算出的Base64共享密钥将完全一致,因为公钥字节解析准确,X25519密钥交换算法的计算逻辑是标准统一的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:45:37