use of sun.security.pkcs.EncryptedPrivateKeyInfo in project jdk8u_jdk by JetBrains.
the class PKCS12KeyStore method engineSetKeyEntry.
/**
* Assigns the given key (that has already been protected) to the given
* alias.
*
* <p>If the protected key is of type
* <code>java.security.PrivateKey</code>, it must be accompanied by a
* certificate chain certifying the corresponding public key. If the
* underlying keystore implementation is of type <code>jks</code>,
* <code>key</code> must be encoded as an
* <code>EncryptedPrivateKeyInfo</code> as defined in the PKCS #8 standard.
*
* <p>If the given alias already exists, the keystore information
* associated with it is overridden by the given key (and possibly
* certificate chain).
*
* @param alias the alias name
* @param key the key (in protected format) to be associated with the alias
* @param chain the certificate chain for the corresponding public
* key (only useful if the protected key is of type
* <code>java.security.PrivateKey</code>).
*
* @exception KeyStoreException if this operation fails.
*/
public synchronized void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException {
// as defined in PKCS#8
try {
new EncryptedPrivateKeyInfo(key);
} catch (IOException ioe) {
throw new KeyStoreException("Private key is not stored" + " as PKCS#8 EncryptedPrivateKeyInfo: " + ioe, ioe);
}
PrivateKeyEntry entry = new PrivateKeyEntry();
entry.date = new Date();
if (debug != null) {
debug.println("Setting a protected private key at alias '" + alias + "'");
}
try {
// set the keyId to current date
entry.keyId = ("Time " + (entry.date).getTime()).getBytes("UTF8");
} catch (UnsupportedEncodingException ex) {
// Won't happen
}
// set the alias
entry.alias = alias.toLowerCase(Locale.ENGLISH);
entry.protectedPrivKey = key.clone();
if (chain != null) {
// validate cert-chain
if ((chain.length > 1) && (!validateChain(chain))) {
throw new KeyStoreException("Certificate chain is " + "not valid");
}
entry.chain = chain.clone();
certificateCount += chain.length;
if (debug != null) {
debug.println("Setting a " + entry.chain.length + "-certificate chain at alias '" + alias + "'");
}
}
// add the entry
privateKeyCount++;
entries.put(alias.toLowerCase(Locale.ENGLISH), entry);
}
use of sun.security.pkcs.EncryptedPrivateKeyInfo in project jdk8u_jdk by JetBrains.
the class PKCS12KeyStore method encryptPrivateKey.
/*
* Encrypt private key using Password-based encryption (PBE)
* as defined in PKCS#5.
*
* NOTE: By default, pbeWithSHAAnd3-KeyTripleDES-CBC algorithmID is
* used to derive the key and IV.
*
* @return encrypted private key encoded as EncryptedPrivateKeyInfo
*/
private byte[] encryptPrivateKey(byte[] data, KeyStore.PasswordProtection passwordProtection) throws IOException, NoSuchAlgorithmException, UnrecoverableKeyException {
byte[] key = null;
try {
String algorithm;
AlgorithmParameters algParams;
AlgorithmId algid;
// Initialize PBE algorithm and parameters
algorithm = passwordProtection.getProtectionAlgorithm();
if (algorithm != null) {
AlgorithmParameterSpec algParamSpec = passwordProtection.getProtectionParameters();
if (algParamSpec != null) {
algParams = AlgorithmParameters.getInstance(algorithm);
algParams.init(algParamSpec);
} else {
algParams = getAlgorithmParameters(algorithm);
}
} else {
// Check default key protection algorithm for PKCS12 keystores
algorithm = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
String prop = Security.getProperty(KEY_PROTECTION_ALGORITHM[0]);
if (prop == null) {
prop = Security.getProperty(KEY_PROTECTION_ALGORITHM[1]);
}
return prop;
}
});
if (algorithm == null || algorithm.isEmpty()) {
algorithm = "PBEWithSHA1AndDESede";
}
algParams = getAlgorithmParameters(algorithm);
}
ObjectIdentifier pbeOID = mapPBEAlgorithmToOID(algorithm);
if (pbeOID == null) {
throw new IOException("PBE algorithm '" + algorithm + " 'is not supported for key entry protection");
}
// Use JCE
SecretKey skey = getPBEKey(passwordProtection.getPassword());
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, skey, algParams);
byte[] encryptedKey = cipher.doFinal(data);
algid = new AlgorithmId(pbeOID, cipher.getParameters());
if (debug != null) {
debug.println(" (Cipher algorithm: " + cipher.getAlgorithm() + ")");
}
// wrap encrypted private key in EncryptedPrivateKeyInfo
// as defined in PKCS#8
EncryptedPrivateKeyInfo encrInfo = new EncryptedPrivateKeyInfo(algid, encryptedKey);
key = encrInfo.getEncoded();
} catch (Exception e) {
UnrecoverableKeyException uke = new UnrecoverableKeyException("Encrypt Private Key failed: " + e.getMessage());
uke.initCause(e);
throw uke;
}
return key;
}
use of sun.security.pkcs.EncryptedPrivateKeyInfo in project jdk8u_jdk by JetBrains.
the class PKCS12KeyStore method createSafeContent.
/*
* Create SafeContent Data content type.
* Includes encrypted secret key in a SafeBag of type SecretBag.
* Includes encrypted private key in a SafeBag of type PKCS8ShroudedKeyBag.
* Each PKCS8ShroudedKeyBag includes pkcs12 attributes
* (see comments in getBagAttributes)
*/
private byte[] createSafeContent() throws CertificateException, IOException {
DerOutputStream out = new DerOutputStream();
for (Enumeration<String> e = engineAliases(); e.hasMoreElements(); ) {
String alias = e.nextElement();
Entry entry = entries.get(alias);
if (entry == null || (!(entry instanceof KeyEntry))) {
continue;
}
DerOutputStream safeBag = new DerOutputStream();
KeyEntry keyEntry = (KeyEntry) entry;
// DER encode the private key
if (keyEntry instanceof PrivateKeyEntry) {
// Create SafeBag of type pkcs8ShroudedKeyBag
safeBag.putOID(PKCS8ShroudedKeyBag_OID);
// get the encrypted private key
byte[] encrBytes = ((PrivateKeyEntry) keyEntry).protectedPrivKey;
EncryptedPrivateKeyInfo encrInfo = null;
try {
encrInfo = new EncryptedPrivateKeyInfo(encrBytes);
} catch (IOException ioe) {
throw new IOException("Private key not stored as " + "PKCS#8 EncryptedPrivateKeyInfo" + ioe.getMessage());
}
// Wrap the EncryptedPrivateKeyInfo in a context-specific tag.
DerOutputStream bagValue = new DerOutputStream();
bagValue.write(encrInfo.getEncoded());
safeBag.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), bagValue);
// DER encode the secret key
} else if (keyEntry instanceof SecretKeyEntry) {
// Create SafeBag of type SecretBag
safeBag.putOID(SecretBag_OID);
// Create a SecretBag
DerOutputStream secretBag = new DerOutputStream();
secretBag.putOID(PKCS8ShroudedKeyBag_OID);
// Write secret key in a context-specific tag
DerOutputStream secretKeyValue = new DerOutputStream();
secretKeyValue.putOctetString(((SecretKeyEntry) keyEntry).protectedSecretKey);
secretBag.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), secretKeyValue);
// Wrap SecretBag in a Sequence
DerOutputStream secretBagSeq = new DerOutputStream();
secretBagSeq.write(DerValue.tag_Sequence, secretBag);
byte[] secretBagValue = secretBagSeq.toByteArray();
// Wrap the secret bag in a context-specific tag.
DerOutputStream bagValue = new DerOutputStream();
bagValue.write(secretBagValue);
// Write SafeBag value
safeBag.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0), bagValue);
} else {
// skip this entry
continue;
}
// write SafeBag Attributes
byte[] bagAttrs = getBagAttributes(alias, entry.keyId, entry.attributes);
safeBag.write(bagAttrs);
// wrap as Sequence
out.write(DerValue.tag_Sequence, safeBag);
}
// wrap as Sequence
DerOutputStream safeBagValue = new DerOutputStream();
safeBagValue.write(DerValue.tag_Sequence, out);
return safeBagValue.toByteArray();
}
use of sun.security.pkcs.EncryptedPrivateKeyInfo in project jdk8u_jdk by JetBrains.
the class JavaKeyStore method engineGetKey.
/**
* Returns the key associated with the given alias, using the given
* password to recover it.
*
* @param alias the alias name
* @param password the password for recovering the key
*
* @return the requested key, or null if the given alias does not exist
* or does not identify a <i>key entry</i>.
*
* @exception NoSuchAlgorithmException if the algorithm for recovering the
* key cannot be found
* @exception UnrecoverableKeyException if the key cannot be recovered
* (e.g., the given password is wrong).
*/
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
Object entry = entries.get(convertAlias(alias));
if (entry == null || !(entry instanceof KeyEntry)) {
return null;
}
if (password == null) {
throw new UnrecoverableKeyException("Password must not be null");
}
KeyProtector keyProtector = new KeyProtector(password);
byte[] encrBytes = ((KeyEntry) entry).protectedPrivKey;
EncryptedPrivateKeyInfo encrInfo;
byte[] plain;
try {
encrInfo = new EncryptedPrivateKeyInfo(encrBytes);
} catch (IOException ioe) {
throw new UnrecoverableKeyException("Private key not stored as " + "PKCS #8 " + "EncryptedPrivateKeyInfo");
}
return keyProtector.recover(encrInfo);
}
use of sun.security.pkcs.EncryptedPrivateKeyInfo in project jdk8u_jdk by JetBrains.
the class KeyProtector method protect.
/*
* Protects the given plaintext key, using the password provided at
* construction time.
*/
public byte[] protect(Key key) throws KeyStoreException {
int i;
int numRounds;
byte[] digest;
// offset in xorKey where next digest will be stored
int xorOffset;
int encrKeyOffset = 0;
if (key == null) {
throw new IllegalArgumentException("plaintext key can't be null");
}
if (!"PKCS#8".equalsIgnoreCase(key.getFormat())) {
throw new KeyStoreException("Cannot get key bytes, not PKCS#8 encoded");
}
byte[] plainKey = key.getEncoded();
if (plainKey == null) {
throw new KeyStoreException("Cannot get key bytes, encoding not supported");
}
// Determine the number of digest rounds
numRounds = plainKey.length / DIGEST_LEN;
if ((plainKey.length % DIGEST_LEN) != 0)
numRounds++;
// Create a random salt
byte[] salt = new byte[SALT_LEN];
SecureRandom random = new SecureRandom();
random.nextBytes(salt);
// Set up the byte array which will be XORed with "plainKey"
byte[] xorKey = new byte[plainKey.length];
// Compute the digests, and store them in "xorKey"
for (i = 0, xorOffset = 0, digest = salt; i < numRounds; i++, xorOffset += DIGEST_LEN) {
md.update(passwdBytes);
md.update(digest);
digest = md.digest();
md.reset();
// Copy the digest into "xorKey"
if (i < numRounds - 1) {
System.arraycopy(digest, 0, xorKey, xorOffset, digest.length);
} else {
System.arraycopy(digest, 0, xorKey, xorOffset, xorKey.length - xorOffset);
}
}
// XOR "plainKey" with "xorKey", and store the result in "tmpKey"
byte[] tmpKey = new byte[plainKey.length];
for (i = 0; i < tmpKey.length; i++) {
tmpKey[i] = (byte) (plainKey[i] ^ xorKey[i]);
}
// Store salt and "tmpKey" in "encrKey"
byte[] encrKey = new byte[salt.length + tmpKey.length + DIGEST_LEN];
System.arraycopy(salt, 0, encrKey, encrKeyOffset, salt.length);
encrKeyOffset += salt.length;
System.arraycopy(tmpKey, 0, encrKey, encrKeyOffset, tmpKey.length);
encrKeyOffset += tmpKey.length;
// Append digest(password, plainKey) as an integrity check to "encrKey"
md.update(passwdBytes);
Arrays.fill(passwdBytes, (byte) 0x00);
passwdBytes = null;
md.update(plainKey);
digest = md.digest();
md.reset();
System.arraycopy(digest, 0, encrKey, encrKeyOffset, digest.length);
// wrap the protected private key in a PKCS#8-style
// EncryptedPrivateKeyInfo, and returns its encoding
AlgorithmId encrAlg;
try {
encrAlg = new AlgorithmId(new ObjectIdentifier(KEY_PROTECTOR_OID));
return new EncryptedPrivateKeyInfo(encrAlg, encrKey).getEncoded();
} catch (IOException ioe) {
throw new KeyStoreException(ioe.getMessage());
}
}
Aggregations