下面列出了怎么用java.security.KeyStore.PasswordProtection的API类实例代码及写法,或者点击链接到github查看源代码。
public static void main(final String[] args) throws IOException {
try (InputStream is = new FileInputStream("src/main/resources/keystore.jks");
JKSSignatureToken jksSignatureToken = new JKSSignatureToken(is, new PasswordProtection("dss-password".toCharArray()))) {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
List<DSSPrivateKeyEntry> keys = jksSignatureToken.getKeys();
for (DSSPrivateKeyEntry key : keys) {
CertificateToken certificate = key.getCertificate();
System.out.println(dateFormat.format(certificate.getNotAfter()) + ": " + certificate.getSubject().getCanonical());
CertificateToken[] certificateChain = key.getCertificateChain();
for (CertificateToken x509Certificate : certificateChain) {
System.out.println("/t" + dateFormat.format(x509Certificate.getNotAfter()) + ": " + x509Certificate.getSubject().getCanonical());
}
}
System.out.println("DONE");
}
}
private DSSPrivateKeyEntry getDSSPrivateKeyEntry(KeyStore keyStore, String alias, PasswordProtection passwordProtection) {
try {
if (keyStore.isKeyEntry(alias)) {
final Entry entry = keyStore.getEntry(alias, passwordProtection);
if (entry instanceof PrivateKeyEntry) {
PrivateKeyEntry pke = (PrivateKeyEntry) entry;
return new KSPrivateKeyEntry(alias, pke);
} else {
LOG.warn("Skipped entry (unsupported class : {})", entry.getClass().getSimpleName());
}
} else {
LOG.debug("No related/supported key found for alias '{}'", alias);
}
} catch (GeneralSecurityException e) {
throw new DSSException("Unable to retrieve key from keystore", e);
}
return null;
}
@Override
public void engineLoad(LoadStoreParameter param) throws IOException,
NoSuchAlgorithmException, CertificateException {
if (param == null) {
engineLoad(null, null);
return;
}
ProtectionParameter pParam = param.getProtectionParameter();
if (pParam == null) {
throw new NoSuchAlgorithmException();
}
if (pParam instanceof PasswordProtection) {
char[] password = ((PasswordProtection) pParam).getPassword();
if (password == null) {
throw new NoSuchAlgorithmException();
} else {
return;
}
}
throw new CertificateException();
}
@Override
public void engineStore(LoadStoreParameter param) throws IOException,
NoSuchAlgorithmException, CertificateException {
if (param == null) {
throw new IOException();
}
ProtectionParameter pParam = param.getProtectionParameter();
if (pParam instanceof PasswordProtection) {
char[] password = ((PasswordProtection) pParam).getPassword();
if (password == null) {
throw new NoSuchAlgorithmException();
} else if (password.length == 0) {
throw new CertificateException();
}
return;
}
throw new UnsupportedOperationException();
}
public static String readEntity(KeyStore keyStore, String entityAlias, String entityPassword)
throws GeneralSecurityException
{
SecretKeyEntry secretKeyEntry = (SecretKeyEntry) keyStore.getEntry(entityAlias, new PasswordProtection(entityPassword.toCharArray()));
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
PBEKeySpec keySpec = (PBEKeySpec) factory.getKeySpec(secretKeyEntry.getSecretKey(), PBEKeySpec.class);
return new String(keySpec.getPassword());
}
private static Password createFromFlagValue(String flagValue) {
if (flagValue.startsWith("pass:")) {
return new Password(
() -> new PasswordProtection(flagValue.substring("pass:".length()).toCharArray()));
} else if (flagValue.startsWith("file:")) {
Path passwordFile = Paths.get(flagValue.substring("file:".length()));
checkFileExistsAndReadable(passwordFile);
return new Password(
() -> new PasswordProtection(readPasswordFromFile(passwordFile).toCharArray()));
}
throw new FlagParseException("Passwords must be prefixed with \"pass:\" or \"file:\".");
}
public String addKey(PrivateKey key) throws KeyStoreException {
String keyID = getUniqueID(key);
SecretKey secretKey = new SecretKeySpec(key.getBytes(), "EC");
SecretKeyEntry kEntry = new SecretKeyEntry(secretKey);
ks.setEntry(keyID, kEntry, new PasswordProtection(password));
netwotkTypeMap.put(keyID, key.getNetworkType());
return keyID;
}
public void changePassword(char[] password) throws KeyStoreException {
try {
for (String alias : Collections.list(ks.aliases())) {
Entry entry = ks.getEntry(alias, new PasswordProtection(this.password)); // read
ks.setEntry(alias, entry, new PasswordProtection(password)); // override
}
// update the password
Arrays.fill(this.password, '0');
this.password = Arrays.copyOf(password, password.length);
} catch (NoSuchAlgorithmException | UnrecoverableEntryException e) {
throw new KeyStoreException(e);
}
}
/**
* Creates a new SSLContext based on the provided parameters. This SSLContext will be used to
* provide new SSLSockets that are authorized to connect to a Cloud SQL instance.
*/
private SSLContext createSslContext(
KeyPair keyPair, Metadata metadata, Certificate ephemeralCertificate) {
try {
KeyStore authKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
authKeyStore.load(null, null);
KeyStore.PrivateKeyEntry privateKey =
new PrivateKeyEntry(keyPair.getPrivate(), new Certificate[] {ephemeralCertificate});
authKeyStore.setEntry("ephemeral", privateKey, new PasswordProtection(new char[0]));
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(authKeyStore, new char[0]);
KeyStore trustedKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustedKeyStore.load(null, null);
trustedKeyStore.setCertificateEntry("instance", metadata.getInstanceCaCertificate());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X.509");
tmf.init(trustedKeyStore);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
return sslContext;
} catch (GeneralSecurityException | IOException ex) {
throw new RuntimeException(
String.format(
"[%s] Unable to create a SSLContext for the Cloud SQL instance.", connectionName),
ex);
}
}
private PrivateKeyEntry loadCAKeyEntry() throws IOException,
GeneralSecurityException {
final KeyStore keystore = loadKeyStore();
final Entry entry = keystore.getEntry(this.alias,
new PasswordProtection(this.password.toCharArray()));
return (PrivateKeyEntry) entry;
}
private void loadPrivateKeyEntry() throws GeneralSecurityException {
rootPrivateKeyEntry = (PrivateKeyEntry) rootCaKeystore.getEntry(
rootCaAlias,
new PasswordProtection(rootCaPassword.toCharArray()));
if (rootPrivateKeyEntry == null) {
throw new RuntimeException(
"Could not read private key entry from rootca keystore with alias "
+ rootCaAlias);
}
}
private void initKeystore(final InputStream ksStream, final String ksType, final String ksPassword) {
try (InputStream is = ksStream) {
keyStore = KeyStore.getInstance(ksType);
final char[] password = (ksPassword == null) ? null : ksPassword.toCharArray();
keyStore.load(is, password);
passwordProtection = new PasswordProtection(password);
} catch (GeneralSecurityException | IOException e) {
throw new DSSException("Unable to initialize the keystore", e);
}
}
@Test
public void testPkcs12() throws IOException {
try (Pkcs12SignatureToken signatureToken = new Pkcs12SignatureToken("src/test/resources/user_a_rsa.p12",
new PasswordProtection("password".toCharArray()))) {
assertNotNull(signatureToken);
List<DSSPrivateKeyEntry> keys = signatureToken.getKeys();
assertFalse(keys.isEmpty());
KSPrivateKeyEntry dssPrivateKeyEntry = (KSPrivateKeyEntry) keys.get(0);
assertNotNull(dssPrivateKeyEntry);
assertNotNull(dssPrivateKeyEntry.getAlias());
DSSPrivateKeyEntry entry = signatureToken.getKey(dssPrivateKeyEntry.getAlias(),
new PasswordProtection("password".toCharArray()));
assertNotNull(entry);
assertNotNull(entry.getCertificate());
assertNotNull(entry.getCertificateChain());
assertNotNull(entry.getEncryptionAlgorithm());
ToBeSigned toBeSigned = new ToBeSigned("Hello world".getBytes("UTF-8"));
SignatureValue signValue = signatureToken.sign(toBeSigned, DigestAlgorithm.SHA256, entry);
assertNotNull(signValue);
assertNotNull(signValue.getAlgorithm());
assertNotNull(signValue.getValue());
}
}
@Test
public void wrongPassword() throws IOException {
PasswordProtection passwordProtection = new PasswordProtection("wrong password".toCharArray());
Exception exception = assertThrows(DSSException.class,
() -> new Pkcs12SignatureToken("src/test/resources/user_a_rsa.p12", passwordProtection));
assertEquals("Unable to instantiate KeyStoreSignatureTokenConnection", exception.getMessage());
}
/**
* Generate self-signed test-CA key/certificate and a test user key/certificate
*/
private static void generatePkiCerts() throws Exception {
String caPath = getTestPkiCACertsPath(); // CA certs keystore is .jks file
File caFile = new File(caPath);
if (caFile.exists() && !caFile.delete()) {
throw new RuntimeException("Failed to generate new test-CA key file: " + caPath);
}
String userKeystorePath = getTestPkiUserKeystorePath(); // user keystore is .p12 file
File userKeystoreFile = new File(userKeystorePath);
if (userKeystoreFile.exists() && !userKeystoreFile.delete()) {
throw new RuntimeException(
"Failed to generate new test-user key file: " + userKeystorePath);
}
String serverKeystorePath = getTestPkiServerKeystorePath(); // server keystore is .p12 file
File serverKeystoreFile = new File(serverKeystorePath);
if (serverKeystoreFile.exists() && !serverKeystoreFile.delete()) {
throw new RuntimeException(
"Failed to generate new test-server key file: " + serverKeystorePath);
}
// Generate CA certificate and keystore
Msg.info(ServerTestUtil.class, "Generating self-signed CA cert: " + caPath);
CertificateExtensions caCertExtensions = new CertificateExtensions();
BasicConstraintsExtension caBasicConstraints = new BasicConstraintsExtension(true, true, 1);
caCertExtensions.set(PKIXExtensions.BasicConstraints_Id.toString(), caBasicConstraints);
KeyUsageExtension caKeyUsage = new KeyUsageExtension();
caKeyUsage.set(KeyUsageExtension.KEY_CERTSIGN, true);
caCertExtensions.set(PKIXExtensions.KeyUsage_Id.toString(), caKeyUsage);
KeyStore caKeystore = ApplicationKeyManagerUtils.createKeyStore(null, "PKCS12",
ApplicationKeyManagerFactory.DEFAULT_PASSWORD.toCharArray(), "test-CA",
caCertExtensions, TEST_PKI_CA_DN, null, 2);
ApplicationKeyManagerUtils.exportX509Certificates(caKeystore, caFile);
PasswordProtection caPass =
new PasswordProtection(ApplicationKeyManagerFactory.DEFAULT_PASSWORD.toCharArray());
PrivateKeyEntry caPrivateKeyEntry =
(PrivateKeyEntry) caKeystore.getEntry("test-CA", caPass);
// Generate User/Client certificate and keystore
Msg.info(ServerTestUtil.class, "Generating test user key/cert (signed by test-CA, pwd: " +
TEST_PKI_USER_PASSPHRASE + "): " + userKeystorePath);
ApplicationKeyManagerUtils.createKeyStore(userKeystoreFile, "PKCS12",
TEST_PKI_USER_PASSPHRASE.toCharArray(), "test-sig", null, TEST_PKI_USER_DN,
caPrivateKeyEntry, 2);
// Generate Server certificate and keystore
Msg.info(ServerTestUtil.class, "Generating test server key/cert (signed by test-CA, pwd: " +
TEST_PKI_SERVER_PASSPHRASE + "): " + serverKeystorePath);
ApplicationKeyManagerUtils.createKeyStore(serverKeystoreFile, "PKCS12",
TEST_PKI_SERVER_PASSPHRASE.toCharArray(), "test-sig", null, TEST_PKI_SERVER_DN,
caPrivateKeyEntry, 2);
}
public Password(Supplier<PasswordProtection> passwordSupplier) {
this.passwordSupplier = passwordSupplier;
}
@VisibleForTesting
public static Password createForTest(String password) {
return new Password(() -> new PasswordProtection(password.toCharArray()));
}
/** Special note: It's the responsibility of the caller to destroy the password once used. */
public final PasswordProtection getValue() {
return passwordSupplier.get();
}
private ProtectionParameter createProtection(final EntryDescriptor descr) {
return new PasswordProtection(descr.getPassword().toCharArray());
}
protected AbstractKeyStoreTokenConnection getToken() {
return new KeyStoreSignatureTokenConnection(getKeystoreContent(getSigningAlias() + ".p12"), KEYSTORE_TYPE,
new PasswordProtection(PKI_FACTORY_KEYSTORE_PASSWORD.toCharArray()));
}
public static void main(String[] args) throws IOException {
// tag::demo[]
try (Pkcs12SignatureToken token = new Pkcs12SignatureToken("src/main/resources/user_a_rsa.p12", new PasswordProtection("password".toCharArray()))) {
List<DSSPrivateKeyEntry> keys = token.getKeys();
for (DSSPrivateKeyEntry entry : keys) {
System.out.println(entry.getCertificate().getCertificate());
}
ToBeSigned toBeSigned = new ToBeSigned("Hello world".getBytes());
SignatureValue signatureValue = token.sign(toBeSigned, DigestAlgorithm.SHA256, keys.get(0));
System.out.println("Signature value : " + Utils.toBase64(signatureValue.getValue()));
}
// end::demo[]
}
@Override
PasswordProtection getKeyProtectionParameter() {
return null;
}
@Override
PasswordProtection getKeyProtectionParameter() {
return new PasswordProtection("nimp".toCharArray());
}
public KeyStoreSignatureTokenConnection(byte[] ksBytes, String ksType, PasswordProtection ksPassword) {
this(new ByteArrayInputStream(ksBytes), ksType, ksPassword);
}
public KeyStoreSignatureTokenConnection(String filepath, String ksType, PasswordProtection ksPassword) throws IOException {
this(new File(filepath), ksType, ksPassword);
}
public KeyStoreSignatureTokenConnection(File ksFile, String ksType, PasswordProtection ksPassword) throws IOException {
this(new FileInputStream(ksFile), ksType, ksPassword);
}
@Override
PasswordProtection getKeyProtectionParameter() {
return password;
}
public static void main(String[] args) {
String PIN = "PINCODE";
// -Djava.security.debug = sunpkcs11
// 32b
// Pkcs11SignatureToken token = new Pkcs11SignatureToken("C:\\Windows\\SysWOW64\\onepin-opensc-pkcs11.dll");
// 64b
// Pkcs11SignatureToken token = new Pkcs11SignatureToken("C:\\Windows\\System32\\beidpkcs11.dll");
// Pkcs11SignatureToken token = new Pkcs11SignatureToken("C:\\Windows\\System32\\beidpkcs11.dll",
// (PasswordInputCallback) null, 3)
// Pkcs11SignatureToken token = new Pkcs11SignatureToken("C:\\Windows\\System32\\onepin-opensc-pkcs11.dll",
// new PasswordProtection(PIN.toCharArray()), 1)
String alias = null;
try (Pkcs11SignatureToken token = new Pkcs11SignatureToken("C:\\Program Files\\Gemalto\\Classic Client\\BIN\\gclib.dll",
new PasswordProtection(PIN.toCharArray()), 2)) {
List<DSSPrivateKeyEntry> keys = token.getKeys();
for (DSSPrivateKeyEntry entry : keys) {
System.out.println(entry.getCertificate().getCertificate());
}
alias = ((KSPrivateKeyEntry) keys.get(0)).getAlias();
// ToBeSigned toBeSigned = new ToBeSigned("Hello world".getBytes());
// SignatureValue signatureValue = token.sign(toBeSigned, DigestAlgorithm.SHA256, dssPrivateKeyEntry);
// System.out.println("Signature value : " +
// DatatypeConverter.printBase64Binary(signatureValue.getValue()));
}
try (Pkcs11SignatureToken token = new Pkcs11SignatureToken("C:\\Program Files\\Gemalto\\Classic Client\\BIN\\gclib.dll",
new PasswordProtection(PIN.toCharArray()), 2)) {
DSSPrivateKeyEntry key = token.getKey(alias, new PasswordProtection(PIN.toCharArray()));
ToBeSigned toBeSigned = new ToBeSigned("Hello world".getBytes());
SignatureValue signatureValue = token.sign(toBeSigned, DigestAlgorithm.SHA256, key);
System.out.println("Signature value : " + Base64.getEncoder().encodeToString(signatureValue.getValue()));
}
}
/**
* Construct a KeyStoreSignatureTokenConnection object.
* Please note that the keystore password will also be used to retrieve the private key.
* For each keystore entry (identifiable by alias) the same private key password will be used.
*
* If you want to specify a separate private key password use the {@link #getKey(String, PasswordProtection)}
* method.
*
* @param ksStream
* the inputstream which contains the keystore
* @param ksType
* the keystore type
* @param password
* the keystore password
*/
public KeyStoreSignatureTokenConnection(InputStream ksStream, String ksType, PasswordProtection password) {
try (InputStream is = ksStream) {
this.keyStore = KeyStore.getInstance(ksType);
this.password = password;
this.keyStore.load(is, password.getPassword());
} catch (Exception e) {
throw new DSSException("Unable to instantiate KeyStoreSignatureTokenConnection", e);
}
}
/**
* Sometimes, the password is known in advance. This create a SignatureTokenConnection and the keys will be accessed
* using the provided password. The default constructor for CallbackPkcs11SignatureToken.
*
* @param pkcs11Path
* the path for the library (.dll, .so)
* @param password
* the pin code / password to use
*/
public Pkcs11SignatureToken(String pkcs11Path, PasswordProtection password) {
this(pkcs11Path, password, 0);
}