⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keystore.java

📁 面向应用的智能安全代理平台和工具包是一个综合网络应用的安全共性需求而设计和实现的一个通用性的网络信息安全应用支撑平台
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
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 + -