Jac*_*ack 22 java mysql tomcat spring-security
将数据库的用户名和密码保存在xml文件中并将其导入spring security的安全文件中是一个好主意吗?还有更好的选择吗?如果我需要加密密码怎么做以及如何在phpMyAdmin上找到加密版本的密码?MySQL的
登录-service.xml中
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/muDB" />
<property name="username" value="jack" />
<property name="password" value="alex123432" />
</bean>
</beans>
Run Code Online (Sandbox Code Playgroud)
MyProject的-security.xml文件
....
<beans:import resource='login-service.xml'/>
....
Run Code Online (Sandbox Code Playgroud)
请注意:由于所有用户相关的密码都已加密,我只想隐藏DATABASE本身的密码而不是表格列.我的应用程序将使用此密码连接到数据库.
jec*_*nom 31
首先,您应该知道,无论您做什么,如果攻击者获得对您的服务器文件的访问权限,他将能够窃取密码.
如果您使用应用服务器的数据源,则只需将明文密码的位置移动到其他文件即可.
如果您使用某种形式的加密来避免存储明文密码,那么您的应用仍然需要使用其已有的另一个密码对其进行解密.如果攻击者竭尽全力访问您的系统,您可以相信他也会知道这一点.你正在做的是混淆(并获得虚假的安全感)而不是实际保护它.
更安全的解决方案是让用户在应用启动期间提供密码(或密码来解密数据库密码),但这会使管理变得非常困难.如果你已经是偏执狂(安全性很好,而不是那种疯狂的那种)有人可以访问你的服务器,你应该考虑到DB密码将驻留在系统内存中.
除此之外,请将密码保存在配置文件中(您可以相当确信服务器不会向外界显示),锁定系统并仅为数据库用户提供所需的最低权限.
配置密码真的很糟糕,并没有银弹.然而,这种解决方案适用于大多数安全性bla-bla-bla.最重要的是,它还会混淆SCM中的凭据.
PropertyPlaceholderConfigurer:
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
public class EncryptedPropertyPlacementConfigurer extends PropertyPlaceholderConfigurer
{
/** algorithm used for encrpytion and decryption */
private static final String ALGORITHM = "PBEWithMD5AndDES";
/** 8-byte Salt. */
private static final byte[] SALT = { ... };
/** Iteration count. */
private static final int ITERATION_COUNT = 19;
/** Stores parameter specification. */
private static final AlgorithmParameterSpec PARAM_SPEC = new PBEParameterSpec(SALT, ITERATION_COUNT);
//All properties starting with !! will be decrypted.
private static final String ENCRYPTIGION_LEADIN = "!!";
public static class EncrypterException extends RuntimeException
{
private static final long serialVersionUID = -7336009350594115318L;
public EncrypterException(final String message, final Throwable cause)
{
super(message, cause);
}
public EncrypterException(final String message)
{
super(message);
}
}
private static String decrypt(final String passPhrase, final String message)
{
// Create the key
final KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), SALT, ITERATION_COUNT);
SecretKey key;
try
{
key = SecretKeyFactory.getInstance(ALGORITHM).generateSecret(keySpec);
}
catch (final Exception e)
{
throw new EncrypterException("Error setting up encryption details.", e);
}
if (!Base64.isBase64(message))
{
throw new EncrypterException("Message is not a valid base64 message.");
}
final String result;
try
{
final Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key, PARAM_SPEC);
final byte[] dec = Base64.decodeBase64(message);
result = new String(cipher.doFinal(dec), "UTF-8");
}
catch (final Exception e)
{
throw new EncrypterException("Error decrypting content.", e);
}
return result;
}
@Override
protected String convertPropertyValue(final String originalValue)
{
if (StringUtils.isNotBlank(originalValue) && originalValue.startsWith(ENCRYPTIGION_LEADIN))
{
return decrypt("<Your magic password>", originalValue.substring(2));
}
return super.convertPropertyValue(originalValue);
}
}
Run Code Online (Sandbox Code Playgroud)
你的豆子:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="propertyPlaceholderConfigurer" class="...EncryptedPropertyPlacementConfigurer ">
<property name="location" value="classpath:/spring.properties" />
<property name="ignoreResourceNotFound" value="true" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean>
</beans>
Run Code Online (Sandbox Code Playgroud)
你的财产档案:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/muDB
jdbc.user=!!ar7CWlcL8eI=
jdbc.password=!!ar7CWlcL8eI=
Run Code Online (Sandbox Code Playgroud)
注意: 如果您使用无限制的JCE策略,您也可以使用更好的加密算法,但由于我们除了混淆之外什么也没做,这样做就可以了,并且不会让您最终得到调试会话.
更新:
您可以使用它来生成密码:
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import org.apache.commons.codec.binary.Base64;
public class Main
{
private static class DesEncrypter
{
/** algorithm used for encrpytion and decryption */
private static final String ALGORITHM = "PBEWithMD5AndDES";
/** 8-byte Salt. */
private static final byte[] SALT = { <You salt> };
/** Iteration count. */
private static final int ITERATION_COUNT = 19;
/** Stores parameter specification. */
private static final AlgorithmParameterSpec PARAM_SPEC = new PBEParameterSpec(
SALT, ITERATION_COUNT);
/** Key specification. */
private final KeySpec keySpec;
/** Secret key. */
private final SecretKey key;
public DesEncrypter(final String passPhrase)
{
// Create the key
keySpec = new PBEKeySpec(passPhrase.toCharArray(), SALT, ITERATION_COUNT);
try
{
key = SecretKeyFactory.getInstance(ALGORITHM).generateSecret(keySpec);
}
catch (final Exception ex)
{
throw new RuntimeException("Could not create DesEncrypter: " + ex.getMessage(), ex);
}
}
public final String encrypt(final String message)
{
try
{
// Create cipher instance
final Cipher cipher = Cipher.getInstance(ALGORITHM);
// Initialize cipher
cipher.init(Cipher.ENCRYPT_MODE, key, PARAM_SPEC);
// Encode string
final byte[] enc = cipher.doFinal(message.getBytes("UTF8"));
// Encode bytes to base64 to get a string
return Base64.encodeBase64String(enc);
}
catch (final Exception ex)
{
throw new RuntimeException("Error encrypting message.", ex);
}
}
}
public static void main(final String[] args)
{
if (args.length == 2)
{
System.out.println("!!" + new DesEncrypter(args[0]).encrypt(args[1]));
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
31317 次 |
| 最近记录: |