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

NodeJS ECDH密钥生成函数转C#求助:获取randomBytes的buf

Converting Node.js ECDH Key Generation to C# (Including crypto.randomBytes Equivalent)

Alright, let's tackle translating your Node.js ECDH key generation function to C# properly, including matching the behavior of crypto.randomBytes and the key formatting/encoding steps from your original code.

First, let's recap what your Node.js function does:

  • Creates an ECDH instance using the prime256v1 curve (NIST P-256)
  • Generates a key pair
  • Creates a 16-byte random buffer
  • Encodes the private key, public key, and random buffer to Base64, then escapes them for URI safety

Here's the complete C# implementation that mirrors this behavior, building on your existing code snippets:

Required Usings

using System;
using System.Security.Cryptography;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;

Result Class

First, define a class to hold the keys and auth secret, matching the structure returned by your Node.js function:

public class EcdhKeyResult
{
    public string PrivateKey { get; set; }
    public string PublicKey { get; set; }
    public string AuthSecret { get; set; }
}

Complete Generation Method

public static EcdhKeyResult GenerateKeys()
{
    // Generate ECC key pair (matches crypto.createECDH('prime256v1') + dh.generateKeys())
    var secureRandom = new SecureRandom();
    var curveOid = X962NamedCurves.GetOid("prime256v1"); // Fixed: use string instead of char
    var keyGenerator = new ECKeyPairGenerator();
    var genParams = new ECKeyGenerationParameters(curveOid, secureRandom);
    
    keyGenerator.Init(genParams);
    AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();

    // Process private key (matches dh.getPrivateKey('base64') + escape())
    var privateKeyParams = (ECPrivateKeyParameters)keyPair.Private;
    byte[] privateKeyRawBytes = privateKeyParams.D.ToByteArrayUnsigned();
    string privateKeyBase64 = Convert.ToBase64String(privateKeyRawBytes);
    string escapedPrivateKey = Uri.EscapeDataString(privateKeyBase64);

    // Process public key (matches dh.getPublicKey('base64') + escape())
    // Node.js returns uncompressed public key (0x04 prefix + X coordinate + Y coordinate)
    var publicKeyParams = (ECPublicKeyParameters)keyPair.Public;
    var curve = X962NamedCurves.GetByOid(curveOid);
    
    byte[] xCoordBytes = publicKeyParams.Q.AffineXCoord.GetEncoded();
    byte[] yCoordBytes = publicKeyParams.Q.AffineYCoord.GetEncoded();
    
    byte[] uncompressedPublicKey = new byte[1 + xCoordBytes.Length + yCoordBytes.Length];
    uncompressedPublicKey[0] = 0x04; // Mark as uncompressed
    Buffer.BlockCopy(xCoordBytes, 0, uncompressedPublicKey, 1, xCoordBytes.Length);
    Buffer.BlockCopy(yCoordBytes, 0, uncompressedPublicKey, 1 + xCoordBytes.Length, yCoordBytes.Length);
    
    string publicKeyBase64 = Convert.ToBase64String(uncompressedPublicKey);
    string escapedPublicKey = Uri.EscapeDataString(publicKeyBase64);

    // Generate 16-byte random buffer (matches crypto.randomBytes(16) + escape())
    byte[] authSecretRaw = RandomBytes();
    string authSecretBase64 = Convert.ToBase64String(authSecretRaw);
    string escapedAuthSecret = Uri.EscapeDataString(authSecretBase64);

    return new EcdhKeyResult
    {
        PrivateKey = escapedPrivateKey,
        PublicKey = escapedPublicKey,
        AuthSecret = escapedAuthSecret
    };
}

// Updated random bytes method (replaces obsolete RNGCryptoServiceProvider)
public static byte[] RandomBytes()
{
    byte[] randomBuffer = new byte[16];
    // Use modern RandomNumberGenerator for better security and compatibility
    using (var rng = RandomNumberGenerator.Create())
    {
        rng.GetBytes(randomBuffer);
    }
    return randomBuffer;
}

Key Notes to Match Node.js Behavior:

  • Curve Selection: Fixed your original C# code's typo ('prime256v1' as a char instead of string) to correctly reference the P-256 curve.
  • Private Key Encoding: Node.js returns the raw EC private key (the D value as a byte array), so we extract that from ECPrivateKeyParameters instead of using a formatted key structure like PKCS#8.
  • Public Key Format: Node.js defaults to returning an uncompressed public key (0x04 prefix + X/Y coordinates), so we manually construct this format instead of using DER-encoded SubjectPublicKeyInfo.
  • URI Escaping: escape() in Node.js maps directly to C#'s Uri.EscapeDataString() for consistent URI-safe encoding.
  • Random Bytes: Updated your random buffer method to use RandomNumberGenerator instead of the obsolete RNGCryptoServiceProvider for better security and compatibility with newer .NET versions.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:08:11