提交 b691337a 编写于 作者: V vinnie

8006591: Protect keystore entries using stronger PBE algorithms

Reviewed-by: mullan
上级 45399bfb
/* /*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,6 +29,7 @@ import java.io.*; ...@@ -29,6 +29,7 @@ import java.io.*;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.*; import java.util.*;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
...@@ -239,6 +240,8 @@ public class KeyStore { ...@@ -239,6 +240,8 @@ public class KeyStore {
ProtectionParameter, javax.security.auth.Destroyable { ProtectionParameter, javax.security.auth.Destroyable {
private final char[] password; private final char[] password;
private final String protectionAlgorithm;
private final AlgorithmParameterSpec protectionParameters;
private volatile boolean destroyed = false; private volatile boolean destroyed = false;
/** /**
...@@ -251,6 +254,72 @@ public class KeyStore { ...@@ -251,6 +254,72 @@ public class KeyStore {
*/ */
public PasswordProtection(char[] password) { public PasswordProtection(char[] password) {
this.password = (password == null) ? null : password.clone(); this.password = (password == null) ? null : password.clone();
this.protectionAlgorithm = null;
this.protectionParameters = null;
}
/**
* Creates a password parameter and specifies the protection algorithm
* and associated parameters to use when encrypting a keystore entry.
* <p>
* The specified {@code password} is cloned before it is stored in the
* new {@code PasswordProtection} object.
*
* @param password the password, which may be {@code null}
* @param protectionAlgorithm the encryption algorithm name, for
* example, {@code PBEWithHmacSHA256AndAES_256}.
* See the Cipher section in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
* Java Cryptography Architecture Standard Algorithm Name
* Documentation</a>
* for information about standard encryption algorithm names.
* @param protectionParameters the encryption algorithm parameter
* specification, which may be {@code null}
* @exception NullPointerException if {@code protectionAlgorithm} is
* {@code null}
*
* @since 1.8
*/
public PasswordProtection(char[] password, String protectionAlgorithm,
AlgorithmParameterSpec protectionParameters) {
if (protectionAlgorithm == null) {
throw new NullPointerException("invalid null input");
}
this.password = (password == null) ? null : password.clone();
this.protectionAlgorithm = protectionAlgorithm;
this.protectionParameters = protectionParameters;
}
/**
* Gets the name of the protection algorithm.
* If none was set then the keystore provider will use its default
* protection algorithm. The name of the default protection algorithm
* for a given keystore type is set using the
* {@code 'keystore.<type>.keyProtectionAlgorithm'} security property.
* For example, the
* {@code keystore.PKCS12.keyProtectionAlgorithm} property stores the
* name of the default key protection algorithm used for PKCS12
* keystores. If the security property is not set, an
* implementation-specific algorithm will be used.
*
* @return the algorithm name, or {@code null} if none was set
*
* @since 1.8
*/
public String getProtectionAlgorithm() {
return protectionAlgorithm;
}
/**
* Gets the parameters supplied for the protection algorithm.
*
* @return the algorithm parameter specification, or {@code null},
* if none was set
*
* @since 1.8
*/
public AlgorithmParameterSpec getProtectionParameters() {
return protectionParameters;
} }
/** /**
......
/* /*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,19 +26,25 @@ ...@@ -26,19 +26,25 @@
package sun.security.pkcs12; package sun.security.pkcs12;
import java.io.*; import java.io.*;
import java.security.AccessController;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.Key; import java.security.Key;
import java.security.KeyStore;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PrivilegedAction;
import java.security.KeyStoreSpi; import java.security.KeyStoreSpi;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.UnrecoverableEntryException;
import java.security.UnrecoverableKeyException; import java.security.UnrecoverableKeyException;
import java.security.Security;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*; import java.util.*;
...@@ -49,8 +55,10 @@ import javax.crypto.SecretKeyFactory; ...@@ -49,8 +55,10 @@ import javax.crypto.SecretKeyFactory;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.security.auth.DestroyFailedException;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
import sun.security.util.Debug;
import sun.security.util.DerInputStream; import sun.security.util.DerInputStream;
import sun.security.util.DerOutputStream; import sun.security.util.DerOutputStream;
import sun.security.util.DerValue; import sun.security.util.DerValue;
...@@ -119,6 +127,13 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -119,6 +127,13 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
public static final int VERSION_3 = 3; public static final int VERSION_3 = 3;
private static final String[] KEY_PROTECTION_ALGORITHM = {
"keystore.pkcs12.keyProtectionAlgorithm",
"keystore.PKCS12.keyProtectionAlgorithm"
};
private static final Debug debug = Debug.getInstance("pkcs12");
private static final int keyBag[] = {1, 2, 840, 113549, 1, 12, 10, 1, 2}; private static final int keyBag[] = {1, 2, 840, 113549, 1, 12, 10, 1, 2};
private static final int certBag[] = {1, 2, 840, 113549, 1, 12, 10, 1, 3}; private static final int certBag[] = {1, 2, 840, 113549, 1, 12, 10, 1, 3};
...@@ -131,6 +146,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -131,6 +146,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
{1, 2, 840, 113549, 1, 12, 1, 6}; {1, 2, 840, 113549, 1, 12, 1, 6};
private static final int pbeWithSHAAnd3KeyTripleDESCBC[] = private static final int pbeWithSHAAnd3KeyTripleDESCBC[] =
{1, 2, 840, 113549, 1, 12, 1, 3}; {1, 2, 840, 113549, 1, 12, 1, 3};
private static final int pbes2[] = {1, 2, 840, 113549, 1, 5, 13};
private static ObjectIdentifier PKCS8ShroudedKeyBag_OID; private static ObjectIdentifier PKCS8ShroudedKeyBag_OID;
private static ObjectIdentifier CertBag_OID; private static ObjectIdentifier CertBag_OID;
...@@ -139,6 +155,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -139,6 +155,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
private static ObjectIdentifier PKCS9CertType_OID; private static ObjectIdentifier PKCS9CertType_OID;
private static ObjectIdentifier pbeWithSHAAnd40BitRC2CBC_OID; private static ObjectIdentifier pbeWithSHAAnd40BitRC2CBC_OID;
private static ObjectIdentifier pbeWithSHAAnd3KeyTripleDESCBC_OID; private static ObjectIdentifier pbeWithSHAAnd3KeyTripleDESCBC_OID;
private static ObjectIdentifier pbes2_OID;
private int counter = 0; private int counter = 0;
private static final int iterationCount = 1024; private static final int iterationCount = 1024;
...@@ -163,6 +180,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -163,6 +180,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
new ObjectIdentifier(pbeWithSHAAnd40BitRC2CBC); new ObjectIdentifier(pbeWithSHAAnd40BitRC2CBC);
pbeWithSHAAnd3KeyTripleDESCBC_OID = pbeWithSHAAnd3KeyTripleDESCBC_OID =
new ObjectIdentifier(pbeWithSHAAnd3KeyTripleDESCBC); new ObjectIdentifier(pbeWithSHAAnd3KeyTripleDESCBC);
pbes2_OID = new ObjectIdentifier(pbes2);
} catch (IOException ioe) { } catch (IOException ioe) {
// should not happen // should not happen
} }
...@@ -288,6 +306,12 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -288,6 +306,12 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
KeyFactory kfac = KeyFactory.getInstance(algName); KeyFactory kfac = KeyFactory.getInstance(algName);
key = kfac.generatePrivate(kspec); key = kfac.generatePrivate(kspec);
if (debug != null) {
debug.println("Retrieved a protected private key at alias '" +
alias + "'");
}
} catch (Exception e) { } catch (Exception e) {
UnrecoverableKeyException uke = UnrecoverableKeyException uke =
new UnrecoverableKeyException("Get Key failed: " + new UnrecoverableKeyException("Get Key failed: " +
...@@ -315,6 +339,13 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -315,6 +339,13 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (entry.chain == null) { if (entry.chain == null) {
return null; return null;
} else { } else {
if (debug != null) {
debug.println("Retrieved a " +
entry.chain.length +
"-certificate chain at alias '" + alias + "'");
}
return entry.chain.clone(); return entry.chain.clone();
} }
} else { } else {
...@@ -343,6 +374,12 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -343,6 +374,12 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (entry.chain == null) { if (entry.chain == null) {
return null; return null;
} else { } else {
if (debug != null) {
debug.println("Retrieved a certificate at alias '" + alias +
"'");
}
return entry.chain[0]; return entry.chain[0];
} }
} else { } else {
...@@ -392,6 +429,28 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -392,6 +429,28 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
public synchronized void engineSetKeyEntry(String alias, Key key, public synchronized void engineSetKeyEntry(String alias, Key key,
char[] password, Certificate[] chain) char[] password, Certificate[] chain)
throws KeyStoreException throws KeyStoreException
{
KeyStore.PasswordProtection passwordProtection =
new KeyStore.PasswordProtection(password);
try {
setKeyEntry(alias, key, passwordProtection, chain);
} finally {
try {
passwordProtection.destroy();
} catch (DestroyFailedException dfe) {
// ignore
}
}
}
/*
* Sets a key entry
*/
private void setKeyEntry(String alias, Key key,
KeyStore.PasswordProtection passwordProtection, Certificate[] chain)
throws KeyStoreException
{ {
try { try {
KeyEntry entry = new KeyEntry(); KeyEntry entry = new KeyEntry();
...@@ -401,8 +460,14 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -401,8 +460,14 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if ((key.getFormat().equals("PKCS#8")) || if ((key.getFormat().equals("PKCS#8")) ||
(key.getFormat().equals("PKCS8"))) { (key.getFormat().equals("PKCS8"))) {
// Encrypt the private key // Encrypt the private key
if (debug != null) {
debug.println("Setting a protected private key at " +
"alias '" + alias + "'");
}
entry.protectedPrivKey = entry.protectedPrivKey =
encryptPrivateKey(key.getEncoded(), password); encryptPrivateKey(key.getEncoded(), passwordProtection);
} else { } else {
throw new KeyStoreException("Private key is not encoded" + throw new KeyStoreException("Private key is not encoded" +
"as PKCS#8"); "as PKCS#8");
...@@ -418,6 +483,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -418,6 +483,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
throw new KeyStoreException("Certificate chain is " + throw new KeyStoreException("Certificate chain is " +
"not validate"); "not validate");
entry.chain = chain.clone(); entry.chain = chain.clone();
if (debug != null) {
debug.println("Setting a " + chain.length +
"-certificate chain at alias '" + alias + "'");
}
} }
// set the keyId to current date // set the keyId to current date
...@@ -472,6 +542,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -472,6 +542,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
KeyEntry entry = new KeyEntry(); KeyEntry entry = new KeyEntry();
entry.date = new Date(); entry.date = new Date();
if (debug != null) {
debug.println("Setting a protected key at alias '" + alias + "'");
}
try { try {
// set the keyId to current date // set the keyId to current date
entry.keyId = ("Time " + (entry.date).getTime()).getBytes("UTF8"); entry.keyId = ("Time " + (entry.date).getTime()).getBytes("UTF8");
...@@ -484,6 +558,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -484,6 +558,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
entry.protectedPrivKey = key.clone(); entry.protectedPrivKey = key.clone();
if (chain != null) { if (chain != null) {
entry.chain = chain.clone(); entry.chain = chain.clone();
if (debug != null) {
debug.println("Setting a " + entry.chain.length +
"-certificate chain at alias '" + alias + "'");
}
} }
// add the entry // add the entry
...@@ -576,31 +655,76 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -576,31 +655,76 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
* Encrypt private key using Password-based encryption (PBE) * Encrypt private key using Password-based encryption (PBE)
* as defined in PKCS#5. * as defined in PKCS#5.
* *
* NOTE: Currently pbeWithSHAAnd3-KeyTripleDES-CBC algorithmID is * NOTE: By default, pbeWithSHAAnd3-KeyTripleDES-CBC algorithmID is
* used to derive the key and IV. * used to derive the key and IV.
* *
* @return encrypted private key encoded as EncryptedPrivateKeyInfo * @return encrypted private key encoded as EncryptedPrivateKeyInfo
*/ */
private byte[] encryptPrivateKey(byte[] data, char[] password) private byte[] encryptPrivateKey(byte[] data,
KeyStore.PasswordProtection passwordProtection)
throws IOException, NoSuchAlgorithmException, UnrecoverableKeyException throws IOException, NoSuchAlgorithmException, UnrecoverableKeyException
{ {
byte[] key = null; byte[] key = null;
try { try {
// create AlgorithmParameters String algorithm;
AlgorithmParameters algParams = AlgorithmParameters algParams;
getAlgorithmParameters("PBEWithSHA1AndDESede"); 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);
}
ObjectIdentifier pbeOID = mapPBEAlgorithmToOID(algorithm);
if (pbeOID != null) {
algid = new AlgorithmId(pbeOID, algParams);
} else {
throw new IOException("PBE algorithm '" + algorithm +
" 'is not supported for key entry protection");
}
} 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 = "PBEWithSHA1AndDESede";
}
algParams = getAlgorithmParameters(algorithm);
algid = new AlgorithmId(pbeWithSHAAnd3KeyTripleDESCBC_OID,
algParams);
}
// Use JCE // Use JCE
SecretKey skey = getPBEKey(password); SecretKey skey = getPBEKey(passwordProtection.getPassword());
Cipher cipher = Cipher.getInstance("PBEWithSHA1AndDESede"); Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, skey, algParams); cipher.init(Cipher.ENCRYPT_MODE, skey, algParams);
byte[] encryptedKey = cipher.doFinal(data); byte[] encryptedKey = cipher.doFinal(data);
if (debug != null) {
debug.println(" (Cipher algorithm: " + cipher.getAlgorithm() +
")");
}
// wrap encrypted private key in EncryptedPrivateKeyInfo // wrap encrypted private key in EncryptedPrivateKeyInfo
// as defined in PKCS#8 // as defined in PKCS#8
AlgorithmId algid =
new AlgorithmId(pbeWithSHAAnd3KeyTripleDESCBC_OID, algParams);
EncryptedPrivateKeyInfo encrInfo = EncryptedPrivateKeyInfo encrInfo =
new EncryptedPrivateKeyInfo(algid, encryptedKey); new EncryptedPrivateKeyInfo(algid, encryptedKey);
key = encrInfo.getEncoded(); key = encrInfo.getEncoded();
...@@ -615,6 +739,18 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -615,6 +739,18 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
return key; return key;
} }
/*
* Map a PBE algorithm name onto its object identifier
*/
private ObjectIdentifier mapPBEAlgorithmToOID(String algorithm) {
// Check for PBES2 algorithms
if (algorithm.toLowerCase().startsWith("pbewithhmacsha")) {
return pbes2_OID;
}
return null;
}
/** /**
* Assigns the given certificate to the given alias. * Assigns the given certificate to the given alias.
* *
...@@ -649,6 +785,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -649,6 +785,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
public synchronized void engineDeleteEntry(String alias) public synchronized void engineDeleteEntry(String alias)
throws KeyStoreException throws KeyStoreException
{ {
if (debug != null) {
debug.println("Removing entry at alias '" + alias + "'");
}
entries.remove(alias.toLowerCase(Locale.ENGLISH)); entries.remove(alias.toLowerCase(Locale.ENGLISH));
} }
...@@ -778,11 +918,21 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -778,11 +918,21 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
DerOutputStream authSafeContentInfo = new DerOutputStream(); DerOutputStream authSafeContentInfo = new DerOutputStream();
// -- create safeContent Data ContentInfo // -- create safeContent Data ContentInfo
if (debug != null) {
debug.println("Storing " + privateKeyCount +
" protected key(s) in a PKCS#7 data content-type");
}
byte[] safeContentData = createSafeContent(); byte[] safeContentData = createSafeContent();
ContentInfo dataContentInfo = new ContentInfo(safeContentData); ContentInfo dataContentInfo = new ContentInfo(safeContentData);
dataContentInfo.encode(authSafeContentInfo); dataContentInfo.encode(authSafeContentInfo);
// -- create EncryptedContentInfo // -- create EncryptedContentInfo
if (debug != null) {
debug.println("Storing certificate(s) in a PKCS#7 encryptedData " +
"content-type");
}
byte[] encrData = createEncryptedData(password); byte[] encrData = createEncryptedData(password);
ContentInfo encrContentInfo = ContentInfo encrContentInfo =
new ContentInfo(ContentInfo.ENCRYPTED_DATA_OID, new ContentInfo(ContentInfo.ENCRYPTED_DATA_OID,
...@@ -812,7 +962,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -812,7 +962,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
stream.flush(); stream.flush();
} }
/* /*
* Generate Hash. * Generate Hash.
*/ */
...@@ -1143,6 +1292,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -1143,6 +1292,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
cipher.init(Cipher.ENCRYPT_MODE, skey, algParams); cipher.init(Cipher.ENCRYPT_MODE, skey, algParams);
encryptedData = cipher.doFinal(data); encryptedData = cipher.doFinal(data);
if (debug != null) {
debug.println(" (Cipher algorithm: " + cipher.getAlgorithm() +
")");
}
} catch (Exception e) { } catch (Exception e) {
throw new IOException("Failed to encrypt" + throw new IOException("Failed to encrypt" +
" safe contents entry: " + e, e); " safe contents entry: " + e, e);
...@@ -1240,11 +1394,21 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -1240,11 +1394,21 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
contentType = safeContents.getContentType(); contentType = safeContents.getContentType();
safeContentsData = null; safeContentsData = null;
if (contentType.equals((Object)ContentInfo.DATA_OID)) { if (contentType.equals((Object)ContentInfo.DATA_OID)) {
if (debug != null) {
debug.println("Loading PKCS#7 data content-type");
}
safeContentsData = safeContents.getData(); safeContentsData = safeContents.getData();
} else if (contentType.equals(ContentInfo.ENCRYPTED_DATA_OID)) { } else if (contentType.equals(ContentInfo.ENCRYPTED_DATA_OID)) {
if (password == null) { if (password == null) {
continue; continue;
} }
if (debug != null) {
debug.println("Loading PKCS#7 encryptedData content-type");
}
DerInputStream edi = DerInputStream edi =
safeContents.getContent().toDerInputStream(); safeContents.getContent().toDerInputStream();
int edVersion = edi.getInteger(); int edVersion = edi.getInteger();
...@@ -1312,6 +1476,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -1312,6 +1476,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
m.update(authSafeData); m.update(authSafeData);
byte[] macResult = m.doFinal(); byte[] macResult = m.doFinal();
if (debug != null) {
debug.println("Checking keystore integrity " +
"(MAC algorithm: " + m.getAlgorithm() + ")");
}
if (!Arrays.equals(macData.getDigest(), macResult)) { if (!Arrays.equals(macData.getDigest(), macResult)) {
throw new SecurityException("Failed PKCS12" + throw new SecurityException("Failed PKCS12" +
" integrity checking"); " integrity checking");
...@@ -1417,7 +1586,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -1417,7 +1586,10 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
(new ByteArrayInputStream(certValue.getOctetString())); (new ByteArrayInputStream(certValue.getOctetString()));
bagItem = cert; bagItem = cert;
} else { } else {
// log error message for "unsupported PKCS12 bag type"
if (debug != null) {
debug.println("Unsupported PKCS12 bag type: " + bagId);
}
} }
DerValue[] attrSet; DerValue[] attrSet;
...@@ -1453,7 +1625,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ...@@ -1453,7 +1625,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
} else if (attrId.equals((Object)PKCS9LocalKeyId_OID)) { } else if (attrId.equals((Object)PKCS9LocalKeyId_OID)) {
keyId = valSet[0].getOctetString(); keyId = valSet[0].getOctetString();
} else { } else {
// log error message for "unknown attr"
if (debug != null) {
debug.println("Unsupported PKCS12 bag attribute: " +
attrId);
}
} }
} }
} }
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8006591
* @summary Protect keystore entries using stronger PBE algorithms
*/
import java.io.*;
import java.security.*;
import javax.crypto.spec.*;
// Retrieve a keystore entry, protected by the default encryption algorithm.
// Set the keystore entry, protected by a stronger encryption algorithm.
public class PBETest {
private final static String DIR = System.getProperty("test.src", ".");
private static final String PBE_ALGO = "PBEWithHmacSHA1AndAES_128";
private static final char[] PASSWORD = "passphrase".toCharArray();
private static final String KEYSTORE_TYPE = "JKS";
private static final String KEYSTORE = DIR + "/keystore.jks";
private static final String NEW_KEYSTORE_TYPE = "PKCS12";
private static final String NEW_KEYSTORE = PBE_ALGO + ".p12";
private static final String ALIAS = "vajra";
private static final byte[] IV = {
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20
};
private static final byte[] SALT = {
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
};
private static final int ITERATION_COUNT = 1024;
public static void main(String[] args) throws Exception {
new File(NEW_KEYSTORE).delete();
try {
KeyStore keystore = load(KEYSTORE_TYPE, KEYSTORE, PASSWORD);
KeyStore.Entry entry =
keystore.getEntry(ALIAS,
new KeyStore.PasswordProtection(PASSWORD));
System.out.println("Retrieved entry named '" + ALIAS + "'");
// Set entry
KeyStore keystore2 = load(NEW_KEYSTORE_TYPE, null, null);
keystore2.setEntry(ALIAS, entry,
new KeyStore.PasswordProtection(PASSWORD, PBE_ALGO,
new PBEParameterSpec(SALT, ITERATION_COUNT,
new IvParameterSpec(IV))));
System.out.println("Encrypted entry using: " + PBE_ALGO);
System.out.println("Storing keystore to: " + NEW_KEYSTORE);
keystore2.store(new FileOutputStream(NEW_KEYSTORE), PASSWORD);
keystore2 = load(NEW_KEYSTORE_TYPE, NEW_KEYSTORE, PASSWORD);
entry = keystore2.getEntry(ALIAS,
new KeyStore.PasswordProtection(PASSWORD));
System.out.println("Retrieved entry named '" + ALIAS + "'");
} finally {
new File(NEW_KEYSTORE).delete();
System.out.println("Deleted keystore: " + NEW_KEYSTORE);
}
}
private static KeyStore load(String type, String path, char[] password)
throws Exception {
FileInputStream stream = null;
if (path != null) {
stream = new FileInputStream(path);
}
KeyStore keystore = KeyStore.getInstance(type);
System.out.println("Loading keystore from: " + path);
keystore.load(stream, password);
return keystore;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册