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

📄 jcecipherfactory.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*   Derby - Class org.apache.derby.impl.services.jce.JCECipherFactory   Copyright 2000, 2004 The Apache Software Foundation or its licensors, as applicable.   Licensed under the Apache License, Version 2.0 (the "License");   you may not use this file except in compliance with the License.   You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License. */package org.apache.derby.impl.services.jce;import org.apache.derby.iapi.services.crypto.CipherFactory;import org.apache.derby.iapi.services.crypto.CipherProvider;import org.apache.derby.iapi.services.monitor.ModuleControl;import org.apache.derby.iapi.services.monitor.Monitor;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.services.info.JVMInfo;import org.apache.derby.iapi.util.StringUtil;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.reference.Attribute;import org.apache.derby.iapi.util.StringUtil;import java.util.Properties;import java.security.Key;import java.security.Provider;import java.security.SecureRandom;import java.security.Security;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.MessageDigest;import java.security.spec.KeySpec;import java.security.spec.InvalidKeySpecException;import java.io.FileNotFoundException;import java.io.IOException;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import javax.crypto.spec.SecretKeySpec;import org.apache.derby.iapi.store.raw.RawStoreFactory;import org.apache.derby.io.StorageFactory;import org.apache.derby.io.WritableStorageFactory;import org.apache.derby.io.StorageFile;import org.apache.derby.io.StorageRandomAccessFile;/**	This CipherFactory creates new JCECipherProvider.	@see CipherFactory */public final class JCECipherFactory implements CipherFactory, ModuleControl, java.security.PrivilegedExceptionAction{    private final static String MESSAGE_DIGEST = "MD5";	private final static String DEFAULT_PROVIDER = "com.sun.crypto.provider.SunJCE";	private final static String DEFAULT_ALGORITHM = "DES/CBC/NoPadding";	private final static String DES = "DES";	private final static String DESede = "DESede";    private final static String TripleDES = "TripleDES";    private final static String AES = "AES";    // minimum boot password length in bytes    private final static int BLOCK_LENGTH = 8;    /**	AES encryption takes in an default Initialization vector length (IV) length of 16 bytes	This is needed to generate an IV to use for encryption and decryption process 	@see CipherProvider     */    private final static int AES_IV_LENGTH = 16;    // key length in bytes	private int keyLengthBits;    private int encodedKeyLength;    private String cryptoAlgorithm;    private String cryptoAlgorithmShort;    private String cryptoProvider;    private String cryptoProviderShort;	private MessageDigest messageDigest;	private SecretKey mainSecretKey;	private byte[] mainIV;	/**	    Amount of data that is used for verification of external encryption key	    This does not include the MD5 checksum bytes	 */	private final static int VERIFYKEY_DATALEN = 4096;	private StorageFile activeFile;	private int action;	private String activePerms;	static String providerErrorName(String cps) {		return cps == null ? "default" : cps;	}	private byte[] generateUniqueBytes() throws StandardException	{		try {			String provider = cryptoProviderShort;			KeyGenerator keyGen;			if (provider == null)			{				keyGen = KeyGenerator.getInstance(cryptoAlgorithmShort);			}			else			{				if( provider.equals("BouncyCastleProvider"))					provider = "BC";				keyGen = KeyGenerator.getInstance(cryptoAlgorithmShort, provider);			}			keyGen.init(keyLengthBits);			SecretKey key = keyGen.generateKey();			return key.getEncoded();		} catch (java.security.NoSuchAlgorithmException nsae) {    		throw StandardException.newException(SQLState.ENCRYPTION_NOSUCH_ALGORITHM, cryptoAlgorithm,				JCECipherFactory.providerErrorName(cryptoProviderShort));		} catch (java.security.NoSuchProviderException nspe) {			throw StandardException.newException(SQLState.ENCRYPTION_BAD_PROVIDER,				JCECipherFactory.providerErrorName(cryptoProviderShort));		}	}	/**		Encrypt the secretKey with the boot password.		This includes the following steps, 		getting muck from the boot password and then using this to generate a key,		generating an appropriate IV using the muck		using the key and IV thus generated to create the appropriate cipher provider		and encrypting the secretKey 		@return hexadecimal string of the encrypted secretKey		@exception StandardException Standard Cloudscape error policy	 */	private String encryptKey(byte[] secretKey, byte[] bootPassword)		 throws StandardException	{		// In case of AES, care needs to be taken to allow for 16 bytes muck as well		// as to have the secretKey that needs encryption to be a aligned appropriately		// AES supports 16 bytes block size		int muckLength = secretKey.length;		if(cryptoAlgorithmShort.equals(AES))			muckLength = AES_IV_LENGTH;				byte[] muck = getMuckFromBootPassword(bootPassword, muckLength);		SecretKey key = generateKey(muck);		byte[] IV = generateIV(muck);                CipherProvider tmpCipherProvider = createNewCipher(ENCRYPT,key,IV);				// store the actual secretKey.length before any possible padding  		encodedKeyLength = secretKey.length;		// for the secretKey to be encrypted, first ensure that it is aligned to the block size of the 		// encryption algorithm by padding bytes appropriately if needed                secretKey = padKey(secretKey,tmpCipherProvider.getEncryptionBlockSize());                byte[] result = new byte[secretKey.length];		// encrypt the secretKey using the key generated of muck from  boot password and the generated IV  		tmpCipherProvider.encrypt(secretKey, 0, secretKey.length, result, 0);		return org.apache.derby.iapi.util.StringUtil.toHexString(result, 0, result.length);	}		/**            For block ciphers, and  algorithms using the NoPadding scheme, the data that has             to be encrypted needs to be a multiple of the expected block size for the cipher 	    Pad the key with appropriate padding to make it blockSize align	    @param     secretKey	the data that needs blocksize alignment	    @param     blockSizeAlign   secretKey needs to be blocksize aligned			    @return    a byte array with the contents of secretKey along with padded bytes in the end		       to make it blockSize aligned         */	private byte[] padKey(byte[] secretKey,int blockSizeAlign)	{	    byte [] result = secretKey;	    if(secretKey.length % blockSizeAlign != 0 )	    {		int encryptedLength = secretKey.length + blockSizeAlign - (secretKey.length % blockSizeAlign);		result = new byte[encryptedLength];		System.arraycopy(secretKey,0,result,0,secretKey.length);	    }	    return result;	}	/**	    Decrypt the secretKey with the user key .	    This includes the following steps, 	    retrieve the encryptedKey, generate the muck from the boot password and generate an appropriate IV using	    the muck,and using the key and IV decrypt the encryptedKey 	    @return decrypted key  		@exception StandardException Standard Cloudscape error policy	 */	private byte[] decryptKey(String encryptedKey, int encodedKeyCharLength, byte[] bootPassword)		 throws StandardException	{		byte[] secretKey = org.apache.derby.iapi.util.StringUtil.fromHexString(encryptedKey, 0, encodedKeyCharLength);		// In case of AES, care needs to be taken to allow for 16 bytes muck as well		// as to have the secretKey that needs encryption to be a aligned appropriately		// AES supports 16 bytes block size		int muckLength;		if(cryptoAlgorithmShort.equals(AES))		    muckLength = AES_IV_LENGTH;		else	            muckLength = secretKey.length;			byte[] muck = getMuckFromBootPassword(bootPassword, muckLength);		// decrypt the encryptedKey with the mucked up boot password to recover		// the secretKey		SecretKey key = generateKey(muck);		byte[] IV = generateIV(muck);		createNewCipher(DECRYPT, key, IV).			decrypt(secretKey, 0, secretKey.length, secretKey, 0);		return secretKey;	}	private byte[] getMuckFromBootPassword(byte[] bootPassword, int encodedKeyByteLength) {		int ulength = bootPassword.length;		byte[] muck = new byte[encodedKeyByteLength];				int rotation = 0;		for (int i = 0; i < bootPassword.length; i++)			rotation += bootPassword[i];		for (int i = 0; i < encodedKeyByteLength; i++)			muck[i] = (byte)(bootPassword[(i+rotation)%ulength] ^                (bootPassword[i%ulength] << 4));		return muck;	}	/**		Generate a Key object using the input secretKey that can be used by		JCECipherProvider to encrypt or decrypt.		@exception StandardException Standard Cloudscape Error Policy	 */	private SecretKey generateKey(byte[] secretKey) throws StandardException	{		int length = secretKey.length;		if (length < CipherFactory.MIN_BOOTPASS_LENGTH)			throw StandardException.newException(SQLState.ILLEGAL_BP_LENGTH, new Integer(MIN_BOOTPASS_LENGTH));		try		{            if (cryptoAlgorithmShort.equals(DES))            {   // single DES			    if (DESKeySpec.isWeak(secretKey, 0))			    {				    // OK, it is weak, spice it up				    byte[] spice = StringUtil.getAsciiBytes("louDScap");				    for (int i = 0; i < 7; i++)					    secretKey[i] = (byte)((spice[i] << 3) ^ secretKey[i]);			    }            }			return new SecretKeySpec(secretKey, cryptoAlgorithmShort);		}		catch (InvalidKeyException ike)		{			throw StandardException.newException(SQLState.CRYPTO_EXCEPTION, ike);		}	}	/**		Generate an IV using the input secretKey that can be used by		JCECipherProvider to encrypt or decrypt.	 */	private byte[] generateIV(byte[] secretKey)	{		// do a little simple minded muddling to make the IV not		// strictly alphanumeric and the number of total possible keys a little		// bigger.		int IVlen = BLOCK_LENGTH;				byte[] iv = null;		if(cryptoAlgorithmShort.equals(AES))		{			IVlen = AES_IV_LENGTH;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -