All Implemented Interfaces:
Destroyable, DataStructure

public class PrivateKeyextends SimpleDataStructure implements Destroyable
Private (secret) key for the asymmetric encryption of an I2P destination.

Type and length:

  • The EncType is fixed at construction and never changes, and it determines the length: 256 bytes for the default EncType.ELGAMAL_2048, 32 for EncType.ECIES_X25519. KEYSIZE_BYTES is the default type's length only.
  • For ElGamal the array is the private exponent padded to the key size, which is why hashCode() uses the last 4 bytes - the leading ones are all zero.
  • Call destroy() when the key is no longer needed. That zeroes the array and returns it to the byte cache, so after it the key reports isDestroyed() and length() still returns the type's length but the data is gone.

Caching:

  • The derived public key is cached in memory: the first toPublic() computes it, later calls return the same PublicKey instance. A key built with the PrivateKey(EncType, byte[], PublicKey) constructor starts with the caller's instance. There is no key cache of any kind here, and no create() factory method - build the key directly, or read it from a PrivateKeyFile.

Thread safety:

  • Not thread-safe. The data cannot be reassigned once set, but the cached public key and the zeroing done by destroy() are unsynchronized writes to plain fields, and SimpleDataStructure.getData() hands out the backing array. Share a fully populated key, or pass it through a synchronized structure, and do not destroy() or write to the array while another thread may be using it.
  • Field Details

    • DEF_TYPE

      private static final EncType DEF_TYPE
      Type assumed when a key names none.
    • KEYSIZE_BYTES

      public static final int KEYSIZE_BYTES
      Default key size in bytes (256 for ElGamal).
    • _type

      private final EncType _type
      The encryption type of this key.
    • _pubKey

      private PublicKey _pubKey
      Cache of the matching public key, derived on first use.
  • Constructor Details

    • PrivateKey

      public PrivateKey()
      Constructor for an empty key of the default type, for reading from a stream. Call readBytes() or fromBase64() to fill it in.
    • PrivateKey

      public PrivateKey(EncType type)
      Constructor with type.
      Parameters:
      type - non-null
    • PrivateKey

      public PrivateKey(byte[] data)
      Private key from raw key data, of the default type.
      Parameters:
      data - key data, non-null, 256 bytes
      Throws:
      IllegalArgumentException - if data is null or the wrong length
    • PrivateKey

      public PrivateKey(EncType type, byte[] data)
      Constructor with type and data.
      Parameters:
      type - non-null
      data - must be non-null, and of the type's key length
      Throws:
      IllegalArgumentException - if data is null or the wrong length, or if type is null
    • PrivateKey

      public PrivateKey(EncType type, byte[] data, PublicKey pubKey)
      Constructor with type, data, and cached public key.
      Parameters:
      type - non-null
      data - must be non-null, and of the type's key length
      pubKey - corresponding pubKey to be cached, non-null
      Throws:
      IllegalArgumentException - if data is null or the wrong length, or if pubKey is null or of another type
    • PrivateKey

      public PrivateKey(String base64Data) throws DataFormatException
      Private key of the default type from a string of base64 data.
      Parameters:
      base64Data - a string of base64 data (the output of .toBase64() called on a prior instance of PrivateKey)
      Throws:
      DataFormatException - if the data is not valid
  • Method Details

    • length

      public int length()
      Key length in bytes, determined by the encryption type.
      Specified by:
      length in class SimpleDataStructure
      Returns:
      the legal length of the byte array
    • getType

      public EncType getType()
      Encryption type of this private key.
      Returns:
      non-null
    • toPublic

      public PublicKey toPublic()
      Derives the PublicKey corresponding to the secret contents of this PrivateKey. As of 0.9.44 the result is cached, so every call after the first returns the same instance.
      Returns:
      a PublicKey object
      Throws:
      IllegalArgumentException - on bad key
    • destroy

      public void destroy()
      Destroy this key and clear its data, per the javax.security.auth.Destroyable interface. The data is zeroed and returned to the byte cache, the cached public key is dropped, and the key reports isDestroyed() afterwards. Calling this more than once is harmless.
      Specified by:
      destroy in interface Destroyable
    • isDestroyed

      public boolean isDestroyed()
      Whether this key has been destroyed.
      Specified by:
      isDestroyed in interface Destroyable
      Returns:
      true if destroy() has run and the key data has been zeroed, false while the key is still usable
    • toString

      public String toString()
      The type and the size, never the data, so the secret is not printed. Prints "null" for the data of a destroyed key.
      Overrides:
      toString in class SimpleDataStructure
      Returns:
      a string representation
    • hashCode

      public int hashCode()
      We assume the data has enough randomness in it, so use the last 4 bytes for speed. Overridden since we use short exponents, so the first 227 bytes are all zero. Non-default types hash the whole array instead.
      Overrides:
      hashCode in class SimpleDataStructure
      Returns:
      the hash code
    • equals

      public boolean equals(Object obj)
      Two private keys are equal when their types and data are equal. A key and a destroyed copy of it are not equal, since the data differs.
      Overrides:
      equals in class SimpleDataStructure
      Parameters:
      obj - the object to compare
      Returns:
      true if the types and data match