jceks

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2024 License: MIT Imports: 15 Imported by: 0

README

JCEKS (Java Cryptogaphy Extension Key Store)

Package jceks parses, pack, unpack JCEKS (Java Cryptogaphy Extension Key Store) files and extracts keys and certificates. This module only implements a fraction of the JCEKS cryptographic protocols.

Documentation

Index

Constants

View Source
const (

	// DigestSeparator is used to build the file's verification digest. The
	// digest is over the keystore password encoded as UTF-16, then this
	// string (yes, really — check the OpenJDK source) encoded as UTF-8, and
	// then the actual file data.
	DigestSeparator = "Mighty Aphrodite"

	// CertType is the certificate type string that is encoded into each
	// certificate's header in the keystore.
	CertType = "X.509"
)

Variables

View Source
var (
	// JavaKeyEncryptionOID1 is the object identifier for one type of
	// password-based encryption used in .jceks files.
	JavaKeyEncryptionOID1 = asn1.ObjectIdentifier{
		1, 3, 6, 1, 4, 1, 42, 2, 17, 1, 1,
	}

	// JavaKeyEncryptionOID2 is the object identifier for one type of
	// password-based encryption used in .jceks files.
	JavaKeyEncryptionOID2 = asn1.ObjectIdentifier{
		1, 3, 6, 1, 4, 1, 42, 2, 19, 1,
	}
)

Functions

func ComputeDigest

func ComputeDigest(raw []byte, passwd string) []byte

ComputeDigest performs the custom hash function over the given file data. DO NOT RE-USE THIS CODE: this is an atrocious way to perform message authentication. Use the HMAC example from https://github.com/lwithers/go-crypto-examples instead. Note this construct is vulnerable to a length extension attack, which is actually exploitable if the JCEKS reader code does not properly check the "number of entries" value.

func DecryptJavaKeyEncryption1

func DecryptJavaKeyEncryption1(ciphertext []byte, password string,
) ([]byte, error)

DecryptJavaKeyEncryption1 decrypts ciphertext encrypted with one of the Java key encryption algorithms.

PLEASE NOTE: this appears to be custom crypto. You should *never* do this. DO NOT RE-USE THIS CODE. If you want an example of how to encrypt a blob of data or a file with a password, then see the password-encrypt example at:

https://github.com/lwithers/go-crypto-examples

func DecryptPKCS8

func DecryptPKCS8(raw []byte, password string) ([]byte, error)

DecryptPKCS8 decrypts a PKCS#8 EncryptedPrivateKeyInfo, presumably returning a marshalled PrivateKeyInfo structure. It only knows how to handle the two encryption algorithms that are used by the Java keytool program.

func EncryptJavaKeyEncryption1

func EncryptJavaKeyEncryption1(plaintext []byte, password string,
) ([]byte, error)

EncryptJavaKeyEncryption1 encrypts plaintext with one of the Java key encryption algorithms.

PLEASE NOTE: this appears to be custom crypto. You should *never* do this. DO NOT RE-USE THIS CODE. If you want an example of how to encrypt a blob of data or a file with a password, then see the password-encrypt example at:

https://github.com/lwithers/go-crypto-examples

func MarshalPKCS8

func MarshalPKCS8(key interface{}) ([]byte, error)

MarshalPKCS8 marshals an RSA or EC private key into an (unencrypted) PKCS#8 PrivateKeyInfo structure. It returns the DER-encoded structure.

func PasswordUTF16

func PasswordUTF16(passwd string) []byte

PasswordUTF16 returns a password encoded in UTF-16, big-endian byte order.

Types

type Cert

type Cert struct {
	// Alias is a name used to refer to this certificate.
	Alias string

	// Timestamp records when this record was created.
	Timestamp time.Time

	// Raw is the raw X.509 certificate marshalled in DER form.
	Raw []byte

	// CertErr is set if there is an error parsing the certificate.
	CertErr error

	// Cert is the parsed X.509 certificate.
	Cert *x509.Certificate
}

Cert holds a certificate to trust.

type EncryptedPrivateKeyInfo

type EncryptedPrivateKeyInfo struct {
	// Algo identifies the encryption algorithm (and any associated
	// parameters) used to encrypt EncryptedData.
	Algo pkix.AlgorithmIdentifier

	// EncryptedData is an encrypted, marshalled PrivateKeyInfo.
	EncryptedData []byte
}

EncryptedPrivateKeyInfo is the ASN.1 structure used to hold an encrypted private key. It is defined in RFC 5208 § 6:

https://tools.ietf.org/html/rfc5208#section-6

type Keypair

type Keypair struct {
	// Alias is a name used to refer to this keypair.
	Alias string

	// Timestamp records when this record was created.
	Timestamp time.Time

	// PrivKeyErr is set if an error is encountered during decryption or
	// unmarshalling of the decrypted key.
	PrivKeyErr error

	// EncryptedKey is the raw PKCS#8 marshalled EncryptedPrivateKeyInfo.
	EncryptedKey []byte

	// RawKey is the raw PKCS#8 marshalled PrivateKeyInfo, after it has
	// been decrypted. It will not have been set if decryption failed.
	RawKey []byte

	// PrivateKey is the unmarshalled private key. It will not have been
	// set if decryption failed or if unmarshalling failed.
	PrivateKey interface{}

	// CertChain is a chain of certificates associated with the private key.
	// The first entry in the chain (index 0) should correspond to
	// PrivateKey; there should then follow any intermediate CAs. In
	// general the root CA should not be part of the chain.
	CertChain []*KeypairCert
}

Keypair holds a private key and an associated certificate chain.

type KeypairCert

type KeypairCert struct {
	// Raw X.509 certificate data (in DER form).
	Raw []byte

	// Cert is the parsed X.509 certificate. It is nil if the certificate
	// could not be parsed.
	Cert *x509.Certificate

	// CertErr records any error encountered while parsing a certificate.
	CertErr error
}

KeypairCert is an entry in the certificate chain associated with a Keypair.

type Keystore

type Keystore struct {
	// Certs is a list of CA certificates to trust. It may contain either
	// root or intermediate CA certificates. It should not contain end-user
	// certificates.
	Certs []*Cert

	// Keypairs is a list of private keys. Each key may have a certificate
	// chain associated with it.
	Keypairs []*Keypair
}

Keystore represents a single JCEKS file. It holds a list of certificates and a list of keypairs (private keys with associated certificate chains).

func Parse

func Parse(raw []byte, opts *Options) (*Keystore, error)

Parse a JCEKS file. If desired, opts may be specified to provide more control over the parsing. If nil, then we will use an empty password when attempting to decrypt keys and will not attempt to verify the digest stored in the file.

Errors encountered when parsing a certificate, or decrypting or parsing a private key, are stored within the returned Keystore structure. These do not lead to the parse failing and will not be returned as an error by the top level function. Unrecoverable errors (i.e. malformed file) will result in the Parse function returning an error. If digest verification is requested and the password or the digest is incorrect, an error will also be returned. If any useful data has been extracted it will be returned as a partial Keystore.

func (*Keystore) Pack

func (ks *Keystore) Pack(opts *Options) ([]byte, error)

Pack writes a JCEKS file. opts must be specified, and the SkipVerifyDigest option will be ignored. The password will always be taken from opts, and if it is an empty string then an empty string will be used for the password. This function requires that all certificates and private keys are present, so be sure to check this if you have obtained a Keystore using Parse(). Each record should have a unique alias (not checked). If a record's Timestamp is zero then the current system time will be queried and be used.

type Options

type Options struct {
	// Password is used as part of a SHA-1 digest over the .jceks file.
	Password string

	// SkipVerifyDigest can be set to skip digest verification when loading
	// a keystore file. This will inhibit errors from Parse if you don't
	// know the password.
	SkipVerifyDigest bool

	// KeyPasswords are used to generate the "encryption" keys for stored
	// private keys. The map's key is the alias of the private key, and the
	// value is the password. If there is no entry in the map for a given
	// alias, then the top-level Password is inherited. Empty strings are
	// interpreted as an empty password, so use delete() if you truly want
	// to delete values.
	KeyPasswords map[string]string
}

Options for manipulating a keystore. These allow the caller to specify the password(s) used, or to skip the digest verification if the password is unknown.

type PrivateKeyInfo

type PrivateKeyInfo struct {
	// Version of structure. Should be zero.
	Version int

	// Algo denotes the private key algorithm (e.g. RSA).
	Algo pkix.AlgorithmIdentifier

	// PrivateKey is the marshalled private key. It should be interpreted
	// according to Algo.
	PrivateKey []byte
}

PrivateKeyInfo is the ASN.1 structure used to hold a private key. It is defined in RFC 52080 § 5:

https://tools.ietf.org/html/rfc5208#section-5

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL