zoukankan      html  css  js  c++  java
  • 自己做CA

    https://wangbin.io/blog/it/https-ca.html

    最近chrome提示https证书错误,缺少subjectAltName,查了下解决方法,更新下。

    一. 简介

    之前我的博客支持https使用的是向StartCom CA申请签发的一年免费证书。StartCom是受信赖的CA机构,它的根证书被各种操作系统和浏览器内置信任,所以由它签发的证书也会被信任。

    最近做了个iOS ipa包上传下载程序,也需要使用https链接,上网查了下发现可以自己签名证书,所以实践了下,下面是详细步骤。

    特别推荐下面这个网站,讲的是...非常详细。

    https://jamielinux.com/docs/openssl-certificate-authority/index.html

    教程里有些功能了解就可以了,我们不需要使用,所以我去掉了其中一些步骤,简单好用些。

    二. CA

    自己当CA,就是用openssl命令生成自己的根证书,让用户安装信任它,那么所有用这个根证书签名的证书,就也可以被信任啦。

    所以做为CA,我们首先要生成自己的根证书ca.cert.pem,而生成根证书需要ca.key.pem。

    开始

    创建/root/ca文件夹,所有CA的操作都会在这个文件夹执行。

        # mkdir /root/ca
        # cd /root/ca
        # mkdir certs crl newcerts private
        # chmod 700 private
        # touch index.txt
        # echo 1000 > serial
        # touch openssl.cnf

    /root/ca:CA文件夹

    /root/ca/certs:新签署证书和根证书存放的位置

    /root/ca/crl:证书请求文件存放位置

    /root/ca/newcerts:新签署证书存放的位置,是/root/ca/certs的备份

    /root/ca/private:ca.key.pem存放位置,千万别丢失

    /root/ca/index.txt:证书签名的纪录

    /root/ca/serial:下一次证书签名的序列号,保存到index.txt

    拷贝下面内容到/root/ca/openssl.cnf

    # OpenSSL root CA configuration file.
    # Copy to `/root/ca/openssl.cnf`.
    
    [ ca ]
    # `man ca`
    default_ca = CA_default
    
    [ CA_default ]
    # Directory and file locations.
    dir               = /root/ca
    certs             = $dir/certs
    crl_dir           = $dir/crl
    new_certs_dir     = $dir/newcerts
    database          = $dir/index.txt
    serial            = $dir/serial
    RANDFILE          = $dir/private/.rand
    
    # The root key and root certificate.
    private_key       = $dir/private/ca.key.pem
    certificate       = $dir/certs/ca.cert.pem
    
    # For certificate revocation lists.
    crlnumber         = $dir/crlnumber
    crl               = $dir/crl/ca.crl.pem
    crl_extensions    = crl_ext
    default_crl_days  = 30
    
    # SHA-1 is deprecated, so use SHA-2 instead.
    default_md        = sha256
    
    name_opt          = ca_default
    cert_opt          = ca_default
    default_days      = 3750
    preserve          = no
    policy            = policy_strict
    
    [ policy_strict ]
    # The root CA should only sign intermediate certificates that match.
    # See the POLICY FORMAT section of `man ca`.
    countryName             = match
    stateOrProvinceName     = match
    organizationName        = match
    organizationalUnitName  = optional
    commonName              = supplied
    emailAddress            = optional
    
    [ policy_loose ]
    # Allow the intermediate CA to sign a more diverse range of certificates.
    # See the POLICY FORMAT section of the `ca` man page.
    countryName             = optional
    stateOrProvinceName     = optional
    localityName            = optional
    organizationName        = optional
    organizationalUnitName  = optional
    commonName              = supplied
    emailAddress            = optional
    
    [ req ]
    # Options for the `req` tool (`man req`).
    default_bits        = 2048
    distinguished_name  = req_distinguished_name
    string_mask         = utf8only
    
    # SHA-1 is deprecated, so use SHA-2 instead.
    default_md          = sha256
    
    # Extension to add when the -x509 option is used.
    x509_extensions     = v3_ca
    
    [ req_distinguished_name ]
    # See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
    countryName                     = Country Name (2 letter code)
    stateOrProvinceName             = State or Province Name
    localityName                    = Locality Name
    0.organizationName              = Organization Name
    organizationalUnitName          = Organizational Unit Name
    commonName                      = Common Name
    emailAddress                    = Email Address
    
    # Optionally, specify some defaults.
    countryName_default             = CN
    stateOrProvinceName_default     = JiangSu
    localityName_default            = NanJing
    0.organizationName_default      = wangbin
    organizationalUnitName_default  = wangbin
    emailAddress_default            = webmaster@wangbin.io
    
    [ v3_ca ]
    # Extensions for a typical CA (`man x509v3_config`).
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    
    [ v3_intermediate_ca ]
    # Extensions for a typical intermediate CA (`man x509v3_config`).
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true, pathlen:0
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    
    [ usr_cert ]
    # Extensions for client certificates (`man x509v3_config`).
    basicConstraints = CA:FALSE
    nsCertType = client, email
    nsComment = "OpenSSL Generated Client Certificate"
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer
    keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage = clientAuth, emailProtection
    
    [ server_cert ]
    # Extensions for server certificates (`man x509v3_config`).
    basicConstraints = CA:FALSE
    nsCertType = server
    nsComment = "OpenSSL Generated Server Certificate"
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer:always
    keyUsage = critical, digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    
    [alt_names]
    IP.1 = 127.0.0.1
    IP.2 = 192.168.1.1
    DNS.1 = wangbin.io
    DNS.2 = ioptimi.wangbin.io
    
    [ crl_ext ]
    # Extension for CRLs (`man x509v3_config`).
    authorityKeyIdentifier=keyid:always
    
    [ ocsp ]
    # Extension for OCSP signing certificates (`man ocsp`).
    basicConstraints = CA:FALSE
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer
    keyUsage = critical, digitalSignature
    extendedKeyUsage = critical, OCSPSigning

    具体的解释可以看上面的链接(真的是很推荐),这里我拣重要的说下

    dir = /root/ca:这里需要改为上面的CA文件夹

    policy = policy_strict:签CA证书使用strict策略

    countryName_default = CN

    0.organizationName_default = wangbin CA

    这两个是国家和组织名字,会显示到生成的证书上。简单的签个CA证书,我们只设置这两个值,其他都是空。

    [ v3_ca ]:签CA证书需要这个配置

    [ server_cert ]:接下来签服务端证书需要这个

    生成root key

    # cd /root/ca
    # openssl genrsa -aes256 -out private/ca.key.pem 4096
    
    输入两次密码wangbin123456,这个是很重要的密码,设置严格点。
    
    # chmod 400 private/ca.key.pem

    生成root certificate

    # cd /root/ca
    # openssl req -config openssl.cnf 
          -key private/ca.key.pem 
          -new -x509 -days 7500 -sha256 -extensions v3_ca 
          -out certs/ca.cert.pem
    
    根据提示输入key的密码:wangbin123456
    然后一值回车下去,使用默认值
    
    # chmod 444 certs/ca.cert.pem

    -days 7300:有效期20年

    到这一步ca.key.pem(root key)和ca.cert.pem(root certificate)都已经生成好了,路径如下

    /root/ca/private/ca.key.pem
    /root/ca/certs/ca.cert.pem

    至此生成根证书完成。

    ca.key.pem密码是wangbin123456,非常重要,需要好好保存。

    ca.cert.pem就是根证书,需要把它发给用户,让用户安装信任它,这样以后我们用这个证书签名的证书就都可以被信任了。

    三. 生成服务端证书

    CA角色要做的工作已经完成了,下面我们以用户这个角色,生成一个tomcat和nginx可以使用的服务端证书。

    这里假设我们网站的域名或ip地址是127.0.0.1,那么在ca同级目录下创建127.0.0.1文件夹,生成服务端证书操作都在这个目录下进行。

    # mkdir /root/127.0.0.1
    # cd /root/127.0.0.1
    
    # openssl genrsa -out server.key 2048
    # openssl req -new -key server.key -out server.csr
    
    会出现提示,尽量全部都填写,防止以后浏览器对证书验证变得严格,又要重新签名。关键数据重复填写就可以了。
    Country Name输入:CN
    State or Province Name输入:JiangSu
    Locality Name(eg, city)输入:NanJing
    Organization Name (eg, company)输入:wangbin.io
    Organizational Unit Name (eg, section)输入:wangbin.io
    Common Name输入域名或ip:127.0.0.1
    Email Address:xxx@qq.com
    
    extra信息
    A challenge password输入:server123456
    An optional company name []:wangbin.io

    openssl genrsa -out server.key 2048:这个命令后面2048代表加密位数,严格的使用4096,例如上面的根证书使用的就是这个,一般使用2048和1024就可以了,数值越大https链接等待时间越长。

    到这儿,我们服务端key(server.key)和证书请求(server.csr)就生成啦。

    接下来拷贝server.csr到ca/crl并改名为127.0.0.1.csr.pem

    cp server.csr ../ca/crl/127.0.0.1.csr.pem

    然后角色切换到CA角色,对这个请求进行处理。

    首先修改下/root/ca/openssl.cnf

    policy            = policy_strict
    改为
    policy            = policy_loose

    policy_strict只在生成根证书的时候使用,其他时候使用loose策略就可以啦。

    2017.08.31修改:将下面IP或者DNS更新为要签名的

    [alt_names]
    IP.1 = 127.0.0.1
    IP.2 = 192.168.1.1
    DNS.1 = wangbin.io
    DNS.2 = ioptimi.wangbin.io

    执行命令,生成证书

    # cd /root/ca
    # openssl ca -config openssl.cnf 
      -extensions server_cert -days 375 -notext -md sha256 
      -in crl/127.0.0.1.csr.pem 
      -out certs/127.0.0.1.cert.pem

    -days 375:有效期375天,默认值也是375天

    这时候,你会发现

    • /root/ca/certs下多了127.0.0.1.cert.pem(这个就是生成好的证书)
    • newcerts下面多了1000.pem(这个是证书备份,1000是从serial中取的)
    • /root/ca/index.txt多了行纪录

      /root/ca/index.txt
      V   171014020124Z       1000    unknown /C=CN/ST=Some-State/O=Internet Widgits Pty Ltd/CN=127.0.0.1
    • /root/ca/serial中的值+1变成了1001。

    将/root/ca/certs/127.0.0.1.cert.pem证书发给用户,CA角色的工作就完成啦。

    角色切换回用户,我们将CA发给我们的127.0.0.1.cert.pem拷贝到/root/127.0.0.1目录下,并改名为server.crt

    cp certs/127.0.0.1.cert.pem ../127.0.0.1/server.crt

    这时我们目录下有下面三个文件

    server.crt server.csr server.key

    server.crt就是我们要的证书,我们可以配置nginx支持https啦。

    nginx配置

    server {
        listen       443;
        server_name  127.0.0.1;
    
        ssl on;
        ssl_certificate      /root/127.0.0.1/server.crt;
        ssl_certificate_key  /root/127.0.0.1/server.key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
    
        location / {
            proxy_pass   http://127.0.0.1;
        }
    
        location ~ ^(.*)/.svn/ {
            deny all;
        }
    }

    要支持tomcat的话,我们还需要进行下面的操作。

    # cd /root/127.0.0.1
    # openssl pkcs12 -export 
        -in server.crt 
        -inkey server.key 
        -out server.p12
    
    输入两次密码:server123456
    
    # keytool -importkeystore -v 
        -srckeystore  server.p12 
        -srcstoretype pkcs12 
        -srcstorepass server123456 
        -destkeystore server.keystore 
        -deststoretype jks 
        -deststorepass server123456

    操作后的文件目录

    server.crt      server.csr      server.key  
    server.p12      server.keystore 

    tomcat配置

    <Connector SSLEnabled="true" clientAuth="false" 
    keystoreFile="/root/127.0.0.1/server.keystore" 
    keystorePass="server123456" 
    maxThreads="150" port="8443" protocol="org.apache.coyote.http11.Http11Protocol" scheme="https" secure="true" sslProtocol="TLS"/>

    结尾

    以后如果需要生成别的服务端证书,我们就只用从三. 生成服务端证书开始就可以啦,是不是很easy.

    最后

    安装信任下我的根证书吧

  • 相关阅读:
    Rails组件逐个数:Rails Form helpers
    watirwebdriver常用方法
    Rails组件逐个数:Rails Form helpers(续)
    rails常用命令速查手册
    Rails new, build, create, save方法区别
    Ruby如何使用require从外部加载自定义类或模块
    升级Firefox8后watirwebdriver出现错误“unable to obtain stable firefox connection in 60 seconds”
    POJ2723Get Luffy Out(2sat)
    POJ3683Priest John's Busiest Day(2sat)
    UVA11374Airport Express(dijkstra)
  • 原文地址:https://www.cnblogs.com/linus-tan/p/13571544.html
Copyright © 2011-2022 走看看