public class NKey
extends java.lang.Object
The NATS ecosystem will be moving to Ed25519 keys for identity, authentication and authorization for entities such as Accounts, Users, Servers and Clusters.
NKeys are based on the Ed25519 standard. This signing algorithm provides for the use of public and private keys to sign and verify data. NKeys is designed to formulate keys in a much friendlier fashion referencing work done in cryptocurrencies, specifically Stellar. Bitcoin and others use a form of Base58 (or Base58Check) to encode raw keys. Stellar utilizes a more traditional Base32 with a CRC16 and a version or prefix byte. NKeys utilizes a similar format with one or two prefix bytes. The base32 encoding of these prefixes will yield friendly human readable prefixes, e.g. 'N' = server, 'C' = cluster, 'O' = operator, 'A' = account, and 'U' = user to help developers and administrators quickly identify key types.
Each NKey is generated from 32 bytes. These bytes are called the seed and are encoded, in the NKey world, into a string starting with the letter 'S', with a second character indicating the key’s type, e.g. "SU" is a seed for a u er key pair, "SA" is a seed for an account key pair. The seed can be used t create the Ed25519 public/private key pair and should be protected as a p ivate key. It is equivalent to the private key for a PGP key pair, or the m ster password for your password vault.
Ed25519 uses the seed bytes to generate a key pair. The pair contains a private key, which can be used to sign data, and a public key which can be used to verify a signature. The public key can be distributed, and is not considered secret.
The NKey libraries encode 32 byte public keys using Base32 and a CRC16 checksum plus a prefix based on the key type, e.g. U for a user key.
The NKey libraries have support for exporting a 64 byte private key. This data is encoded into a string starting with the prefix ‘P’ for private. The 64 bytes in a private key consists of the 32 bytes of the seed followed by he 32 bytes of the public key. Essentially, the private key is redundant sin e you can get it back from the seed alone. The NATS team recommends sto ing the 32 byte seed and letting the NKey library regenerate anything els it needs for signing.
The existence of both a seed and a private key can result in confusion. It is reasonable to simply think of Ed25519 as having a public key and a private seed, and ignore the longer private key concept. In fact, the NKey libraries generally expect you to create an NKey from either a public key, to use for verification, or a seed, to use for signing.
The NATS system will utilize public NKeys for identification, the NATS system will never store or even have access to any private keys or seeds. Authentication will utilize a challenge-response mechanism based on a collection of random bytes called a nonce.
Version note - 2.2.0 provided string arguments for seeds, this is not as safe as char arrays, so in 2.3.0 we have included a breaking change to char arrays. While this is not the proper version choice, NKeys aren't widely used, if at all yet, so we are making the change on a minor jump.
Modifier and Type | Class and Description |
---|---|
static class |
NKey.Type
NKeys use a prefix byte to indicate their intended owner: 'N' = server, 'C' =
cluster, 'A' = account, and 'U' = user.
|
Modifier and Type | Method and Description |
---|---|
void |
clear()
Clear the seed and public key char arrays by filling them
with random bytes then zero-ing them out.
|
static NKey |
createAccount(java.security.SecureRandom random)
Create an Account NKey from the provided random number generator.
|
static NKey |
createCluster(java.security.SecureRandom random)
Create an Cluster NKey from the provided random number generator.
|
static NKey |
createOperator(java.security.SecureRandom random)
Create an Operator NKey from the provided random number generator.
|
static NKey |
createServer(java.security.SecureRandom random)
Create a Server NKey from the provided random number generator.
|
static NKey |
createUser(java.security.SecureRandom random)
Create a User NKey from the provided random number generator.
|
boolean |
equals(java.lang.Object o) |
static NKey |
fromPublicKey(char[] publicKey)
Create an NKey object from the encoded public key.
|
static NKey |
fromSeed(char[] seed)
Creates an NKey object from a string encoded seed.
|
java.security.KeyPair |
getKeyPair() |
char[] |
getPrivateKey() |
char[] |
getPublicKey() |
char[] |
getSeed() |
NKey.Type |
getType() |
int |
hashCode() |
static boolean |
isValidPublicAccountKey(char[] src) |
static boolean |
isValidPublicClusterKey(char[] src) |
static boolean |
isValidPublicOperatorKey(char[] src) |
static boolean |
isValidPublicServerKey(char[] src) |
static boolean |
isValidPublicUserKey(char[] src) |
byte[] |
sign(byte[] input)
Sign aribitrary binary input.
|
boolean |
verify(byte[] input,
byte[] signature)
Verify a signature.
|
public static NKey createAccount(java.security.SecureRandom random) throws java.io.IOException, java.security.NoSuchProviderException, java.security.NoSuchAlgorithmException
random
- A secure random providerjava.io.IOException
- if the seed cannot be encoded to a stringjava.security.NoSuchProviderException
- if the default secure random cannot be createdjava.security.NoSuchAlgorithmException
- if the default secure random cannot be createdpublic static NKey createCluster(java.security.SecureRandom random) throws java.io.IOException, java.security.NoSuchProviderException, java.security.NoSuchAlgorithmException
random
- A secure random providerjava.io.IOException
- if the seed cannot be encoded to a stringjava.security.NoSuchProviderException
- if the default secure random cannot be createdjava.security.NoSuchAlgorithmException
- if the default secure random cannot be createdpublic static NKey createOperator(java.security.SecureRandom random) throws java.io.IOException, java.security.NoSuchProviderException, java.security.NoSuchAlgorithmException
random
- A secure random providerjava.io.IOException
- if the seed cannot be encoded to a stringjava.security.NoSuchProviderException
- if the default secure random cannot be createdjava.security.NoSuchAlgorithmException
- if the default secure random cannot be createdpublic static NKey createServer(java.security.SecureRandom random) throws java.io.IOException, java.security.NoSuchProviderException, java.security.NoSuchAlgorithmException
random
- A secure random providerjava.io.IOException
- if the seed cannot be encoded to a stringjava.security.NoSuchProviderException
- if the default secure random cannot be createdjava.security.NoSuchAlgorithmException
- if the default secure random cannot be createdpublic static NKey createUser(java.security.SecureRandom random) throws java.io.IOException, java.security.NoSuchProviderException, java.security.NoSuchAlgorithmException
random
- A secure random providerjava.io.IOException
- if the seed cannot be encoded to a stringjava.security.NoSuchProviderException
- if the default secure random cannot be createdjava.security.NoSuchAlgorithmException
- if the default secure random cannot be createdpublic static NKey fromPublicKey(char[] publicKey)
publicKey
- the string encoded public keypublic static NKey fromSeed(char[] seed)
seed
- the string encoded seed, see getSeed()
public static boolean isValidPublicAccountKey(char[] src)
src
- the encoded public keypublic static boolean isValidPublicClusterKey(char[] src)
src
- the encoded public keypublic static boolean isValidPublicOperatorKey(char[] src)
src
- the encoded public keypublic static boolean isValidPublicServerKey(char[] src)
src
- the encoded public keypublic static boolean isValidPublicUserKey(char[] src)
src
- the encoded public keypublic void clear()
public char[] getSeed()
public char[] getPublicKey() throws java.security.GeneralSecurityException, java.io.IOException
java.security.GeneralSecurityException
- if there is an encryption problemjava.io.IOException
- if there is a problem encoding the public
keypublic char[] getPrivateKey() throws java.security.GeneralSecurityException, java.io.IOException
java.security.GeneralSecurityException
- if there is an encryption problemjava.io.IOException
- if there is a problem encoding the keypublic java.security.KeyPair getKeyPair() throws java.security.GeneralSecurityException, java.io.IOException
java.security.GeneralSecurityException
- if there is an encryption problemjava.io.IOException
- if there is a problem encoding or decodingpublic NKey.Type getType()
public byte[] sign(byte[] input) throws java.security.GeneralSecurityException, java.io.IOException
input
- the bytes to signjava.security.GeneralSecurityException
- if there is an encryption problemjava.io.IOException
- if there is a problem reading the datapublic boolean verify(byte[] input, byte[] signature) throws java.security.GeneralSecurityException, java.io.IOException
input
- the bytes that were signedsignature
- the bytes for the signaturejava.security.GeneralSecurityException
- if there is an encryption problemjava.io.IOException
- if there is a problem reading the datapublic boolean equals(java.lang.Object o)
equals
in class java.lang.Object
public int hashCode()
hashCode
in class java.lang.Object