日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

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

發布時間:2023/12/3 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 glassfish默认密码_在MySQL上使用含盐密码的GlassFish JDBC安全性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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帖子以獲得完整的設置。

什么是弱項或缺失項?

開箱即用的解決方案非常簡單。 它只是對密碼進行哈希處理。 有很多方法可以非常快速地從普通哈希中恢復密碼。 破解哈希的最簡單方法是嘗試猜測密碼,對每個猜測進行哈希處理,并檢查猜測的哈希是否等于被破解的哈希。 如果哈希值相等,則猜測為密碼。 猜測密碼的兩種最常見方式是字典攻擊和蠻力攻擊。 查找表也是眾所周知的。 它們是非??焖俚仄平庠S多相同類型哈希的有效方法。 總體思路是在密碼字典中預先計算密碼的哈希值,并將它們及其對應的密碼存儲在查找表數據結構中。 但是我們現在還沒有完成。 您還會發現稱為反向查找表的內容。 這種攻擊使攻擊者可以同時對多個散列應用字典或蠻力攻擊,而無需預先計算查找表。 最后但并非最不重要的彩虹表攻擊。 它們就像查找表,只是它們犧牲了散列破解速度以使查找表更小。 令人印象深刻的方法列表。 顯然,這不能滿足我個人對密碼保護的需求。

加一些鹽

上述方法之所以有效,是因為每個密碼都以完全相同的方式進行哈希處理。 每次通過安全哈希函數運行密碼時,都會產生完全相同的輸出。 防止這種情況的一種方法是在其中添加一些鹽。 在對哈希進行哈希運算之前,將一個隨機字符串添加或添加到密碼之前可以解決此問題。 該隨機字符串稱為“鹽”。 請注意,對于所有密碼重用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安全性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。