Nethereum.KeyStore 7.0.0

Prefix Reserved
dotnet add package Nethereum.KeyStore --version 7.0.0
                    
NuGet\Install-Package Nethereum.KeyStore -Version 7.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Nethereum.KeyStore" Version="7.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Nethereum.KeyStore" Version="7.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Nethereum.KeyStore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Nethereum.KeyStore --version 7.0.0
                    
#r "nuget: Nethereum.KeyStore, 7.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Nethereum.KeyStore@7.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Nethereum.KeyStore&version=7.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Nethereum.KeyStore&version=7.0.0
                    
Install as a Cake Tool

Nethereum.KeyStore

Password-encrypted private key storage using the Web3 Secret Storage Definition standard.

Overview

Nethereum.KeyStore implements the Web3 Secret Storage Definition for encrypting and storing Ethereum private keys. This is a standard format for encrypted key storage used across the Ethereum ecosystem.

Key Features:

  • AES-128-CTR encryption with password-derived keys
  • Scrypt KDF (memory-hard, ASIC-resistant)
  • PBKDF2 KDF (legacy, faster but less secure)
  • Configurable KDF parameters for performance tuning
  • JSON serialization/deserialization

Use Cases:

  • Encrypted local key storage
  • Wallet file generation
  • Key import/export between applications
  • Performance-tuned encryption for constrained environments (WASM, mobile)

Installation

dotnet add package Nethereum.KeyStore

Dependencies

Nethereum:

  • Nethereum.Hex - Hex encoding/decoding

External:

  • BouncyCastle.Cryptography or Portable.BouncyCastle (conditional) - Cryptographic operations

Quick Start

using Nethereum.KeyStore;
using Nethereum.Signer;
using Nethereum.Hex.HexConvertors.Extensions;

// Generate a new key
var ecKey = EthECKey.GenerateKey();

// Encrypt and generate keystore JSON
var service = new KeyStoreScryptService();
string password = "testPassword";
string json = service.EncryptAndGenerateKeyStoreAsJson(
    password,
    ecKey.GetPrivateKeyAsBytes(),
    ecKey.GetPublicAddress()
);

// Decrypt later
byte[] privateKey = service.DecryptKeyStoreFromJson(password, json);

Usage Examples

Example 1: Generate Key and Create Keystore (Scrypt)

using Nethereum.KeyStore;
using Nethereum.Signer;
using Nethereum.Hex.HexConvertors.Extensions;

var ecKey = EthECKey.GenerateKey();
var keyStoreScryptService = new KeyStoreScryptService();
string password = "testPassword";

// Encrypt and serialize to JSON
string json = keyStoreScryptService.EncryptAndGenerateKeyStoreAsJson(
    password,
    ecKey.GetPrivateKeyAsBytes(),
    ecKey.GetPublicAddress()
);

// Save to file
File.WriteAllText($"keystore-{ecKey.GetPublicAddress()}.json", json);

// Decrypt to verify
byte[] key = keyStoreScryptService.DecryptKeyStoreFromJson(password, json);
Assert.Equal(ecKey.GetPrivateKey(), key.ToHex(true));

Example 2: Custom Scrypt Parameters (Performance Tuning)

using Nethereum.KeyStore;
using Nethereum.KeyStore.Model;
using Nethereum.Signer;
using Nethereum.Hex.HexConvertors.Extensions;

var keyStoreService = new KeyStoreScryptService();

// Lower N for faster encryption (WASM, mobile, testing)
// Default: N=262144, R=1, P=8, Dklen=32
var scryptParams = new ScryptParams { Dklen = 32, N = 32, R = 1, P = 8 };

var ecKey = EthECKey.GenerateKey();
string password = "testPassword";

// Encrypt with custom parameters — pass address and ScryptParams object
var keyStore = keyStoreService.EncryptAndGenerateKeyStore(
    password,
    ecKey.GetPrivateKeyAsBytes(),
    ecKey.GetPublicAddress(),
    scryptParams
);

// Or use the JSON shortcut directly
string json = keyStoreService.EncryptAndGenerateKeyStoreAsJson(
    password, ecKey.GetPrivateKeyAsBytes(), ecKey.GetPublicAddress(), scryptParams);

// Decrypt
byte[] decryptedKey = keyStoreService.DecryptKeyStoreFromJson(password, json);

Example 3: Decrypt Existing Keystore (Scrypt)

using Nethereum.KeyStore;
using Nethereum.Hex.HexConvertors.Extensions;

var scryptKeyStoreJson = @"{
    ""crypto"" : {
        ""cipher"" : ""aes-128-ctr"",
        ""cipherparams"" : {
            ""iv"" : ""83dbcc02d8ccb40e466191a123791e0e""
        },
        ""ciphertext"" : ""d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c"",
        ""kdf"" : ""scrypt"",
        ""kdfparams"" : {
            ""dklen"" : 32,
            ""n"" : 262144,
            ""r"" : 1,
            ""p"" : 8,
            ""salt"" : ""ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19""
        },
        ""mac"" : ""2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097""
    },
    ""id"" : ""3198bc9c-6672-5ab3-d995-4942343ae5b6"",
    ""version"" : 3
}";

string password = "testpassword";
var keyStoreScryptService = new KeyStoreScryptService();

// Deserialize and decrypt
var keyStore = keyStoreScryptService.DeserializeKeyStoreFromJson(scryptKeyStoreJson);
byte[] privateKey = keyStoreScryptService.DecryptKeyStore(password, keyStore);

Console.WriteLine($"Private Key: {privateKey.ToHex()}");
// Output: 7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d

Example 4: PBKDF2 Keystore (Legacy)

using Nethereum.KeyStore;
using Nethereum.Signer;
using Nethereum.Hex.HexConvertors.Extensions;

var ecKey = EthECKey.GenerateKey();
var keyStorePbkdf2Service = new KeyStorePbkdf2Service();
string password = "testPassword";

// Encrypt with PBKDF2 (faster but less secure than Scrypt)
string json = keyStorePbkdf2Service.EncryptAndGenerateKeyStoreAsJson(
    password,
    ecKey.GetPrivateKeyAsBytes(),
    ecKey.GetPublicAddress()
);

// Decrypt
byte[] key = keyStorePbkdf2Service.DecryptKeyStoreFromJson(password, json);
Assert.Equal(ecKey.GetPrivateKey(), key.ToHex(true));

Example 5: Detect KDF Type

using Nethereum.KeyStore;

string keystoreJson = File.ReadAllText("wallet.json");
var keyStoreKdfChecker = new KeyStoreKdfChecker();

var kdfType = keyStoreKdfChecker.GetKeyStoreKdfType(keystoreJson);

if (kdfType == KeyStoreKdfChecker.KdfType.scrypt)
{
    var service = new KeyStoreScryptService();
    byte[] privateKey = service.DecryptKeyStoreFromJson(password, keystoreJson);
}
else if (kdfType == KeyStoreKdfChecker.KdfType.pbkdf2)
{
    var service = new KeyStorePbkdf2Service();
    byte[] privateKey = service.DecryptKeyStoreFromJson(password, keystoreJson);
}

Example 6: Default Keystore Service

using Nethereum.KeyStore;
using Nethereum.Signer;
using Nethereum.Hex.HexConvertors.Extensions;

var ecKey = EthECKey.GenerateKey();
var keyStoreService = new KeyStoreService();
string password = "testPassword";

// Uses default Scrypt parameters
string json = keyStoreService.EncryptAndGenerateDefaultKeyStoreAsJson(
    password,
    ecKey.GetPrivateKeyAsBytes(),
    ecKey.GetPublicAddress()
);

byte[] key = keyStoreService.DecryptKeyStoreFromJson(password, json);
Assert.Equal(ecKey.GetPrivateKey(), key.ToHex(true));

API Reference

KeyStoreServiceBase<T>

KeyStoreScryptService and KeyStorePbkdf2Service are thin subclasses of this abstract base (T : KdfParams) — almost every method below is inherited, not redeclared per-KDF. Note the EncryptAndGenerateKeyStoreAsJson overloads take the address parameter as addresss (a real typo in the shipped signature, kept for source compatibility); the object-returning EncryptAndGenerateKeyStore overloads spell it correctly as address.

public abstract class KeyStoreServiceBase<T> : IKeyStoreService<T> where T : KdfParams
{
    public const int CurrentVersion = 3;

    // Key store (private key) encryption
    public KeyStore<T> EncryptAndGenerateKeyStore(string password, byte[] privateKey, string address);
    public KeyStore<T> EncryptAndGenerateKeyStore(string password, byte[] privateKey, string address, T kdfParams);
    public string EncryptAndGenerateKeyStoreAsJson(string password, byte[] privateKey, string addresss);
    public string EncryptAndGenerateKeyStoreAsJson(string password, byte[] privateKey, string addresss, T kdfParams);

    public byte[] DecryptKeyStoreFromJson(string password, string json);
    public virtual byte[] DecryptKeyStore(string password, KeyStore<T> keyStore);

    public abstract KeyStore<T> DeserializeKeyStoreFromJson(string json);   // overridden per-KDF
    public abstract string SerializeKeyStoreToJson(KeyStore<T> keyStore);  // overridden per-KDF
    public abstract string GetKdfType();                                  // "scrypt" / "pbkdf2"
    public virtual string GetCipherType(); // "aes-128-ctr"

    // Generic payload (arbitrary byte[]/string) encryption - same KDF/cipher, no "address" field
    public CryptoStore<T> EncryptAndGenerateCryptoStore(string password, byte[] payload);
    public CryptoStore<T> EncryptAndGenerateCryptoStore(string password, byte[] payload, T kdfParams);
    public string EncryptAndGenerateCryptoStoreAsJson(string password, byte[] payload);
    public string EncryptAndGenerateCryptoStoreFromStringAsJson(string password, string payload);
    public byte[] DecryptCryptoStoreFromJson(string password, string json);
    public byte[] DecryptCryptoStore(string password, CryptoStore<T> cryptoStore);
}

KeyStoreScryptService : KeyStoreServiceBase<ScryptParams>

Scrypt-based keystore encryption (recommended). Adds only the KDF-specific pieces; everything else above is inherited unchanged.

public class KeyStoreScryptService : KeyStoreServiceBase<ScryptParams>
{
    public const string KdfType = "scrypt";
}

Default Scrypt Parameters (GetDefaultParams()):

N = 262144  // CPU/memory cost (2^18)
R = 1       // Block size
P = 8       // Parallelization
Dklen = 32  // Derived key length

KeyStorePbkdf2Service : KeyStoreServiceBase<Pbkdf2Params>

PBKDF2-based keystore encryption (legacy). Same relationship to the base class as KeyStoreScryptService.

public class KeyStorePbkdf2Service : KeyStoreServiceBase<Pbkdf2Params>
{
    public const string KdfType = "pbkdf2";
}

Default PBKDF2 Parameters (GetDefaultParams()):

Count = 262144      // Iteration count
Prf = "hmac-sha256"
Dklen = 32          // Derived key length

KeyStoreService

Unified service: wraps a KeyStoreScryptService + KeyStorePbkdf2Service + KeyStoreKdfChecker internally, and also carries the file-naming/address-extraction and raw-payload-encryption helpers that are NOT on KeyStoreServiceBase<T>.

public class KeyStoreService
{
    public KeyStoreService();
    public KeyStoreService(KeyStoreKdfChecker keyStoreKdfChecker, KeyStoreScryptService keyStoreScryptService,
        KeyStorePbkdf2Service keyStorePbkdf2Service);

    // Encrypt with default Scrypt parameters
    public string EncryptAndGenerateDefaultKeyStoreAsJson(string password, byte[] key, string address);

    // Decrypt (auto-detects KDF type via KeyStoreKdfChecker)
    public byte[] DecryptKeyStoreFromJson(string password, string json);
#if !PCL
    public byte[] DecryptKeyStoreFromFile(string password, string filePath);
#endif

    // Read the "address" field straight out of a keystore JSON document, without deserializing it fully
    public string GetAddressFromKeyStore(string json);

    // "UTC--<ISO8601 with ':' replaced by '-'>--<address without 0x>", the standard Ethereum
    // keystore file-naming convention
    public string GenerateUTCFileName(string address);

    // Generic payload encryption (delegates to the internal KeyStoreScryptService's
    // CryptoStore<ScryptParams> methods - no address field, just password + payload)
    public string EncryptPayloadAsJson(string password, byte[] data);
    public string EncryptPayloadFromStringAsJson(string password, string data);
    public byte[] DecryptPayloadFromJson(string password, string json);
    public string DecryptPayloadToUtf8String(string password, string json);
}

KeyStoreKdfChecker

Detect KDF type from JSON. This is the only detection API — there is no IsScryptKdf/IsPbkdf2Kdf.

public class KeyStoreKdfChecker
{
    public enum KdfType { scrypt, pbkdf2 }

    // Throws if "crypto.kdf" is missing or is neither "scrypt" nor "pbkdf2"
    public KdfType GetKeyStoreKdfType(string json);
}

Model Classes

ScryptParams and Pbkdf2Params both derive from KdfParams, which carries Dklen/Salt; N/R/P and Count/Prf live on the subclasses. Note Pbkdf2Params.Count (JSON "c"), not C.

public class KdfParams
{
    [JsonProperty("dklen")]
    public int Dklen { get; set; }  // Derived key length (32)

    [JsonProperty("salt")]
    public string Salt { get; set; } // Random salt (hex)
}

public class ScryptParams : KdfParams
{
    [JsonProperty("n")]
    public int N { get; set; }      // CPU/memory cost (262144)

    [JsonProperty("r")]
    public int R { get; set; }      // Block size (1)

    [JsonProperty("p")]
    public int P { get; set; }      // Parallelization (8)
}

public class Pbkdf2Params : KdfParams
{
    [JsonProperty("c")]
    public int Count { get; set; }  // Iteration count (262144)

    [JsonProperty("prf")]
    public string Prf { get; set; } // PRF algorithm (hmac-sha256)
}

public class KeyStore<TKdfParams> where TKdfParams : KdfParams
{
    public CryptoInfo<TKdfParams> Crypto { get; set; }
    public string Id { get; set; }      // UUID
    public string Address { get; set; } // Ethereum address (optional)
    public int Version { get; set; }    // Always 3
}

Scrypt Parameter Tuning

Default Parameters (Desktop/Server)

N = 262144  // 2^18 - Strong security, ~100ms encryption
R = 1
P = 8

Use for: Desktop applications, servers, production wallets

Low-Cost Parameters (WASM/Mobile/Testing)

N = 32      // 2^5 - Fast encryption, weaker security
R = 1
P = 8

Use for: Browser WASM, mobile apps, development/testing

High-Security Parameters

N = 1048576  // 2^20 - Very strong security, ~3s encryption
R = 8
P = 1

Use for: Cold storage, high-value accounts, paranoid security

Parameter Effects

Parameter Effect Security Impact Performance Impact
N CPU/memory cost Exponential Exponential
R Block size Linear Linear
P Parallelization Linear Linear (if parallel)

N dominates: Doubling N doubles time and memory. Scrypt needs about 128 x N x R bytes, so the default N=262144 with R=1 uses ~32MB RAM.

Web3 Secret Storage Format

Keystore JSON structure:

{
  "crypto": {
    "cipher": "aes-128-ctr",
    "cipherparams": { "iv": "..." },
    "ciphertext": "...",
    "kdf": "scrypt",
    "kdfparams": {
      "dklen": 32,
      "n": 262144,
      "r": 1,
      "p": 8,
      "salt": "..."
    },
    "mac": "..."
  },
  "id": "3198bc9c-6672-5ab3-d995-4942343ae5b6",
  "version": 3
}

Fields:

  • cipher: Always aes-128-ctr
  • ciphertext: Encrypted private key
  • kdf: scrypt or pbkdf2
  • kdfparams: KDF configuration
  • mac: HMAC for integrity verification
  • version: Always 3

Important Notes

Scrypt vs PBKDF2

Feature Scrypt PBKDF2
Security Memory-hard, ASIC-resistant CPU-only, ASIC-vulnerable
Speed Slower (~100ms default) Faster (~50ms)
Recommendation Use this Legacy only

Use Scrypt unless you need compatibility with very old systems.

File Naming Convention

Standard naming convention used across Ethereum tools:

UTC--<created_at UTC ISO8601>--<address hex>

Example:

UTC--2024-01-15T10-30-45.123Z--0x12890d2cce102216644c59dae5baed380d84830c

Security Considerations

  1. Password strength is critical - No KDF can protect weak passwords
  2. N parameter tradeoff - Higher N = more secure but slower
  3. Salt is auto-generated - Uses cryptographically secure random bytes
  4. MAC prevents tampering - Detects modified ciphertext
  5. AES-128-CTR - Standard encryption mode, secure when properly implemented

Used By

  • Nethereum.Accounts - Account management with keystore loading

Dependencies

  • Nethereum.Hex - Hex encoding/decoding

Additional Resources

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net451 is compatible.  net452 was computed.  net46 was computed.  net461 is compatible.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (14)

Showing the top 5 NuGet packages that depend on Nethereum.KeyStore:

Package Downloads
Nethereum.Web3

Nethereum.Web3 Ethereum Web3 Class Library to interact via RPC with an Ethereum client, for example geth. Including contract interaction, deployment, transaction, encoding / decoding and event filters

Nethereum.Accounts

Nethereum.Accounts Ethereum Accounts and Transaction Managers Class Library

Nethereum

Package Description

AElf.Client

This is a C# client library, used to communicate with the AElf API.

AElf.OS

Main module for the OS layer.

GitHub repositories (2)

Showing the top 2 popular GitHub repositories that depend on Nethereum.KeyStore:

Repository Stars
AElfProject/AElf
An AI-enhanced cloud-native layer-1 blockchain network. 
biheBlockChain/MyLinkToken
开源链克口袋,玩客币钱包
Version Downloads Last Updated
7.0.0 154 10/2/2026
6.1.0 175,471 3/25/2026
6.0.4 21,051 3/18/2026
6.0.3 1,646 3/18/2026
6.0.1 2,768 3/17/2026
6.0.0 5,922 3/16/2026
5.8.0 105,436 1/6/2026
5.0.0 478,112 5/28/2025
4.29.0 322,409 2/10/2025
4.28.0 94,512 1/7/2025
4.27.1 16,427 12/24/2024
4.27.0 10,471 12/24/2024
4.26.0 108,676 10/1/2024
4.25.0 52,709 9/19/2024
4.21.4 151,799 8/9/2024
4.21.3 11,776 7/22/2024
4.21.2 79,662 6/26/2024
4.21.1 4,187 6/26/2024
4.21.0 22,100 6/18/2024
4.20.0 412,198 3/28/2024
Loading failed