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
prime256v1curve (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
Dvalue as a byte array), so we extract that fromECPrivateKeyParametersinstead 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#'sUri.EscapeDataString()for consistent URI-safe encoding. - Random Bytes: Updated your random buffer method to use
RandomNumberGeneratorinstead of the obsoleteRNGCryptoServiceProviderfor better security and compatibility with newer .NET versions.
内容的提问来源于stack exchange,提问作者Angelo Bestetti
相关产品推荐
相关产品推荐

