Class NKey


  • 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.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  NKey.Type
      NKeys use a prefix byte to indicate their intended owner: 'N' = server, 'C' = cluster, 'A' = account, and 'U' = user.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method 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.
      • Methods inherited from class java.lang.Object

        clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • createAccount

        public static NKey createAccount​(java.security.SecureRandom random)
                                  throws java.io.IOException,
                                         java.security.NoSuchProviderException,
                                         java.security.NoSuchAlgorithmException
        Create an Account NKey from the provided random number generator. If no random is provided, SecureRandom.getInstance("SHA1PRNG", "SUN") will be used to creat eone. The new NKey contains the private seed, which should be saved in a secure location.
        Parameters:
        random - A secure random provider
        Returns:
        the new Nkey
        Throws:
        java.io.IOException - if the seed cannot be encoded to a string
        java.security.NoSuchProviderException - if the default secure random cannot be created
        java.security.NoSuchAlgorithmException - if the default secure random cannot be created
      • createCluster

        public static NKey createCluster​(java.security.SecureRandom random)
                                  throws java.io.IOException,
                                         java.security.NoSuchProviderException,
                                         java.security.NoSuchAlgorithmException
        Create an Cluster NKey from the provided random number generator. If no random is provided, SecureRandom.getInstance("SHA1PRNG", "SUN") will be used to creat eone. The new NKey contains the private seed, which should be saved in a secure location.
        Parameters:
        random - A secure random provider
        Returns:
        the new Nkey
        Throws:
        java.io.IOException - if the seed cannot be encoded to a string
        java.security.NoSuchProviderException - if the default secure random cannot be created
        java.security.NoSuchAlgorithmException - if the default secure random cannot be created
      • createOperator

        public static NKey createOperator​(java.security.SecureRandom random)
                                   throws java.io.IOException,
                                          java.security.NoSuchProviderException,
                                          java.security.NoSuchAlgorithmException
        Create an Operator NKey from the provided random number generator. If no random is provided, SecureRandom.getInstance("SHA1PRNG", "SUN") will be used to creat eone. The new NKey contains the private seed, which should be saved in a secure location.
        Parameters:
        random - A secure random provider
        Returns:
        the new Nkey
        Throws:
        java.io.IOException - if the seed cannot be encoded to a string
        java.security.NoSuchProviderException - if the default secure random cannot be created
        java.security.NoSuchAlgorithmException - if the default secure random cannot be created
      • createServer

        public static NKey createServer​(java.security.SecureRandom random)
                                 throws java.io.IOException,
                                        java.security.NoSuchProviderException,
                                        java.security.NoSuchAlgorithmException
        Create a Server NKey from the provided random number generator. If no random is provided, SecureRandom.getInstance("SHA1PRNG", "SUN") will be used to creat eone. The new NKey contains the private seed, which should be saved in a secure location.
        Parameters:
        random - A secure random provider
        Returns:
        the new Nkey
        Throws:
        java.io.IOException - if the seed cannot be encoded to a string
        java.security.NoSuchProviderException - if the default secure random cannot be created
        java.security.NoSuchAlgorithmException - if the default secure random cannot be created
      • createUser

        public static NKey createUser​(java.security.SecureRandom random)
                               throws java.io.IOException,
                                      java.security.NoSuchProviderException,
                                      java.security.NoSuchAlgorithmException
        Create a User NKey from the provided random number generator. If no random is provided, SecureRandom.getInstance("SHA1PRNG", "SUN") will be used to creat eone. The new NKey contains the private seed, which should be saved in a secure location.
        Parameters:
        random - A secure random provider
        Returns:
        the new Nkey
        Throws:
        java.io.IOException - if the seed cannot be encoded to a string
        java.security.NoSuchProviderException - if the default secure random cannot be created
        java.security.NoSuchAlgorithmException - if the default secure random cannot be created
      • fromPublicKey

        public static NKey fromPublicKey​(char[] publicKey)
        Create an NKey object from the encoded public key. This NKey can be used for verification but not for signing.
        Parameters:
        publicKey - the string encoded public key
        Returns:
        the new Nkey
      • fromSeed

        public static NKey fromSeed​(char[] seed)
        Creates an NKey object from a string encoded seed. This NKey can be used to sign or verify.
        Parameters:
        seed - the string encoded seed, see getSeed()
        Returns:
        the Nkey
      • isValidPublicAccountKey

        public static boolean isValidPublicAccountKey​(char[] src)
        Parameters:
        src - the encoded public key
        Returns:
        true if the public key is an account public key
      • isValidPublicClusterKey

        public static boolean isValidPublicClusterKey​(char[] src)
        Parameters:
        src - the encoded public key
        Returns:
        true if the public key is a cluster public key
      • isValidPublicOperatorKey

        public static boolean isValidPublicOperatorKey​(char[] src)
        Parameters:
        src - the encoded public key
        Returns:
        true if the public key is an operator public key
      • isValidPublicServerKey

        public static boolean isValidPublicServerKey​(char[] src)
        Parameters:
        src - the encoded public key
        Returns:
        true if the public key is a server public key
      • isValidPublicUserKey

        public static boolean isValidPublicUserKey​(char[] src)
        Parameters:
        src - the encoded public key
        Returns:
        true if the public key is a user public key
      • clear

        public void clear()
        Clear the seed and public key char arrays by filling them with random bytes then zero-ing them out. The nkey is unusable after this operation.
      • getSeed

        public char[] getSeed()
        Returns:
        the string encoded seed for this NKey
      • getPublicKey

        public char[] getPublicKey()
                            throws java.security.GeneralSecurityException,
                                   java.io.IOException
        Returns:
        the encoded public key for this NKey
        Throws:
        java.security.GeneralSecurityException - if there is an encryption problem
        java.io.IOException - if there is a problem encoding the public key
      • getPrivateKey

        public char[] getPrivateKey()
                             throws java.security.GeneralSecurityException,
                                    java.io.IOException
        Returns:
        the encoded private key for this NKey
        Throws:
        java.security.GeneralSecurityException - if there is an encryption problem
        java.io.IOException - if there is a problem encoding the key
      • getKeyPair

        public java.security.KeyPair getKeyPair()
                                         throws java.security.GeneralSecurityException,
                                                java.io.IOException
        Returns:
        A Java security keypair that represents this NKey in Java security form.
        Throws:
        java.security.GeneralSecurityException - if there is an encryption problem
        java.io.IOException - if there is a problem encoding or decoding
      • getType

        public NKey.Type getType()
        Returns:
        the Type of this NKey
      • sign

        public byte[] sign​(byte[] input)
                    throws java.security.GeneralSecurityException,
                           java.io.IOException
        Sign aribitrary binary input.
        Parameters:
        input - the bytes to sign
        Returns:
        the signature for the input from the NKey
        Throws:
        java.security.GeneralSecurityException - if there is an encryption problem
        java.io.IOException - if there is a problem reading the data
      • verify

        public boolean verify​(byte[] input,
                              byte[] signature)
                       throws java.security.GeneralSecurityException,
                              java.io.IOException
        Verify a signature.
        Parameters:
        input - the bytes that were signed
        signature - the bytes for the signature
        Returns:
        true if the signature matches this keys signature for the input.
        Throws:
        java.security.GeneralSecurityException - if there is an encryption problem
        java.io.IOException - if there is a problem reading the data
      • equals

        public boolean equals​(java.lang.Object o)
        Overrides:
        equals in class java.lang.Object
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class java.lang.Object