查看: 1560|回复: 25
|
你们是怎样提升系统的保安的?
[复制链接]
|
|
发表于 6-4-2007 12:00 AM
|
显示全部楼层
md5
不错一下 |
|
|
|
|
|
|
|

楼主 |
发表于 6-4-2007 12:00 AM
|
显示全部楼层
让我先开始,
我就以系统的最前(Login Window)开始
如果系统有Login的,
我个人认为当User输入错的Password时最好不要用MessageBox来Prompt
因为如果遇到Hacker,会很容易被Trace到,
一两分钟就可以轻而易举的Crack掉Login Window了
比如如果User输入错的Password时系统会Prompt "Invalid Password"之类的
只要在Debugger里寻找"Invalid Password"就可以轻易跳过Password Check了
给个例子:

只要NOP掉00401C7E那一行,就可以跳过了
(我不是在教你们如何破解,只是在提意见如何防止你们的系统被破解,请不要滥用)
[ 本帖最后由 hcong85 于 6-4-2007 12:16 AM 编辑 ] |
|
|
|
|
|
|
|

楼主 |
发表于 6-4-2007 12:10 AM
|
显示全部楼层
原帖由 红发 于 6-4-2007 12:00 AM 发表
md5
不错一下
怎样用?可不可以给例子啊? |
|
|
|
|
|
|
|

楼主 |
发表于 6-4-2007 10:12 PM
|
显示全部楼层
接下来要和大家分享的是我如何存密码在Database里
当我一开始学Database时,
我是以Plane Text直接存放在Database里.
后来在老师口中得知 XOR 可以用来做Encryption
于是就开始研究如何Encrypt密码
终于我用 XOR 成功写出Encrypt和Decrypt的Functions
Encrypt 是把密码加入" rivate Key" Encrypt成一个Random的String(当然每次Encrypt出来的都不一样,不然很容易就被人家Decrypt去了)
Decrypt 则是把Encrypt出来的Random String加入用来Encrypt的" rivate Key" Decrypt回原来的密码
学会了Encryption,当然要把它运用在系统里以提高保安啦
在学院的Project里就用了这一招,可惜只得了一个 A-
最近又在佳礼看到exiang大哥说MD5是one way hash code,
很感谢他的那句话教会了我新的存密码的方法
对以前的我来说,CRC32, MD5 之类的东东只是用来测试Data或File有没有被改过或是损坏
现在又多学了一招,
就是把密码算出MD5再存进Database里,
然后每当用户输入密码时我再把他输入的密码算出MD5再和Database里的MD5做比较
这样做会避免了密码被Decrypt,因为MD5是one way hash code,
即使密码的Database被人偷了,他们也那不到密码
即使系统是我们写的,我们也没有办法读取密码.(提高了用户的安心)
今天先分享到这里
如果我有那里说错了记得要纠正我哦
小弟在次先谢过大家用心看我写的帖子
如果有更好的方法也欢迎进来分享 
[ 本帖最后由 hcong85 于 7-4-2007 11:20 PM 编辑 ] |
|
|
|
|
|
|
|
发表于 7-4-2007 10:54 AM
|
显示全部楼层
|
|
|
|
|
|
|

楼主 |
发表于 7-4-2007 06:06 PM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 7-4-2007 06:36 PM
|
显示全部楼层
encrypt 的方法有很多, 看看 Cryptography 就懂了
什么 Hash-Algorithm (就像楼上提到的 MD5), 什么 Checksum-Algorithm (就像楼上提到的 XOR),
什么 Encryption-Algorithm 等等
我看过一个软件是用打字的速度来 generate code
然后要 decrypt 那些 code 才能进 |
|
|
|
|
|
|
|
发表于 7-4-2007 08:04 PM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 7-4-2007 08:15 PM
|
显示全部楼层
我在想如果我不放password。
那样人家不就是猜不到
哈 |
|
|
|
|
|
|
|
发表于 7-4-2007 08:57 PM
|
显示全部楼层
|
|
|
|
|
|
|

楼主 |
发表于 7-4-2007 10:11 PM
|
显示全部楼层
原帖由 sson 于 7-4-2007 08:04 PM 发表
不过却可以以短时间找到“碰撞”
所以在 DB 内存放密码的 MD5 也是不可靠的了,因为可以找到符合的“配对”。
加上目前的处理机越来越快,穷举法逆转也不是不可能的了。
其实我也有想过会“碰撞”
http://en.wikipedia.org/wiki/MD5
因为不关你算多大的资料,算出来的结果都差不多32Bytes左右而已,
32MB的Combination数量怎么说也多过32B吧(句个Example而已 )
所以碰撞是必然的,
所以我就帖在这里讨论,希望可以借机学到跟好的存放密码的方法
原帖由 sson 于 7-4-2007 08:04 PM 发表
不过小章鱼更喜欢压缩技术 ,不知那位可以开帖一起研究研究
压缩技术我也有兴趣有空来交流交流
我在想如果把压缩技术当Encryption用有没有可能啊
就是说把密码用自己的验算方法压缩后存放在DB里
安全又省位,
想就容易,做就...
原帖由 红发 于 7-4-2007 08:15 PM 发表
我在想如果我不放password。
那样人家不就是猜不到
哈
酱人家果然是猜不到也,
不过,也不用猜了,没有密码,就是说不用密码也能进了 
[ 本帖最后由 hcong85 于 7-4-2007 10:14 PM 编辑 ] |
|
|
|
|
|
|
|
发表于 7-4-2007 10:58 PM
|
显示全部楼层
我除了密码之外,其他重要数据都不会用MD5^^
我是用几个encrypt的方法加起来一起encrypt,当然你要记住那顺序和你的private key^^ |
|
|
|
|
|
|
|
发表于 8-4-2007 12:26 AM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 8-4-2007 12:29 AM
|
显示全部楼层
|
|
|
|
|
|
|

楼主 |
发表于 8-4-2007 01:34 AM
|
显示全部楼层
|
|
|
|
|
|
|

楼主 |
发表于 8-4-2007 01:36 AM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 8-4-2007 09:06 AM
|
显示全部楼层
原帖由 hcong85 于 7-4-2007 10:11 PM 发表
其实我也有想过会“碰撞”
http://en.wikipedia.org/wiki/MD5
因为不关你算多大的资料,算出来的结果都差不多32Bytes左右而已,
32MB的Combination数量怎么说也多过32B吧(句个Example而已 )
所以碰撞 ...
你可以加一些盐.... salted password。这里有一段java代码,可以参考一下
基本上,代码里一共重复digest了1000次 ,最后还用base64把hashedpassword和salt存到db里。
- package org.psafix.memopwd;
-
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- import java.io.IOException;
- import sun.misc.BASE64Decoder;
- import sun.misc.BASE64Encoder;
- import java.sql.*;
- import java.util.Arrays;
- import java.security.SecureRandom;
-
- public class Owasp {
- private final static int ITERATION_NUMBER = 1000;
-
- public Owasp() {
- }
-
- /**
- * Authenticates the user with a given login and password
- * If password and/or login is null then always returns false.
- * If the user does not exist in the database returns false.
- * @param con Connection An open connection to a databse
- * @param login String The login of the user
- * @param password String The password of the user
- * @return boolean Returns true if the user is authenticated, false otherwise
- * @throws SQLException If the database is inconsistent or unavailable (
- * (Two users with the same login, salt or digested password altered etc.)
- * @throws NoSuchAlgorithmException If the algorithm SHA-1 is not supported by the JVM
- */
- public boolean authenticate(Connection con, String login, String password)
- throws SQLException, NoSuchAlgorithmException{
- boolean authenticated=false;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- boolean userExist = true;
- // INPUT VALIDATION
- if (login==null||password==null){
- // TIME RESISTANT ATTACK
- // Computation time is equal to the time needed by a legitimate user
- userExist = false;
- login="";
- password="";
- }
-
- ps = con.prepareStatement("SELECT PASSWORD, SALT FROM CREDENTIAL WHERE LOGIN = ?");
- ps.setString(1, login);
- rs = ps.executeQuery();
- String digest, salt;
- if (rs.next()) {
- digest = rs.getString("PASSWORD");
- salt = rs.getString("SALT");
- // DATABASE VALIDATION
- if (digest == null || salt == null) {
- throw new SQLException("Database inconsistant Salt or Digested Password altered");
- }
- if (rs.next()) { // Should not append, because login is the primary key
- throw new SQLException("Database inconsistent two CREDENTIALS with the same LOGIN");
- }
- } else { // TIME RESISTANT ATTACK (Even if the user does not exist the
- // Computation time is equal to the time needed for a legitimate user
- digest = "000000000000000000000000000=";
- salt = "00000000000=";
- userExist = false;
- }
-
- byte[] bDigest = base64ToByte(digest);
- byte[] bSalt = base64ToByte(salt);
-
- // Compute the new DIGEST
- byte[] proposedDigest = getHash(ITERATION_NUMBER, password, bSalt);
-
- return Arrays.equals(proposedDigest, bDigest) && userExist;
- } catch (IOException ex){
- throw new SQLException("Database inconsistant Salt or Digested Password altered");
- }
- finally{
- close(rs);
- close(ps);
- }
- }
-
-
-
- /**
- * Inserts a new user in the database
- * @param con Connection An open connection to a databse
- * @param login String The login of the user
- * @param password String The password of the user
- * @return boolean Returns true if the login and password are ok (not null and length(login)<=100
- * @throws SQLException If the database is unavailable
- * @throws NoSuchAlgorithmException If the algorithm SHA-1 or the SecureRandom is not supported by the JVM
- */
- public boolean createUser(Connection con, String login, String password)
- throws SQLException, NoSuchAlgorithmException
- {
- PreparedStatement ps = null;
- try {
- if (login!=null&&password!=null&&login.length()<=100){
- // Uses a secure Random not a simple Random
- SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
- // Salt generation 64 bits long
- byte[] bSalt = new byte[8];
- random.nextBytes(bSalt);
- // Digest computation
- byte[] bDigest = getHash(ITERATION_NUMBER,password,bSalt);
- String sDigest = byteToBase64(bDigest);
- String sSalt = byteToBase64(bSalt);
-
- ps = con.prepareStatement("INSERT INTO CREDENTIAL (LOGIN, PASSWORD, SALT) VALUES (?,?,?)");
- ps.setString(1,login);
- ps.setString(2,sDigest);
- ps.setString(3,sSalt);
- ps.executeUpdate();
- return true;
- } else {
- return false;
- }
- } finally {
- close(ps);
- }
- }
-
-
- /**
- * From a password, a number of iterations and a salt,
- * returns the corresponding digest
- * @param iterationNb int The number of iterations of the algorithm
- * @param password String The password to encrypt
- * @param salt byte[] The salt
- * @return byte[] The digested password
- * @throws NoSuchAlgorithmException If the algorithm doesn't exist
- */
- public byte[] getHash(int iterationNb, String password, byte[] salt) throws NoSuchAlgorithmException {
- MessageDigest digest = MessageDigest.getInstance("SHA-1");
- digest.reset();
- digest.update(salt);
- byte[] input = digest.digest(password.getBytes());
- for (int i = 0; i < iterationNb; i++) {
- digest.reset();
- input = digest.digest(input);
- }
- return input;
- }
-
-
- public void creerTable(Connection con) throws SQLException{
- Statement st = null;
- try {
- st = con.createStatement();
- st.execute("CREATE TABLE CREDENTIAL (LOGIN VARCHAR(100) PRIMARY KEY, PASSWORD VARCHAR(32) NOT NULL, SALT VARCHAR(32) NOT NULL)");
- } finally {
- close(st);
- }
- }
-
-
-
- /**
- * Closes the current statement
- * @param ps Statement
- */
- public void close(Statement ps) {
- if (ps!=null){
- try {
- ps.close();
- } catch (SQLException ignore) {
- }
- }
- }
-
- /**
- * Closes the current resultset
- * @param ps Statement
- */
- public void close(ResultSet rs) {
- if (rs!=null){
- try {
- rs.close();
- } catch (SQLException ignore) {
- }
- }
- }
-
-
- /**
- * From a base 64 representation, returns the corresponding byte[]
- * @param data String The base64 representation
- * @return byte[]
- * @throws IOException
- */
- public static byte[] base64ToByte(String data) throws IOException {
- BASE64Decoder decoder = new BASE64Decoder();
- return decoder.decodeBuffer(data);
- }
-
- /**
- * From a byte[] returns a base 64 representation
- * @param data byte[]
- * @return String
- * @throws IOException
- */
- public static String byteToBase64(byte[] data){
- BASE64Encoder endecoder = new BASE64Encoder();
- return endecoder.encode(data);
- }
- }
-
-
复制代码
|
|
|
|
|
|
|
|

楼主 |
发表于 8-4-2007 02:20 PM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 10-4-2007 07:34 PM
|
显示全部楼层
|
|
|
|
|
|
| |
本周最热论坛帖子
|