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

📄 jcecipherfactory.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			//			generatedKey = generateUniqueBytes();			properties.put(RawStoreFactory.ENCRYPTED_KEY, saveSecretKey(generatedKey, bootPassword));		}		else		{			generatedKey = getDatabaseSecretKey(properties, bootPassword, SQLState.SERVICE_WRONG_BOOT_PASSWORD);		}		return generatedKey;	}	public void stop()	{	}	/**		get the secretkey used for encryption and decryption when boot password mechanism is used for encryption		Steps include 		retrieve the stored key, decrypt the stored key and verify if the correct boot password was passed 		There is a possibility that the decrypted key includes the original key and padded bytes in order to have		been block size aligned during encryption phase. Hence extract the original key 				@param	properties	properties to retrieve the encrypted key  		@param	bootPassword	boot password used to connect to the encrypted database		@param	errorState	errorstate to account for any errors during retrieval /creation of the secretKey		@return the original unencrypted key bytes to use for encryption and decrytion   		         */	private byte[] getDatabaseSecretKey(Properties properties, byte[] bootPassword, String errorState) throws StandardException {		// recover the generated secret encryption key from the		// services.properties file and the user key.		String keyString = properties.getProperty(RawStoreFactory.ENCRYPTED_KEY);		if (keyString == null)			throw StandardException.newException(errorState);		int encodedKeyCharLength = keyString.indexOf('-');		if (encodedKeyCharLength == -1) // bad form			throw StandardException.newException(errorState);		int verifyKey = Integer.parseInt(keyString.substring(encodedKeyCharLength+1));		byte[] generatedKey = decryptKey(keyString, encodedKeyCharLength, bootPassword);		int checkKey = digest(generatedKey);		if (checkKey != verifyKey)			throw StandardException.newException(errorState);		// if encodedKeyLength is not defined, then either it is an old version with no support for different		// key sizes and padding except for defaults	        byte[] result;			if(encodedKeyLength != 0)		{			result = new byte[encodedKeyLength];			// extract the generated key without the padding bytes			System.arraycopy(generatedKey,0,result,0,encodedKeyLength);			return result;		}		return generatedKey;	}	private String saveSecretKey(byte[] secretKey, byte[] bootPassword) throws StandardException {		String encryptedKey = encryptKey(secretKey, bootPassword);		// make a verification key out of the message digest of		// the generated key		int verifyKey = digest(secretKey);		return encryptedKey.concat("-" + verifyKey);	}	public String changeBootPassword(String changeString, Properties properties, CipherProvider verify)		throws StandardException {		// the new bootPassword is expected to be of the form		// oldkey , newkey.		int seperator = changeString.indexOf(',');		if (seperator == -1)			throw StandardException.newException(SQLState.WRONG_PASSWORD_CHANGE_FORMAT);		String oldBP = changeString.substring(0, seperator).trim();		byte[] oldBPAscii = StringUtil.getAsciiBytes(oldBP);		if (oldBPAscii == null || oldBPAscii.length < CipherFactory.MIN_BOOTPASS_LENGTH)			throw StandardException.newException(SQLState.WRONG_BOOT_PASSWORD);;		String newBP = changeString.substring(seperator+1).trim();		byte[] newBPAscii = StringUtil.getAsciiBytes(newBP);		if (newBPAscii == null || newBPAscii.length < CipherFactory.MIN_BOOTPASS_LENGTH)			throw StandardException.newException(SQLState.ILLEGAL_BP_LENGTH,                new Integer(CipherFactory.MIN_BOOTPASS_LENGTH));		// verify old key		byte[] generatedKey = getDatabaseSecretKey(properties, oldBPAscii, SQLState.WRONG_BOOT_PASSWORD);		// make sure the oldKey is correct		byte[] IV = generateIV(generatedKey);		if (!((JCECipherProvider) verify).verifyIV(IV))			throw StandardException.newException(SQLState.WRONG_BOOT_PASSWORD);		// Make the new key.  The generated key is unchanged, only the		// encrypted key is changed.		String newkey = saveSecretKey(generatedKey, newBPAscii);				properties.put(Attribute.CRYPTO_KEY_LENGTH,keyLengthBits+"-"+encodedKeyLength);				return saveSecretKey(generatedKey, newBPAscii);	}	/**	 	perform actions with privileges enabled.	 */	public final Object run() throws StandardException, InstantiationException, IllegalAccessException {		try {			switch(action)			{				case 1:					Security.addProvider(					(Provider)(Class.forName(cryptoProvider).newInstance()));					break;				case 2:					// SECURITY PERMISSION - MP1 and/or OP4					// depends on the value of activePerms					return activeFile.getRandomAccessFile(activePerms);			}		} catch (ClassNotFoundException cnfe) {			throw StandardException.newException(SQLState.ENCRYPTION_NO_PROVIDER_CLASS,cryptoProvider);		}		catch(FileNotFoundException fnfe) {			throw StandardException.newException(SQLState.ENCRYPTION_UNABLE_KEY_VERIFICATION,cryptoProvider);		}		return null;	}	/**	    The database can be encrypted with an encryption key given in connection url.	    For security reasons, this key is not made persistent in the database.	    But it is necessary to verify the encryption key when booting the database if it is similar	    to the one used when creating the database	    This needs to happen before we access the data/logs to avoid the risk of corrupting the 	    database because of a wrong encryption key.	    This method performs the steps necessary to verify the encryption key if an external	    encryption key is given.	    At database creation, 4k of random data is generated using SecureRandom and MD5 is used	    to compute the checksum for the random data thus generated.  This 4k page of random data	    is then encrypted using the encryption key. The checksum of unencrypted data and	    encrypted data is made persistent in the database in file by name given by	    Attribute.CRYPTO_EXTERNAL_KEY_VERIFYFILE (verifyKey.dat). This file exists directly under the	    database root directory.	    When trying to boot an existing encrypted database, the given encryption key is used to decrypt	    the data in the verifyKey.dat and the checksum is calculated and compared against the original	    stored checksum. If these checksums dont match an exception is thrown.	    Please note, this process of verifying the key  does not provide any added security but only is 	    intended to allow to fail gracefully if a wrong encryption key is used	    @return StandardException is thrown if there are any problems during the process of verification	    		of the encryption key or if there is any mismatch of the encryption key.	 */	public void verifyKey(boolean create, StorageFactory sf, Properties properties)		throws StandardException	{		if(properties.getProperty(Attribute.CRYPTO_EXTERNAL_KEY) == null)			return;		// if firstTime ( ie during creation of database, initial key used )		// In order to allow for verifying the external key for future database boot,		// generate random 4k of data and store the encrypted random data and the checksum		// using MD5 of the unencrypted data. That way, on next database boot a check is performed		// to verify if the key is the same as used when the database was created		StorageRandomAccessFile verifyKeyFile = null;		byte[] data = new byte[VERIFYKEY_DATALEN];		try		{			if(create)			{				getSecureRandom().nextBytes(data);				// get the checksum				byte[] checksum = getMD5Checksum(data);				CipherProvider tmpCipherProvider = createNewCipher(ENCRYPT,mainSecretKey,mainIV);				tmpCipherProvider.encrypt(data, 0, data.length, data, 0);				// openFileForWrite				verifyKeyFile = privAccessFile(sf,Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE,"rw");				// write the checksum length as int, and then the checksum and then the encrypted data				verifyKeyFile.writeInt(checksum.length);				verifyKeyFile.write(checksum);				verifyKeyFile.write(data);				verifyKeyFile.sync(true);			}			else			{				// open file for reading only				verifyKeyFile = privAccessFile(sf,Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE,"r");				// then read the checksum length 				int checksumLen = verifyKeyFile.readInt();				byte[] originalChecksum = new byte[checksumLen];				verifyKeyFile.readFully(originalChecksum);				verifyKeyFile.readFully(data);				// decrypt data with key				CipherProvider tmpCipherProvider = createNewCipher(DECRYPT,mainSecretKey,mainIV);				tmpCipherProvider.decrypt(data, 0, data.length, data, 0);				byte[] verifyChecksum = getMD5Checksum(data);				if(!MessageDigest.isEqual(originalChecksum,verifyChecksum))				{					throw StandardException.newException(SQLState.ENCRYPTION_BAD_EXTERNAL_KEY);				}			}		}		catch(IOException ioe)		{			throw StandardException.newException(SQLState.ENCRYPTION_UNABLE_KEY_VERIFICATION,ioe);		}		finally		{			try			{				if(verifyKeyFile != null)					verifyKeyFile.close();			}			catch(IOException ioee)			{				throw StandardException.newException(SQLState.ENCRYPTION_UNABLE_KEY_VERIFICATION,ioee);			}		}		return ;	}	/**		Use MD5 MessageDigest algorithm to generate checksum		@param data	data to be used to compute the hash value		@return returns the hash value computed using the data	 */	private byte[] getMD5Checksum(byte[] data)		throws StandardException	{		try		{			// get the checksum			MessageDigest md5 = MessageDigest.getInstance("MD5");			return md5.digest(data);		}		catch(NoSuchAlgorithmException nsae)		{			throw StandardException.newException(SQLState.ENCRYPTION_BAD_ALG_FORMAT,MESSAGE_DIGEST);		}	}	/**	 	access a file for either read/write	 	@param storageFactory	factory used for io access	 	@param	fileName		name of the file to create and open for write 							The file will be created directly under the database root directory		@param	filePerms		file permissions, if "rw" open file with read and write permissions							    if "r" , open file with read permissions	 	@return	StorageRandomAccessFile returns file with fileName for writing		@exception IOException Any exception during accessing the file for read/write	 */	private StorageRandomAccessFile privAccessFile(StorageFactory storageFactory,String fileName,String filePerms)		throws java.io.IOException	{		StorageFile verifyKeyFile = storageFactory.newStorageFile("",fileName);		activeFile  = verifyKeyFile;		this.action = 2;		activePerms = filePerms;	    try        {			return (StorageRandomAccessFile)java.security.AccessController.doPrivileged(this);		}		catch( java.security.PrivilegedActionException pae)		{			throw (java.io.IOException)pae.getException();		}	}}

⌨️ 快捷键说明

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