HTTPS - 自认证根证书CA生成/签发/发布


即使是非对称加密系统,也不能保证公钥的分发是可靠的. 为了防范公钥分发过程中的中间人攻击,需要一个可信的"始祖"公证人,这就是CA机构存在的意义.

由CA签发证书认证网站的过程

  1. CA机构生成密钥对: 公钥 ca.cer 和 私钥 ca.key
  2. 浏览器/操作系统携带证书ca.cer
  3. 网站生成私钥 cert.key
  4. 网站将公钥及网站信息(域名/组织等),提交给CA机构
  5. CA机构使用私钥ca.key签发网站证书cert.cer
  6. 网站运营商通过cert.key和 cert.cer运行https
  7. 用户访问网站,获得cert.cer,由于该证书使用CA机构的私钥签发,因此可以通过保存在本地的公钥ca.cer验证
  8. 验证通过并得到了公钥-> 显示绿色https标志; 否则,提示用户风险信息
  9. 用户通过公钥与网站服务器交换对称加密密钥,进行正式的SSL会话

通过上述步骤可以看出,只要能保证网站公钥的可靠性即可,所以如果客户端直接存放了网站的证书,那么也是可以保证https正常进行的.
但是无论是何种证书,都需要可靠的分发到客户端才能保证安全.在开发过程中我们可能有各种各样的服务端,相较于为每一个服务端向客户端分发证书,还不如直接分发根证书,这样只需一次分发,客户端就可以完成后续的签发过程.

自认证CA根证书生成及签发

证书生成过程可以通过openssl完成.为了简化操作,我写了一个shell脚本,只需两步即可生成根证书及使用根证书签发网站证书
保存以下代码为gen_crt.sh,然后按照帮助内容使用即可.

  1. 生成根证书
    ./gen_crt.sh root aes128 2048 365 "/CN=MyCA"

    此时目录下有ca.key及ca.cer两个文件,ca.cer需要发布到客户端
    为了保证私钥的安全,生成过程中需要一个对ca.key加密的密码

  2. 签发网站证书
    ./gen_crt.sh sign aes128 2048 365 "/CN=www.mysite.com" ca.key ca.cer

为了保证私钥的安全,生成过程中需要一个对cert.key加密的密码.

    #!/bin/sh

    help()
    {
        echo "Example: ./gen_crt.sh root aes128 2048 365 \"/CN=CustomCA\""
        echo "Example: ./gen_crt.sh sign aes128 2048 365 \"/CN=www.mysite.com\" ca.key ca.cer"
        echo "key_length: 1024|2048|4096"
        methods="aes128|aes192|aes256|camellia128|camellia192|camellia256|des|des3|idea"
        echo "Supported encryption methods:" $methods
        exit 1
    }

    operation=$1
    method=$2
    key_length=$3
    expire_days=$4
    subj=$5
    ca_key=$6
    ca_cer=$7

    RED="\033[0;31m"
    GREEN="\033[0;32m"
    NC="\033[0m"


    if [ "$operation" = "root" ];then
        if [ $# -ne 5 ];then
            echo "${RED}Invalid argument num:$#${NC}"
            help
        fi
    elif [ "$operation" = "sign" ];then
        if [ $# -ne 7 ];then
            echo "${RED}Invalid argument num:$#${NC}"
            help
        fi
    else
        echo "${RED}Invalid operation $operation${NC}"
        help
    fi

    echo "Operation" $operation

    case $method in
        aes128|aes192|aes256|camellia128|camellia192|camellia256|des|des3|idea)
            echo "Using cryption method:" $method
            ;;
        *)
            echo "Wrong parameters"
            help
            ;;
    esac

    case $key_length in
        1024|2048|4096)
            echo "RSA Key length:" $key_length
            ;;
        *)
            echo "Wrong RSA key length"
            help
            ;;
    esac

    if [$expire_days -lt 0]; then
        echo "Invalid expire days:" $expire_days
        help
    fi

    if [ "$operation" = "root" ];then
        echo "Creating Root CA..."
        openssl genrsa -$method -out ca.key $key_length
        openssl req -x509 -new -key ca.key -out ca.cer -days 750 -subj $subj
        echo "${GREEN}Please distribute ca.cer anywhere needed"
        echo "${RED}Please keep ca.key in a private place${NC}"
    elif [ "$operation" = "sign" ];then
        openssl genrsa -$method -out cert.key $key_length
        openssl req -new -out cert.req -key cert.key -subj $subj
        openssl x509 -req -in cert.req -out cert.cer -CAkey $ca_key -CA $ca_cer -days $expire_days -CAcreateserial
        -CAserial serial
        echo "${GREEN}Please distribute cert.cer freely"
        echo "${RED}Please keep cert.key privately${NC}"
    else
        echo "Unknown operation: $operation"
        help
    fi

在nginx中使用证书

修改nginx配置文件 /etc/nginx/sites-available/xxxx
加入形如以下配置:

listen 443 ssl default_server;
listen [::]:443 ssl default_server;

ssl_certificate /home/ethan/workspace/homesite/tools/cert.cer;
ssl_certificate_key /home/ethan/workspace/homesite/tools/cert.key;

分发CA根证书

分发安全

可以通过可靠的服务(如通过安全验证的邮箱服务提供商、存储下载提供商)将根证书发放给客户端。直接通过http链接发放给客户端(如12306)的方式是不安全的,仅限于实验环境使用

Linux分发(SSH/Python的HTTPS访问等)

浏览器中分发

Chrome:设置->高级设置->HTTPS/SSL "管理证书"
Firefox: Preferences->Advanced->View Certificates->Certificate Manager

iOS分发

待进一步研究

Android分发

待进一步研究

你可能感兴趣的:(HTTPS - 自认证根证书CA生成/签发/发布)