SSL双向认证

概念

  1. 首先要有一个CA根证书,然后用CA根证书来签发用户证书
  2. 用户进行证书申请:一般先生成一个私钥,然后用私钥生成证书请求(证书请求里应包含有公钥信息),再利用证书服务器的CA根证书来签发证书

文件

  • key:私有的密钥
  • pem:用于导出,导入证书时候的证书的格式,有证书开头,结尾的格式。
  • csr:证书签名请求(证书请求文件),含有公钥信息,certificate signing request的缩写
  • crt:证书文件,certificte的缩写
  • crl:证书吊销列表,Certificate Revocation List的缩写

证书

根证书

根证书生成步骤:

生成私钥(key)–> 生成证书请求(csr) --> 用CA根证书签名得到证书(crt)

# 生成ca私有密钥
openssl genrsa -out ca.key 2048
# 生成csr文件
openssl req -new -key ca.key -out ca.csr
# 生成ca根证书
openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt

服务端

服务端证书生成步骤:

生成私钥(key) --> 生成证书请求(csr) --> 用CA根证书签名来得到证书(crt)

# 生成私钥
openssl genrsa -des3 -out server.key 1024
# 生成csr文件
openssl req -new -key server.key -out server.csr
# 生成crt
openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key

# 去除server.key密码的口令
openssl rsa -in server.key -out server.key

# 生成pem文件
cat server.crt server.key > server.pem

客户端

# 生成私钥
openssl genrsa -des3 -out client.key 1024
# 生成csr文件
openssl req -new -key client.key -out client.csr
# 生成crt文件
openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key

# 去除client,key的密码口令
openssl rsa -in client.key -out client.key

# 生成pem文件
cat client.crt client.key > client.pem

Notice Tip

  1. 问题描述:
    The mandatory stateOrProvinceName field was missing
    解决方法:

    # 在生成csr的时候,需要把信息填写完,不能填空,不然后面生成的crt文件会为空,导致pem出错
    # 修改后的配置文件如下:
    [ policy_match ]
    countryName = optional
    stateOrProvinceName = optional
    organizationName = optional
    organizationalUnitName = optional
    commonName = supplied
    emailAddress = optional
    
  2. 问题描述:
    Using configuration from /etc/pki/tls/openssl.cnf
    /etc/pki/CA/index.txt: No such file or directory
    unable to open ‘/etc/pki/CA/index.txt’

    解决方法:

    touch /etc/pki/CA/index.txt
    touch /etc/pki/CA/serial
    
    echo "01" > /etc/pki/CA/serial
    

实现

服务端

function generateSslSocket() {
    # 创建socket流
    $context = stream_context_create();
    
    stream_context_set_option($context, 'ssl', 'local_cert', 'server.pem'); # 服务端证书
    stream_context_set_option($context, 'ssl', 'cafile', 'ca.crt');         # ca根证书
    stream_context_set_option($context, 'ssl', 'allow_self_signed', true);  # 是否允许自签名证书,需要配合peer使用
    stream_context_set_option($context, 'ssl', 'verify_peer', true);        # 是否需要验证 SSL证书
    stream_context_set_option($context, 'ssl', 'verify_peer_name', true);   # 是否需要验证 peer name
    
    # socket监听端口
    $socket = stream_socket_server('ssl://127.0.0.1:8801', $errNo, $errStr,
        STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,$context);
    if ($socket === False) {
        exit();
    }
    
    return $socket;
}

客户端

function sendDataToSslSocket() {
     $errStr = "";
    $retRes = "";

    $context = stream_context_create();

    stream_context_set_option($context, 'ssl', 'local_cert', 'client.pem');
    stream_context_set_option($context, 'ssl', 'cafile', 'ca.crt');
    
    # 这里客户端没有验证自签名,因为在创建证书的时候,我这边主动把签名删除了
    stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
    stream_context_set_option($context, 'ssl', 'verify_peer', false);
    stream_context_set_option($context, 'ssl', 'verify_peer_name', false);

    $fp = stream_socket_client('ssl://127.0.0.1:8801', $errno, $errStr, 20, STREAM_CLIENT_CONNECT, $context);
        
    # 发送数据
    fwrite($this->fp, json_encode($data));
    $retRes = fread($this->fp, 2048);
    
    # 关闭连接
    fclose($this->fp);
    return $retRes;
}

总结

我最终的目标是完成一个SSL认证的代理,该代理可以**[接收请求]、[处理请求]、[多进程自动处理]、[任务进程监控]**。
准备使用的技术包括 SSL、Libevent、ftok、thread、pipe、semphore,目前只是完成了第一步,生成SSL证书,客户端和服务端socket连接。

ps:
该文章已经同步到简书:https://www.jianshu.com/p/bb739a2a0511

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yooKnight

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值