glassfish默认密码

我在该博客上最成功的文章之一是有关在GlassFish上使用基于表单的身份验证设置JDBC安全领域的文章 。 对这篇文章的一些评论使我意识到,要真正使它安全,应该做的还很多。

开箱即用的安全性

图片: TheKenChan ( CC BY-NC 2.0 )

GlassFish已经附带了GlassFish JDBC领域 。 您所要做的就是初始化数据库并正确获得安全性配置,然后就可以完成。 在标准配置中,您可以选择定义摘要算法(包括编码和字符集)。 摘要算法可以是任何JDK支持的 MessageDigest(MD2,MD5,SHA-1,SHA-256,SHA-384,SHA-512)。 比较我的JDBC Security Realm帖子以获得完整的设置。

什么是弱项或缺失项?

开箱即用的解决方案非常简单。 它只是对密码进行哈希处理。 有很多方法可以非常快速地从普通哈希中恢复密码。 破解哈希的最简单方法是尝试猜测密码,对每个猜测进行哈希处理,并检查猜测的哈希是否等于被破解的哈希。 如果哈希值相等,则猜测为密码。 猜测密码的两种最常见方式是字典攻击和蛮力攻击。 查找表也是众所周知的。 它们是非常快速地破解许多相同类型哈希的有效方法。 总体思路是在密码字典中预先计算密码的哈希值,并将它们及其对应的密码存储在查找表数据结构中。 但是我们现在还没有完成。 您还会发现称为反向查找表的内容。 这种攻击使攻击者可以同时对多个散列应用字典或蛮力攻击,而无需预先计算查找表。 最后但并非最不重要的彩虹表攻击。 它们就像查找表,只是它们牺牲了散列破解速度以使查找表更小。 令人印象深刻的方法列表。 显然,这不能满足我个人对密码保护的需求。

加一些盐

上述方法之所以有效,是因为每个密码都以完全相同的方式进行哈希处理。 每次通过安全哈希函数运行密码时,都会产生完全相同的输出。 防止这种情况的一种方法是在其中添加一些盐。 在对哈希进行哈希运算之前,将一个随机字符串添加或添加到密码之前可以解决此问题。 该随机字符串称为“盐”。 请注意,对于所有密码重用salt并不安全。 您仍然可以使用彩虹表或字典攻击来破解它们。 因此,您必须为每个密码随机分配盐,并将其存储在哈希密码旁边。 每次用户更新密码时,它都需要更改。 关于长度的简短句子。 盐不要太短。 对于最有效的长度,其长度应与密码哈希相同。 如果使用SHA512(512/8位= 64字节),则应选择长度至少为64个随机字节的盐。

准备工作

我们现在显然已经离开了标准的JDBCRealm功能。 这意味着我们必须实现自己的安全领域。 从现在开始,我们将其称为UserRealm。 让我们从与JDBCRealm相同的设置开始。 具有“ jdbcrealmdb”架构MySQL数据库。 唯一的区别是,我们准备使用每个密码来保存盐。

USE jdbcrealmdb;
CREATE TABLE `jdbcrealmdb`.`users` (
`username` varchar(255) NOT NULL,
`salt` varchar(255) NOT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `jdbcrealmdb`.`groups` (
`username` varchar(255) DEFAULT NULL,
`groupname` varchar(255) DEFAULT NULL)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE INDEX groups_users_FK1 ON groups(username ASC);

现在,我们实现了基本领域。 以下代码仅显示了强制成员。 我将在接下来的几天中提供该资源。 直到今天,这篇文章仍然可供您使用。

public class UserRealm extends AppservRealm {
/**
* Init realm from properties
*/
protected void init(Properties props)
/**
* Get JAASContext
*/
public String getJAASContext()
/**
* Get AuthType
*/
public String getAuthType()
/**
* Get DB Connection
*/
private Connection getConnection()
/**
* Close Connection
*/
private void closeConnection(Connection cn)
/**
* Close prepared statement
*/
private void closeStatement(PreparedStatement st)
/**
* Make the compiler happy.
*/
public Enumeration getGroupNames(String string)
/**
* Authenticate the user
*/
public String[] authenticate(String userId, String password)
}

但最重要的部分在这里缺失。

设置一些测试

我不是那种受测试驱动的人,但在这种情况下,这确实是有道理的。 因为我将在此处实现的领域不支持通过GlassFish管理控制台进行用户管理。 因此,基本要求是要准备好具有所有用户,密码和盐的数据库。 我们走吧。 添加sql-maven-plugin并在测试编译阶段使其创建表。

<plugin><groupId>org.codehaus.mojo</groupId><artifactId>sql-maven-plugin</artifactId><version>1.3</version><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.18</version></dependency></dependencies><configuration><driver>${driver}</driver><url>${url}</url><username>${username}</username><password>${password}</password><skip>${maven.test.skip}</skip><srcFiles><srcFile>src/test/data/drop-and-create-table.sql</srcFile></srcFiles></configuration><executions><execution><id>create-table</id><phase>test-compile</phase><goals><goal>execute</goal></goals></execution></executions></plugin>

您可以使用一些db-unit magic将测试数据插入数据库中,也可以在测试用例中执行此操作。 我决定走这条路。 首先,让我们将所有相关的JDBC内容放到一个称为SecurityStore的单独位置。 我们基本上需要三种方法。 添加一个用户,为用户添加盐分并验证该用户。

private final static String ADD_USER = "INSERT INTO users VALUES(?,?,?);";private final static String SALT_FOR_USER = "SELECT salt FROM users u WHERE username = ?;";private final static String VERIFY_USER = "SELECT username FROM users u WHERE username = ? AND password = ?;";
//...
public void addUser(String name, String salt, String password) {try {PreparedStatement pstm = con.prepareStatement(ADD_USER);pstm.setString(1, name);pstm.setString(2, salt);pstm.setString(3, password);pstm.executeUpdate();} catch (SQLException ex) {LOGGER.log(Level.SEVERE, "Create User failed!", ex);}}public String getSaltForUser(String name) {String salt = null;try {PreparedStatement pstm = con.prepareStatement(SALT_FOR_USER);pstm.setString(1, name);ResultSet rs = pstm.executeQuery();if (rs.next()) {salt = rs.getString(1);}} catch (SQLException ex) {LOGGER.log(Level.SEVERE, "User not found!", ex);}return salt;}public boolean validateUser(String name, String password) {try {PreparedStatement pstm = con.prepareStatement(VERIFY_USER);pstm.setString(1, name);pstm.setString(2, password);ResultSet rs = pstm.executeQuery();if (rs.next()) {return true;}} catch (SQLException ex) {LOGGER.log(Level.SEVERE, "User validation failed!", ex);}return false;}

为了在这里不执行太多,我决定有两个单独的构造函数:

public SecurityStore(String dataSource)
public SecurityStore(String user, String passwd)

因此,这将与应用程序服务器和本地测试一起使用。 接下来是实际的密码和盐逻辑。

使用密码,哈希和盐

这是我想出的:

public class Password {private SecureRandom random;private static final String CHARSET = "UTF-8";private static final String ENCRYPTION_ALGORITHM = "SHA-512";private BASE64Decoder decoder = new BASE64Decoder();private BASE64Encoder encoder = new BASE64Encoder();public byte[] getSalt(int length) {random = new SecureRandom();byte bytes[] = new byte[length];random.nextBytes(bytes);return bytes;}public byte[] hashWithSalt(String password, byte[] salt) {byte[] hash = null;try {byte[] bytesOfMessage = password.getBytes(CHARSET);MessageDigest md;md = MessageDigest.getInstance(ENCRYPTION_ALGORITHM);md.reset();md.update(salt);md.update(bytesOfMessage);hash = md.digest();} catch (UnsupportedEncodingException | NoSuchAlgorithmException ex) {Logger.getLogger(Password.class.getName()).log(Level.SEVERE, "Encoding Problem", ex);}return hash;}public String base64FromBytes(byte[] text) {return encoder.encode(text);}public byte[] bytesFrombase64(String text) {byte[] textBytes = null;try {textBytes = decoder.decodeBuffer(text);} catch (IOException ex) {Logger.getLogger(Password.class.getName()).log(Level.SEVERE, "Encoding failed!", ex);}return textBytes;}
}

很简单,对不对? 老实说:使用byte []可以更好地隐藏,但是我认为您会更容易理解这里发生的事情。 salt()方法返回配置长度的安全随机盐。 hashWithSalt()方法将所有内容放入一个SHA-512哈希密码中。

关于结束码

我决定对它进行Base64编码,并且正在使用专有的API(sun.misc.BASE64Decoder,Encoder)。 您应该在这里考虑使用Apache Commons。 但这是最简单的方法。 另一种方法是简单地对所有内容进行十六进制编码(零填充)。 Base64和HEX之间的区别实际上只是字节的表示方式。 十六进制是表示“ Base16”的另一种方式。 十六进制将为每个字节占用两个字符– Base64每三个字节将占用4个字符,因此它比十六进制更有效。 假设您使用UTF-8编码XML文档,则100K文件将需要200K进行十六进制编码,而在Base64中则需要133K。

最后是UserRealm中缺少的方法

这篇冗长的文章的最后一部分是UserRealm类中的authenticate方法。

/*** Authenticates a user against GlassFish** @param name The user name* @param givenPwd The password to check* @return String[] of the groups a user belongs to.* @throws Exception*/public String[] authenticate(String name, String givenPwd) throws Exception {SecurityStore store = new SecurityStore(dataSource);// attempting to read the users-saltString salt = store.getSaltForUser(name);// Defaulting to a failed login by setting nullString[] result = null;if (salt != null) {Password pwd = new Password();// get the byte[] from the saltbyte[] saltBytes = pwd.bytesFrombase64(salt);// hash password and saltbyte[] passwordBytes = pwd.hashWithSalt(givenPwd, saltBytes);// Base64 encode to StringString password = pwd.base64FromBytes(passwordBytes);_logger.log(Level.FINE, "PWD Generated {0}", password);// validate password with the dbif (store.validateUser(name, password)) {result[0] = "ValidUser";}}return result;}

这就是所有要做的事情。 如果给定用户名带有盐,我们将生成一个哈希密码,该密码将与数据库中的密码进行核对。 getSaltForUser()也是我们对用户是否存在的隐式检查。

使密码破解更加困难:哈希函数慢

如果安全性不增加更多,则不会被称为安全性。 因此,加盐的密码比简单的散列密码要好得多,但可能仍然不够,因为它们仍然允许对任何单个散列进行暴力破解或字典攻击。 但是您可以添加更多保护。 关键字是key-stretching 。 也称为慢散列函数。 这里的想法是使计算速度足够慢,从而不再允许CPU / GPU驱动的攻击。 它使用特殊的CPU密集型哈希函数实现。 PBKDF2 (基于密码的密钥派生功能2)就是其中之一。 您可以以不同的方式使用它,但只能警告一个:切勿自己尝试这样做。 使用像的测试并提供实现方式的一个PBKDF2WithHmacSHA1从JDK或PKCS5S2ParametersGenerator从BouncyCastle的库。 一个示例可能如下所示:

public byte[] hashWithSlowsalt(String password, byte[] salt) {SecretKeyFactory factory;Key key = null;try {factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");KeySpec keyspec = new PBEKeySpec(password.toCharArray(), salt, 1000, 512);key = factory.generateSecret(keyspec);} catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {Logger.getLogger(Password.class.getName()).log(Level.SEVERE, null, ex);}return key.getEncoded();}

为什么要这样?

我们听说密码和用户数据库泄漏很多。 每天。 一些大型站点受到了攻击,而实现者为其用户提供适当的安全性基本上取决于实施者。 坦白地说,使用提供的功能很难知道在哪里进行调整以及如何进行调整,从而使您感到不舒服。 不要停止学习安全功能,并时刻注意可能出现的问题。 我个人希望GlassFish为用户提供一套更全面的默认领域。 但是只要不是这种情况,我的博客就是引导您朝正确方向发展的唯一途径。 希望您喜欢它!

参考:来自JCG合作伙伴 Markus Eisele在MySQL 企业软件开发博客上MySQL上带有咸密码的GlassFish JDBC安全性 。

翻译自: https://www.javacodegeeks.com/2012/07/glassfish-jdbc-security-with-salted.html

glassfish默认密码

glassfish默认密码_在MySQL上使用含盐密码的GlassFish JDBC安全性相关推荐

  1. mysql重置root密码centos_Centos7重置Mysql 8.0.1 root 密码

    问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码:找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc ...

  2. mysql删除默认密码_修改mysql默认密码方法

    问题描述 今天在MAC上安装完MYSQL后,MYSQL默认给分配了一个默认密码,但当自己在终端上使用默认密码登录的时候,总会提示一个授权失败的错误:Access denied for user 'ro ...

  3. Linux重置Mysql密码_解决MySQL for Linux错误 ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost

    Linux重置Mysql密码 一般这个错误是由密码错误引起,解决的办法自然就是重置密码. 假设我们使用的是root账户. 1.重置密码的第一步就是跳过MySQL的密码认证过程,方法如下: #vim / ...

  4. MySQL记住密码_技术分享 | mysqlsh 命令行模式 密码保存

    作者:胡呈清 爱可生 DBA 团队成员,擅长故障分析.性能优化,个人博客:https://www.jianshu.com/u/a95ec11f67a8,欢迎讨论. 本文来源:原创投稿 *爱可生开源社区 ...

  5. mysql 默认字符集_设定mysql的默认字符集

    mysql> show global variables like '%charac%';    --查看当前mysql采用的字符集 mysql>show global variables ...

  6. mysql初始话密码_您所说的话:如何跟踪密码

    mysql初始话密码 Earlier this week we asked you to share your techniques for managing and organizing your ...

  7. 找回mysql root密码_找回MySQL的root密码

    实验介绍:MySQL的root密码丢失,无法登陆.需要重置其root密码 环境介绍:编译安装的MySQL 这篇博客介绍的找回 mysql root 密码是 mysql 基于编译安装的,如果是多实例下的 ...

  8. c mysql 的默认值_为mysql表字段设置默认值的方法及注意细节

    为mysql表字段设置默认值的方法及注意细节,有需要的朋友可以参考下. 环境:MySQL 5.1 + 命令行工具 问题:MySQL表字段设置默认值 解决方法: 代码如下: --SQL: CREATE ...

  9. 忘记本地mysql密码_本地MySQL密码忘了,怎么找回?

    展开全部 MySQL密码通常保存在mysql数据库中,我们可以在访问数据之后,使用如下指令进32313133353236313431303231363533e58685e5aeb93133336564 ...

最新文章

  1. 再次分享一个多选文件上传方案“.NET研究”
  2. Linux操作系统安装---centos6.7安装图文实例详解(完整版)
  3. 今天 学习用到的一些知识(properties 读取,js 删除元素)
  4. 深入理解 MySQL ——锁、事务与并发控制
  5. 英文文章如何进行略读
  6. (NO.00003)iOS游戏简单的机器人投射游戏成形记(一)
  7. 机器学习--Lasso回归(LassoRegression)
  8. (1)前端工程化—全副武装:通过工程化提升「战斗力」
  9. strlen 计算给定字符串的长度
  10. 节约中小企业运维成本方案
  11. 知识付费平台现状:供应商、购买者议价能力较
  12. Python中使用seek方法来移动文件指针的位置
  13. Frank-Wolf算法
  14. 船讯网|爬虫COOKIE重定向反爬处理
  15. Electron无边框模式下禁止双击最大化窗口
  16. Java工具类实现excel转pdf结果几乎一模一样
  17. 更换鼠标垫(鼠标)的心路历程
  18. CAP迷思:关于分区容忍性
  19. 这款开源的STM32外设驱动库,可以直接拿来用!
  20. Castor简单介绍

热门文章

  1. Oracle入门(七)之表空间
  2. 使用C#操作XML文件
  3. 银行营业网点管理系统——entity类(Branches)
  4. TS字面量进行类型声明
  5. java计算混淆矩阵(分类指标:查准率P,查全率R,P和R的调和均值F1,正确率A)
  6. XML——写出XML文档(XSLT+StAX)
  7. java集合——集合与数组间的转换+算法
  8. jdk switch 枚举_JDK 12开关表达式遇到意外的枚举值
  9. swarm 容器_Oracle应用容器云上的WildFly Swarm
  10. oauth 使用令牌_使用OAuth2令牌的安全REST服务