分类 默认分类 下的文章

用户注册, 登录, 密码的存储

以下的思路中有的是说的注册过程, 有的是登录的过程, 大概类似, 注册存储到 DB, 验证只是对比结果.
对于单向加密算法, 用的比较多的是 md5 或者 SHA1, 这里以 md5 为例.

最简单, 最原始:
客户端 密码: 123456 -------------> 服务器端 存储到数据库 123456

服务器端加密存储
客户端 密码: 123456 -------------> 服务器端 加密后存储到数据库 md5(123456)

客户端加密 再传输
客户端 先加密: md5(123456) -------------> 服务器端 直接存储到数据库 md5(123456)

加盐 加密 再传输
客户端 获得 salt <-----------------------服务器端 给 salt
客户端 先加盐, 再加密: md5(123456 + salt) -------------> 服务器端 直接存储到数据库 md5(123456 + salt)

加盐 加密 再 https 传输 (安全通道)
客户端 <----------- 建立 ssl 安全通道 ---------------> 服务器端
客户端 获得 salt <-----------https---------服务器端 给 salt
客户端 先加盐, 再加密: md5(123456 + slat) -----https-----> 服务器端 直接存储到数据库 md5(123456 + salt)

加盐 加密 再 https 传输 (安全通道) 一用户一盐
客户端 <----------- 建立 ssl 安全通道 ---------------> 服务器端
客户端 获得本用户的 salt <---------https-------服务器端 从盐表获取当前用户的salt (盐表单独 server, 单独数据, 单独表)
客户端 先加盐, 再加密: md5(123456 + slat) ----https-------> 服务器端 直接存储到数据库 md5(123456 + salt)

加盐 加密 再 https 传输 (安全通道) 一用户一盐 双因子认证
客户端 <----------- 建立 ssl 安全通道 ---------------> 服务器端
客户端 获得本用户的 salt <---------https-------服务器端 从盐表获取当前用户的salt (盐表单独 server, 单独数据, 单独表)
客户端 获得第二个因子, 如 短信验证码, hard token, soft token, 邮箱获取验证码 <==另外方式===> 服务器端
客户端 先加盐, 再加密: md5(123456 + slat) 第二个因子 ----https-------> 服务器端 双因子 认证 加密后密码 + 第二因子

java.lang.Object 的 hashCode 方法 注意事项

hashCode: digests the data stored in an instance of the class into a single hash value (a 32-bit signed integer);
Technically, in Java, hashCode() by default is a native method, it is implemented directly in the native code in the JVM.

主要用在 hashTable, hashSet, HashMap等需要hash值的数据结构(hash-based collections), 有了这种离散分布的hash值, 对比操作更快;

基本的要求规范是(The hashCode contract):
1) 一个对象如果没有变化, 那么它返回的hashCode值必须前后一致;
2) 两个对象如果是 equals = true, 那么他们的hashCode 值必须一样;

没有要求说, 不同的JVM实现, 必须返回一致的hashCode值. 即使同一段程序, 在不同的执行(Run)当中, 也可以返回不同的hashCode值;
不同的对象, 返回同样的hash值, 是可以接受的(当然最好(理想)的情况下, 是返回不一样的hashCode值);
返回同样 hashCode值的对象, 不要求必须 equals;

为什么: 两个对象如果是 equals = true, 那么他们的hashCode 值必须一样?

举一个反例: 假如2个对象实例是equals的, 但是hashCode值不一样, 那么把它们两个同时放到一个hashSet, 那么它们就占用2个位置了, 但是因为它们是equals的, 所以我们认为它们应该在这个hashSet中只占一个位置, 是同一个值.

一个重写的例子 (奇数->更好的离散型):
An object’s hashCode method must take the same fields into account as its equals method.

public class Employee {
    int        employeeId;
    String     name;
    Department dept;
 
    // other methods would be in here 
 
    @Override
    public int hashCode() {
        int hash = 1;
        hash = hash * 17 + employeeId;
        hash = hash * 31 + name.hashCode();
        hash = hash * 13 + (dept == null ? 0 : dept.hashCode());
        return hash;
    }
}

HashCode collisions

Whenever two different objects have the same hash code, we call this a collision. A collision is nothing critical, it just means that there is more than one object in a single bucket, so a HashMap lookup has to look again to find the right object. A lot of collisions will degrade the performance of a system, but they won’t lead to incorrect results.
But if you mistake the hash code for a unique handle to an object, e.g use it as a key in a Map, then you will sometimes get the wrong object. Because even though collisions are rare, they are inevitable. For example, the Strings "Aa" and "BB" produce the same hashCode: 2112. Therefore, Never misuse hashCode as a key

there’s one important detail in the hashCode contract that can be quite surprising: hashCode does not guarantee the same result in different executions.

Moreover, you should be aware that the implementation of a hashCode function may change from one version to another. Therefore your code should not depend on any particular hash code values. For example, your should not use the hash code to persist state. Next time you run the application, the hash codes of the “same” objects may be different.

java.lang.String 的hashCode 实现

public int hashCode() {
    if (hashCode == 0) {
        int hash = 0, end = offset + count;
        for (int i = offset; i < end; i++) {
            hash = (hash << 5) - hash + value[i];
        }
        hashCode = hash;
    }
    return hashCode;
}

参考:

  1. wiki
  2. The 3 things you should know about hashCode()

网站访问 -> 代理 ip 检测 -> 端口扫描 -> nmap

看网站的后台浏览记录, 最近发现经常有这么一个网址: mianfeidaili.ttju.cn, 入口是这个网址, 浏览页面竟然也是这个网址. 可以猜测这是一个网页代理, 因为是访问的这个页面, 所以入口和浏览页面的网址都是这个页面.

顺着这个网址找过去, 发现是个: "提供代理IP提取" 的网站. 百度了一下, 发现类似的网站都是提供代理 ip 地址的. 通过某些扫描软件, 发现某一网段, 或者某一运营商(电信,联通,移动)的 ip 段内的免费代理. 然后卖个用户, 用户可以用这些代理刷投票等.

ip 端检测方面比较出名的是 nmap, 它可以 1) 检测该 ip 是否有对应的主机, 该主机是否 up, 2) 那些端口是对外开放的, 是什么协议, 3) 对应的操作系统是什么.

路由器 repo 上竟然有 nmap 软件, 安装之后试了试, 基本的扫描主机还可以. 如果扫描端口什么的, CPU 就飙升了.

eric@home:/tmp/home/eric# nmap -PS21 223.166.19.225/29

Starting Nmap 5.35DC1 ( http://nmap.org ) at 2014-05-25 17:44 UTC
Nmap scan report for 223.166.19.225
Host is up (0.00070s latency).

Nmap scan report for 223.166.19.226
Host is up (0.0027s latency).
Not shown: 997 closed ports
PORT     STATE    SERVICE
23/tcp   filtered telnet
80/tcp   open     http
1900/tcp open     upnp

Nmap done: 8 IP addresses (2 hosts up) scanned in 2138.07 seconds

如上所示, 我扫描了一下我主机所在的 IP 段的一个非常小的部分. 共有8个 IP 地址, 有2个主机 up, 其中上面那个是我的路由器. 下面是另外一台在线的主机. 竟然开着80端口. 不过80端口返回403. 另外还开着1900, 是 upnp 协议.

NCR 访问 google.com 而不是 google.com.hk

为了搜个英文材料, google 总是自动跳转到 google.com.hk 即使点了右下角的 使用 google.com 仍旧跳转到 hk. 登录 google 帐号, 也不可以, 使用代理也不可以.

搜了一下, 如果访问 http://www.google.com/ncr 就能访问 google.com 的服务了.
据说这个 NCR 是 No Country Redirect 的意思.

goagent 代理访问 https 网站 出现的问题

遇到2种问题

  1. 证书不正确的问题

如下图, 报告证书不正确, 这种直接 继续 就好了

请输入图片描述
虽然能继续, 可是还有可能出现页面全乱掉的问题, 如下图. 原因是 CSS/JS 文件在 CDN 或者其它域名上, 所以找到 "其它" 域名, 在另外的窗口打开, 同上, 也点击 继续, 再回到原来页面刷新, 页面就恢复了.
请输入图片描述

  1. 证书不信任的问题 Error Type: HSTS failure

如下图, 浏览器认为不是真正的网站, 直接Block 了. 

请输入图片描述
点击详情, 如下图. 竟然说 facebook 要 chrome block 的, 那么也可以认为这是 chrome 对某些网站做的优化.(可是 chrome 并没有 block google 的 https 网站).
请输入图片描述
如何化解?
添加 goagent 的 CA 到系统信任的 CA 列表. 下图是我的 chrome 在 MAC 上面的操作. (chrome 是使用的系统根证书列表)
找到 chrome 设置, 然后是 https/SSL 管理证书
请输入图片描述
MAC 下自动打开 keychain, 导入证书到 system, 我这个截图有点问题, 实际是导入的 system 下面
请输入图片描述
导入的时候, 选择 always trust
请输入图片描述
导入之后, 重新打开这个证书, 点 Trust 下三角, 然后再次确认 always trust. 就可以了
请输入图片描述