分类目录归档:前端相关

Mac OS下签发多域名证书

前言

本文介绍如何在Mac OS下方便的利用钥匙串程序制作自签名根证书,以及用它签发支持多个域名与泛域名的HTTPS证书。

制作自签名根证书

/Applications/Utilities里打开“钥匙串访问”这个程序,在菜单中选“钥匙串访问” -> “证书助理” -> “创建证书”。过程如图:

名称可以按自己的喜爱去写。


有效期添长一些,比如3650


这里的信息可写可不写。



勾选“证书签名”与“CRL签名”用来颁发与吊销证书。



这里一定要选“将此证书用作证书颁发机构”。


点击继续直到完成。


创建完成后,双击自签名的证书,将证书设置为始终信任。如图:

导出自签名根证书

之后将自签名的根证书导出,命名为ca.p12,存到随意位置。这里一定要选证书和密钥同时导出来,导出的时候可以不设置密码,但之后要及时删除掉ca.p12,以防信息泄露。

创建多域名配置文件

接下来创建配置文件san.cnf,按照要申请的域名去编辑alt_names配置节,其它配置节不用动。例如要申请 *.example.com example.com localhost的多域名证书,按如下配置。编辑完后与之前导出的ca.p12存到一个目录下。

[ req ]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext
[ req_distinguished_name ]
countryName                 = Country Name (2 letter code)
stateOrProvinceName         = State or Province Name (full name)
localityName               = Locality Name (eg, city)
organizationName           = Organization Name (eg, company)
commonName                 = Common Name (e.g. server FQDN or YOUR name)
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1   = *.example.com
DNS.2   = example.com
DNS.3   = localhost

签发多域名证书

然后进到ca.p12san.cnf存放的目录执行下列命令:

openssl pkcs12 -clcerts -nokeys -out ca-cert.pem -in ca.p12  #导出公钥
openssl pkcs12 -nocerts -nodes -out ca-key.pem -in ca.p12 #导出私钥

执行上面两行命令的时候,会提示输入导出ca.p12文件时设下的密码,如果没有设置,直接回车就行。然后继续执行下面的命令签发证书。

openssl req -out user-cert.csr -newkey rsa:2048 -nodes -keyout private.key -config san.cnf #创建多域名证书请求
openssl x509 -req -in user-cert.csr -CAcreateserial -CA ca-cert.pem -CAkey ca-key.pem -out cert.pem -days 500 -sha256 -extfile san.cnf -extensions req_ext #签发证书

执行的过程中提示输入信息,Common Name写成你要申请的主要域名,如:example.comwww.example.com,也可以写成localhost,其余的不知道怎么写的话可以回车跳过。

最后得到的cert.pem为证书,private.key为证书私钥。其它文件都要删除掉。最后将证书和私钥配置到server中,以nginx的为例:

listen  80;
listen  443 ssl;
server_name  example.com;
ssl_certificate      pki/cert.pem;
ssl_certificate_key  pki/private.key;

配置完server后,记得重启服务。用浏览器访问,可以看到最后的效果:

HTTPS化的第一步 —— 申请Let’s Encrypt证书

背景介绍

目前中国的网络环境十分恶劣,运营商劫持的行为比比皆是,最好的对应方式就是把你的站点加密,即启用HTTPS协议。而且下一代HTTP协议(http 2.0)也是建立在HTTPS基础之上的。所以启用HTTPS是一举多得的行为。关于HTTPS协议本身网上有很多介绍,这里不详细说明了,不了解的可以去google一下。

要启用HTTPS,首先要有一个服务器证书,本文会详细介绍一下如何在Let’s Encrypt上申请到免费证书。

相信有很多朋友已经申请过StartSSL提供的免费证书,但最近有人发现StartSSL涉及到了中国的某公司,这意味着你的网站有可能被冒充。

root@kali:~/# host www.startssl.com
www.startssl.com has address 97.74.232.97     # Godaddy
www.startssl.com has address 52.7.55.170      # Amazon Web Services
www.startssl.com has address 52.21.57.183     # Amazon Web Services
www.startssl.com has address 52.0.114.134     # Amazon Web Services
www.startssl.com has address 50.62.56.98      # Godaddy
www.startssl.com has address 104.192.110.222  # QiHU 360 Inc.
www.startssl.com has address 50.62.133.237    # Godaddy

下面是摘自微博的评论:

@ruanyf 如果你正在使用StartSSL提供的免费证书,请小心了。它的私钥服务器现在放在360的机房,意味着理论上360可以冒充你的网站。网页链接

这个消息一放出之后,也有用户禁用了系统的StartSSL根证书,这部分用户在访问使用StartSSL证书的网站时会提示“站点不可信”。所以之前用StartSSL证书的用户换新证书也是十分有必要的。

Let’s Encrypt介绍

Let's Encrypt是国外一个公共的免费SSL项目,由 Linux 基金会托管,它的来头不小,由Mozilla、思科、Akamai、IdenTrust和EFF等组织发起,目的就是向网站自动签发和管理免费证书,以便加速互联网由HTTP过渡到HTTPS,目前Facebook等大公司开始加入赞助行列。

Let's Encrypt已经得了 IdenTrust 的交叉签名,这意味着其证书现在已经可以被Mozilla、Google、Microsoft和Apple等主流的浏览器所信任,你只需要在Web 服务器证书链中配置交叉签名,浏览器客户端会自动处理好其它的一切,Let's Encrypt安装简单,未来大规模采用可能性非常大。

Let's Encrypt虽然还在测试当中,但是市场需求非常大,已经有非常多的朋友迫不及待地安装并用上了Let's Encrypt。Let's Encrypt向广大的网站提供免费SSL证书,不管是对于网站站长、互联网用户,还是对整个Web互联网,都是非常有利的,它有利于整个互联网的安全。

如何申请Let’s Encrypt的证书

Let’s Encrypt提供了很便捷的工具去申请证书。申请者首先要去获取工具。可以在本地机器上执行,也可以在网站服务器上执行。

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --help

执行上面的命令会自动下载缺失的依赖,没有问题的话会打印出来使用帮助。

帮助里提示了有几种获得证书的方式:

Choice of server plugins for obtaining and installing cert:

  --apache          Use the Apache plugin for authentication & installation
  --standalone      Run a standalone webserver for authentication
  (nginx support is experimental, buggy, and not installed by default)
  --webroot         Place files in a server's webroot folder for authentication

这里要介绍一下这个申请工具的运作原理,执行它的时候会产生类似1k8HnVu7aKIMcTm4XYzjYlmgLtMntkuhLCo8c8B3pyo.x24B1t7ILOHGEKSRUY3Wsg9OCNL2E7NJOff_xfZaa-s的字符串,然后接着它会请求http://www.zhoumingzhi.com/.well-known/acme-challenge/1k8HnVu7aKIMcTm4XYzjYlmgLtMntkuhLCo8c8B3pyo这个地址,再看返回的数据是不是上面那一堆字符串,如果是的话就说明申请者对这个域名有所有权,接下来就会发放证书文件。上面提到的那几种方式就是方便用户验证域名所有权的。为了方便理解,我们用通用性最好的方式——手动操作。

./letsencrypt-auto certonly --manual -d www.zhoumingzhi.com --email mingzhi22@gmail.com

执行上面的命令后会有几处让你确认的窗口,按OK就好。然后会出现类似这样的提示:

Make sure your web server displays the following content at
http://www.zhoumingzhi.com/.well-known/acme-challenge/ArUM149fkLfqBTg5cHw37_WRVGKpARnb1_fgpgNGhrw before continuing:

ArUM149fkLfqBTg5cHw37_WRVGKpARnb1_fgpgNGhrw.x24B1t7ILOHGEKSRUY3Wsg9OCNL2E7NJOff_xfZaa-s

现在需要配置你域名所对应的服务器,确保http://www.zhoumingzhi.com/.well-known/acme-challenge/ArUM149fkLfqBTg5cHw37_WRVGKpARnb1_fgpgNGhrw能返回ArUM149fkLfqBTg5cHw37_WRVGKpARnb1_fgpgNGhrw.x24B1t7ILOHGEKSRUY3Wsg9OCNL2E7NJOff_xfZaa-s,如果都准备好了的话按任意键继续,稍等几秒钟,证书就生成好了。

接下来按https://letsencrypt.readthedocs.org/en/latest/using.html#where-are-my-certificates说的去配置你的服务器。

关于IE下iframe里无法读取cookie的问题

在IE下的问题:

  1. http://webmail.mail.yeah.net/js5/main.jsp 页面用iframe嵌入 http://news.163.com/special/163mail_2012/
  2. http://news.163.com/special/163mail_2012/ 中引用 http://api.pr.163.com/mail/user 在.163.com域下发放cookie
  3. http://news.163.com/special/163mail_2012/ 用JavaScript获取不到步骤2中发放的cookie

由于IE特殊的安全策略,在特定的情况下拒绝iframe引用的页面对cookie进行读写。
(参考:http://msdn.microsoft.com/en-us/library/ms537343%28v=vs.85%29.aspx#privacy_preference_settings)

解决方法:在上述例子中的http://api.pr.163.com/mail/user 添加 P3P: “CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR” 响应头。

结论:
如果再遇到无法访问iframe里发放cookie的问题,可以尝试在 cookie的发放地址添加P3P头调试解决。

Tips (2010.8.30-2010.9.3)

  1. 【CSS】做投影效果,标准浏览器用box-shadow,IE用filter: progid:DXImageTransform.Microsoft.Shadow(color=’#66666666′, Direction=135, Strength=2)
  2. 【CSS】做外发光效果,标准浏览器用box-shadow,IE用filter:progid:DXImageTransform.Microsoft.Glow(Color=#444444, Strength=3);
  3. 【PHP】”name1[]=1&name1[]=2″,到了后台会自动转成数组,$_POST[“name1”]的值为[1, 2]。
  4. 【ASP.NET】”name1=1&name1=2″,到了后台会自动转成用逗号分隔的字符串,Request.Form[“name1”]的值为1, 2。
  5. 【HTML】IE下有个unselectable的属性,设为on以后,点击就不会获得焦点了。
  6. 【HTML】IE下有hidefocus属性,设为true以后会隐藏虚线框,和outline: none一样。
  7. 【JS】随机输出1到10个数,不重复:
    var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    var i = 10;
    while(i) {
        var output = Math.round(Math.random() * (--i));
        console.debug(arr.splice(output, 1));
    }
  8. 【JS】随机处理数组里的项:
    Array.prototype.random = function(func) {
        var arr = this.concat();
    
        if(typeof func === 'function') {
            var len = arr.length;
    
            while(len) {
                func(arr.splice(Math.round(Math.random() * (--len)), 1)[0]);
            }
        }
    }
    

Tips (2010.8.4-2010.8.11)

  1. 【JS】创建元素的时候用innerHTML,删除元素的时候用removeChild,替换元素内容的时候用replaceChild。性能分析见http://www.6e6.org/post/49.html
  2. 【HTML】仅在Firefox中,table元素宽度属性百分比大于100%时,Firefox会按100%处理;如果是style中的CSS特性,则不会这么处理。建议给TABLE元素设置宽度的时候,不要使用width属性,而是使用CSS中的width特性。(Google)
  3. 【JS】设置option元素中的文本时需要注意:用doc.createElement(‘option’)创建的节点,IE是无法直接设置text来改变文本的。必须通过 option.appendChild(doc.createTextNode(txt));来实现。但是,一旦节点被插入到页面DOM后,就可以直接设置option.text了。(熊松松)
  4. 【JS】取得textarea里面文字的数量,标准浏览器下可以用textarea.textLength属性,而IE下用textarea.value.length属性。
  5. 【JS】escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z
    encodeURI不编码字符有82个:!,#,$,&,’,(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z
    encodeURIComponent不编码字符有71个:!, ‘,(,),*,-,.,_,~,0-9,a-z,A-Z