📄 keystore.java
字号:
package au.net.aba.crypto.provider;
/*
* $Id: KeyStore.java,v 1.1 1999/01/25 00:46:16 wslade Exp $
* $Author: wslade $
*
* Copyright (C) 1996-1998 Australian Business Access Pty Ltd.
* All rights reserved.
*
* Use, modification, copying and distribution of this software is subject the
* terms and conditions of the ABA Public Licence. See the file
* "PUBLIC_LICENCE" for additional information.
*
* If you have not received a copy of the Public Licence, you must destroy all
* copies of this file immediately.
*
* $Source: /aba/CVSROOT/jdk1.1/src/au.net.aba/crypto/provider/KeyStore.java,v $
* $Revision: 1.1 $
* $Date: 1999/01/25 00:46:16 $
* $State: Exp $
*/
import java.io.*;
import java.util.*;
import java.security.*;
import java.security.cert.Certificate;
import java.security.*;
import java.security.cert.*;
import java.security.spec.*;
import au.net.aba.crypto.spec.AsciiEncodedKeySpec;
import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the <code>KeyStore</code> class.
* All the methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a keystore for a particular keystore type.
*
*
* @since JDK1.2
*/
public class KeyStore extends KeyStoreSpi
{
// Defines the cipher to use to encrypt the store.
// private static final String CIPHER = "PBEWithMD5AndDES";
private static final String CIPHER = "PBEWithSHA1And128BitRC4";
private class PrivateKeyEntry implements Serializable
{
Key mKey;
char[] mPassword;
Certificate mCertificates[];
public boolean validate(char[] password)
{
// Validate the password
if (mPassword.length != password.length)
return false;
for (int i = 0; i < mPassword.length; i++)
if (mPassword[i] != password[i])
return false;
return true;
}
}
// Storage for all Trusted Certificates;
private Hashtable mTrustedCerts = new Hashtable();
// Storage for all Private Key Entries
private Hashtable mPrivateKeys = new Hashtable();
private static final float VERSION = 1.0f;
private class SecurityOutputStream extends ObjectOutputStream
{
public SecurityOutputStream(OutputStream out)
throws IOException
{
super(out);
}
protected void writeStreamHeader()
throws IOException
{
// Write a header
writeFloat(VERSION);
}
/**
* Writes a Key to the stream:<ol>
* Type (int 1..3)</li>
* Algorithm (String)</li>
* Format (String)</li>
* Encoded (byte [])</li></ol>
*/
public void writeKey(Key key)
throws IOException
{
if (key instanceof PrivateKey)
writeInt(1);
else if (key instanceof PublicKey)
writeInt(2);
else if (key instanceof SecretKey)
writeInt(3);
else
throw new IOException("Unknown Key - " + key);
writeObject(key.getAlgorithm());
writeObject(key.getFormat());
writeArray(key.getEncoded());
}
/**
* Writes a Certificate to the stream<ol>
* Type (String)</li>
* Encoded (byte[])</li></ol>
*/
public void writeCert(Certificate cert)
throws IOException, CertificateEncodingException
{
writeObject(cert.getType());
writeArray(cert.getEncoded());
}
/**
* Writes a password to the stream<ol>
* Length (String)</li>
* bytes (char 0..*)</li></ol>
*/
public void writePassword(char[] pwd)
throws IOException
{
writeInt(pwd.length);
for (int i = 0; i < pwd.length; i++)
writeChar(pwd[i]);
}
/**
* Writes an array of bytes, first storing the size and then the array
*/
public void writeArray(byte[] array)
throws IOException
{
writeInt(array.length);
write(array);
}
}
private class SecurityInputStream extends ObjectInputStream
{
public SecurityInputStream(InputStream in)
throws IOException
{
super(in);
}
protected void readStreamHeader()
throws IOException
{
// read a header
float version = readFloat();
if (version != VERSION)
throw new IOException("Invalid stream version:" + version);
}
/**
* Writes a Key to the stream:<ol>
* Type (int 1..3)</li>
* Algorithm (String)</li>
* Format (String)</li>
* Encoded (byte [])</li></ol>
*/
public Key readKey()
throws IOException, ClassNotFoundException,
NoSuchAlgorithmException, InvalidKeySpecException
{
int type = readInt();
String algorithm = (String)readObject();
String format = (String)readObject();
byte[] encode = readArray();
KeySpec keySpec;
if (format.equals("PKCS#8"))
keySpec = new PKCS8EncodedKeySpec(encode);
else if (format.equals("X.509"))
keySpec = new X509EncodedKeySpec(encode);
else if (format.equals("ASCII"))
keySpec = new AsciiEncodedKeySpec(new String(encode));
else
throw new IOException("Unknown Key format: " + format);
switch(type)
{
case 1: // PrivateKey
KeyFactory kf1 = KeyFactory.getInstance(algorithm);
return kf1.generatePrivate(keySpec);
case 2: // PublicKey
KeyFactory kf2 = KeyFactory.getInstance(algorithm);
return kf2.generatePublic(keySpec);
case 3: // SecretKey
SecretKeyFactory kf3 = SecretKeyFactory.getInstance(algorithm);
return kf3.generateSecret(keySpec);
default:
throw new IOException("Unknown KeyType");
}
}
/**
* Reads a Certificate from the stream<ol>
* Type (String)</li>
* Encoded (byte[])</li></ol>
*/
public Certificate readCert()
throws IOException, ClassNotFoundException, CertificateException
{
String type = (String)readObject();
byte[] encoded = readArray();
CertificateFactory cf = CertificateFactory.getInstance(type);
ByteArrayInputStream in = new ByteArrayInputStream(encoded);
return cf.generateCertificate(in);
}
/**
* Reads a password from the stream<ol>
* Length (String)</li>
* bytes (char 0..*)</li></ol>
*/
public char[] readPassword()
throws IOException
{
int length = readInt();
char pwd[] = new char[length];
for (int i = 0; i < pwd.length; i++)
pwd[i] = readChar();
return pwd;
}
/**
* Reads an array of bytes, first storing the size and then the array
*/
public byte[] readArray()
throws IOException
{
int length = readInt();
byte[] array = new byte[length];
read(array, 0, array.length);
return array;
}
}
private Key createKey(char[] password)
throws NoSuchAlgorithmException
{
KeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory skf = SecretKeyFactory.getInstance(CIPHER);
try
{
return skf.generateSecret(keySpec);
}
catch(InvalidKeySpecException e)
{
// We won't get this wrong
throw new ExceptionInInitializerError(e);
}
}
private byte[] encrypt(int code, byte[] salt, char[] password, byte[] input)
throws NoSuchAlgorithmException
{
// Algorithm parameters
AlgorithmParameterSpec aps = new PBEParameterSpec(salt, 20); // 20 iterations
// Encrypt the input now
try
{
Cipher cipher = Cipher.getInstance(CIPHER, "ABA");
Key key = createKey(password);
cipher.init(code, key, aps);
return cipher.doFinal(input);
}
catch(java.security.NoSuchProviderException e)
{
throw new ExceptionInInitializerError(e);
}
catch(InvalidAlgorithmParameterException e)
{
// We are smart enough not to get this wrong
throw new ExceptionInInitializerError(e);
}
catch(NoSuchPaddingException e)
{
// This too.
throw new ExceptionInInitializerError(e);
}
catch(BadPaddingException e)
{
throw new ExceptionInInitializerError(e);
}
catch(javax.crypto.IllegalBlockSizeException e)
{
// Most likely this as well.
throw new ExceptionInInitializerError(e);
}
catch(InvalidKeyException e)
{
// Most likely this as well.
throw new ExceptionInInitializerError(e);
}
}
/**
* Lists all the alias names of this keystore.
*
* @return enumeration of the alias names
*/
public Enumeration engineAliases()
{
return new Enumeration()
{
boolean first = true;
Enumeration enum = mTrustedCerts.keys();
public boolean hasMoreElements()
{
if (!swap())
return false;
return enum.hasMoreElements();
}
public Object nextElement()
{
if (!swap())
return null;
return enum.nextElement();
}
private boolean swap()
{
if (!enum.hasMoreElements())
{
if (!first)
return false;
first = false;
enum = mPrivateKeys.keys();
}
return true;
}
};
}
/**
* Checks if the given alias exists in this keystore.
*
* @param alias the alias name
*
* @return true if the alias exists, false otherwise
*/
public boolean engineContainsAlias(String alias)
{
if (mPrivateKeys.containsKey(alias))
return true;
return mTrustedCerts.containsKey(alias);
}
/**
* Deletes the entry identified by the given alias from this keystore.
*
* @param alias the alias name
*
* @exception KeyStoreException if the entry cannot be removed.
*/
public void engineDeleteEntry(String alias)
throws KeyStoreException
{
Object value;
value = mPrivateKeys.remove(alias);
if (mPrivateKeys.remove(alias) != null)
return;
if (mTrustedCerts.remove(alias) != null)
return;
throw new KeyStoreException("Alias not found - " + alias);
}
/**
* Returns the certificate associated with the given alias.
*
* <p>If the given alias name identifies a
* <i>trusted certificate entry</i>, the certificate associated with that
* entry is returned. If the given alias name identifies a
* <i>key entry</i>, the first element of the certificate chain of that
* entry is returned, or null if that entry does not have a certificate
* chain.
*
* @param alias the alias name
*
* @return the certificate, or null if the given alias does not exist or
* does not contain a certificate.
*/
public Certificate engineGetCertificate(String alias)
{
// First check the Trusted Certificates for the given alias
Object cert = mTrustedCerts.get(alias);
if (cert != null)
return (Certificate)cert;
// Now try the private keys
Object pke = mPrivateKeys.get(alias);
if (pke != null)
{
// Return the first certificate if there is one
PrivateKeyEntry entry = (PrivateKeyEntry)pke;
return entry.mCertificates != null ? entry.mCertificates[0] : null;
}
return null;
}
/**
* Returns the (alias) name of the first keystore entry whose certificate
* matches the given certificate.
*
* <p>This method attempts to match the given certificate with each
* keystore entry. If the entry being considered
* is a <i>trusted certificate entry</i>, the given certificate is
* compared to that entry's certificate. If the entry being considered is
* a <i>key entry</i>, the given certificate is compared to the first
* element of that entry's certificate chain (if a chain exists).
*
* @param cert the certificate to match with.
*
* @return the (alias) name of the first entry with matching certificate,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -