use of org.kse.crypto.CryptoException in project keystore-explorer by kaikramer.
the class OpenSslPvkUtil method loadEncrypted.
/**
* Load an encrypted OpenSSL private key from the specified stream. The
* encoding of the private key will be PEM.
*
* @param is
* Stream load the encrypted private key from
* @param password
* Password to decrypt
* @return The private key
* @throws PrivateKeyUnencryptedException
* If private key is unencrypted
* @throws PrivateKeyPbeNotSupportedException
* If private key PBE algorithm is not supported
* @throws CryptoException
* Problem encountered while loading the private key
* @throws IOException
* An I/O error occurred
*/
public static PrivateKey loadEncrypted(InputStream is, Password password) throws CryptoException, IOException {
byte[] streamContents = ReadUtil.readFully(is);
EncryptionType encType = getEncryptionType(new ByteArrayInputStream(streamContents));
if (encType == null) {
throw new CryptoException(res.getString("NotValidOpenSsl.exception.message"));
}
if (encType == UNENCRYPTED) {
throw new PrivateKeyUnencryptedException(res.getString("OpenSslIsUnencrypted.exception.message"));
}
// OpenSSL must be encrypted and therefore must be PEM
PemInfo pemInfo = PemUtil.decode(new ByteArrayInputStream(streamContents));
byte[] encKey = pemInfo.getContent();
PemAttributes attributes = pemInfo.getAttributes();
String dekInfo = attributes.get(DEK_INFO_ATTR_NAME).getValue();
// Split DEK-Info into encryption pbe algorithm and salt
int separator = dekInfo.indexOf(',');
if (separator == -1) {
throw new CryptoException(MessageFormat.format("OpenSslDekInfoMalformed.exception.message", dekInfo));
}
String encAlg = dekInfo.substring(0, separator);
String salt = dekInfo.substring(separator + 1);
byte[] saltBytes = hexToBytes(salt);
OpenSslPbeType pbeType = OpenSslPbeType.resolveDekInfo(encAlg);
if (pbeType == null) {
throw new PrivateKeyPbeNotSupportedException(encAlg, MessageFormat.format(res.getString("PrivateKeyWrappingAlgUnsupported.exception.message"), encAlg));
}
try {
byte[] decryptKey = deriveKeyFromPassword(password, saltBytes, pbeType.keySize());
// Create cipher - use all of the salt as the IV
Cipher cipher = createCipher(pbeType.jceCipher(), decryptKey, saltBytes, DECRYPT_MODE);
byte[] key = cipher.doFinal(encKey);
return load(new ByteArrayInputStream(key));
} catch (GeneralSecurityException ex) {
throw new CryptoException(MessageFormat.format("OpenSslDecryptionFailed.exception.message", pbeType.friendly()), ex);
}
}
use of org.kse.crypto.CryptoException in project keystore-explorer by kaikramer.
the class Pkcs8Util method getPrivateKeyAlgorithm.
private static String getPrivateKeyAlgorithm(byte[] unencPkcs8) throws IOException, CryptoException {
try (ASN1InputStream ais = new ASN1InputStream(new ByteArrayInputStream(unencPkcs8))) {
ASN1Encodable derEnc;
try {
derEnc = ais.readObject();
} catch (OutOfMemoryError err) {
// Happens with some non ASN.1 files
throw new CryptoException(res.getString("NoUnencryptedPkcs8.exception.message"));
}
if (!(derEnc instanceof ASN1Sequence)) {
throw new CryptoException(res.getString("NoUnencryptedPkcs8.exception.message"));
}
ASN1Sequence privateKeyInfoSequence = (ASN1Sequence) derEnc;
derEnc = privateKeyInfoSequence.getObjectAt(1);
if (!(derEnc instanceof ASN1Sequence)) {
throw new CryptoException(res.getString("NoUnencryptedPkcs8.exception.message"));
}
ASN1Sequence privateKeyAlgorithmSequence = (ASN1Sequence) derEnc;
derEnc = privateKeyAlgorithmSequence.getObjectAt(0);
if (!(derEnc instanceof ASN1ObjectIdentifier)) {
throw new CryptoException(res.getString("NoUnencryptedPkcs8.exception.message"));
}
ASN1ObjectIdentifier algorithmOid = (ASN1ObjectIdentifier) derEnc;
String oid = algorithmOid.getId();
if (oid.equals(RSA.oid())) {
return RSA.jce();
} else if (oid.equals(DSA.oid())) {
return DSA.jce();
} else {
// Unknown algorithm
return oid;
}
}
}
use of org.kse.crypto.CryptoException in project keystore-explorer by kaikramer.
the class Pkcs8Util method getEncrypted.
/**
* PKCS #8 encode and encrypt a private key.
*
* @return The encrypted encoding
* @param privateKey
* The private key
* @param pbeType
* PBE algorithm to use for encryption
* @param password
* Encryption password
* @throws CryptoException
* Problem encountered while getting the encoded private key
* @throws IOException
* If an I/O error occurred
*/
public static byte[] getEncrypted(PrivateKey privateKey, Pkcs8PbeType pbeType, Password password) throws CryptoException, IOException {
try {
byte[] pkcs8 = get(privateKey);
// Generate PBE secret key from password
SecretKeyFactory keyFact = SecretKeyFactory.getInstance(pbeType.jce());
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
SecretKey pbeKey = keyFact.generateSecret(pbeKeySpec);
// Generate random salt and iteration count
byte[] salt = generateSalt();
int iterationCount = generateIterationCount();
// Store in algorithm parameters
PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, iterationCount);
AlgorithmParameters params = AlgorithmParameters.getInstance(pbeType.jce());
params.init(pbeParameterSpec);
// Create PBE cipher from key and params
Cipher cipher = Cipher.getInstance(pbeType.jce());
cipher.init(Cipher.ENCRYPT_MODE, pbeKey, params);
// Encrypt key
byte[] encPkcs8 = cipher.doFinal(pkcs8);
// Create and return encrypted private key information
EncryptedPrivateKeyInfo encPrivateKeyInfo = new EncryptedPrivateKeyInfo(params, encPkcs8);
return encPrivateKeyInfo.getEncoded();
} catch (GeneralSecurityException ex) {
throw new CryptoException("NoEncryptPkcs8PrivateKey.exception.message", ex);
}
}
use of org.kse.crypto.CryptoException in project keystore-explorer by kaikramer.
the class Pkcs8Util method load.
/**
* Load an unencrypted PKCS #8 private key from the stream. The encoding of
* the private key may be PEM or DER.
*
* @param is
* Stream to load the unencrypted private key from
* @return The private key
* @throws PrivateKeyEncryptedException
* If private key is encrypted
* @throws CryptoException
* Problem encountered while loading the private key
* @throws IOException
* If an I/O error occurred
*/
public static PrivateKey load(InputStream is) throws CryptoException, IOException {
byte[] streamContents = ReadUtil.readFully(is);
// Check pkcs #8 is unencrypted
EncryptionType encType = getEncryptionType(new ByteArrayInputStream(streamContents));
if (encType == null) {
// Not a valid PKCS #8 private key
throw new CryptoException(res.getString("NotValidPkcs8.exception.message"));
}
if (encType == ENCRYPTED) {
throw new PrivateKeyEncryptedException(res.getString("Pkcs8IsEncrypted.exception.message"));
}
byte[] pvkBytes = null;
// Check if stream is PEM encoded
PemInfo pemInfo = PemUtil.decode(new ByteArrayInputStream(streamContents));
if (pemInfo != null) {
// It is - get DER from PEM
pvkBytes = pemInfo.getContent();
}
/*
* If we haven't got the key bytes via PEM then just use stream
* contents directly (assume it is DER encoded)
*/
if (pvkBytes == null) {
// Read in private key bytes
pvkBytes = streamContents;
}
try {
// Determine private key algorithm from key bytes
String privateKeyAlgorithm = getPrivateKeyAlgorithm(pvkBytes);
// Convert bytes to private key
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pvkBytes);
KeyFactory keyFactory = KeyFactory.getInstance(privateKeyAlgorithm);
PrivateKey pvk = keyFactory.generatePrivate(privateKeySpec);
return pvk;
} catch (NoSuchAlgorithmException ex) {
throw new CryptoException(res.getString("NoLoadPkcs8PrivateKey.exception.message"), ex);
} catch (InvalidKeySpecException ex) {
throw new CryptoException(res.getString("NoLoadPkcs8PrivateKey.exception.message"), ex);
}
}
use of org.kse.crypto.CryptoException in project keystore-explorer by kaikramer.
the class KeyIdentifierGenerator method generate64BitHashId.
/**
* Generate 64 bit hash key identifier.
*
* @return Key identifier
* @throws CryptoException
* If generation fails
*/
public byte[] generate64BitHashId() throws CryptoException {
try {
DERBitString publicKeyBitString = encodePublicKeyAsBitString(publicKey);
byte[] hash = DigestUtil.getMessageDigest(publicKeyBitString.getBytes(), DigestType.SHA1);
byte[] subHash = Arrays.copyOfRange(hash, 12, 20);
subHash[0] &= 0x0F;
subHash[0] |= 0x40;
return subHash;
} catch (IOException ex) {
throw new CryptoException(res.getString("NoGenerateKeyIdentifier.exception.message"), ex);
}
}
Aggregations