如何在根证书颁发机构下生成服务器和客户端证书

7
所以,我一直在尝试在一个拥有独立证书的Python客户端和Python服务器之间建立SSL连接,而且这两个证书都由同一个CA签名(这个CA也是根CA)。这应该使它们彼此有效,对吗?
我的方法到目前为止是创建一个bash脚本来完成所有操作:
1. 生成根CA的私钥 2. 使用根CA私钥生成根CA证书 3. 生成服务器的私钥 4. 生成服务器的CSR 5. 使用服务器CSR和根CA证书生成服务器证书 6. 生成客户端的私钥 7. 生成客户端的CSR 8. 使用客户端CSR和根CA证书生成客户端证书
#!/bin/bash

BOLD=$(tput bold)
CLEAR=$(tput sgr0)

echo -e "${BOLD}Generating RSA AES-256 Private Key for Root Certificate Authority${CLEAR}"
openssl genrsa -aes256 -out Root.CA.example.llc.key 4096

echo -e "${BOLD}Generating Certificate for Root Certificate Authority${CLEAR}"
openssl req -x509 -new -nodes -key Root.CA.example.llc.key -sha256 -days 1825 -out Root.CA.example.llc.pem

echo -e "${BOLD}Generating RSA Private Key for Server Certificate${CLEAR}"
openssl genrsa -out server/example.llc.server.key 4096

echo -e "${BOLD}Generating Certificate Signing Request for Server Certificate${CLEAR}"
openssl req -new -key server/example.llc.server.key -out server/example.llc.server.csr

echo -e "${BOLD}Generating Certificate for Server Certificate${CLEAR}"
openssl x509 -req -in server/example.llc.server.csr -CA Root.CA.example.llc.pem -CAkey Root.CA.example.llc.key -CAcreateserial -out server/example.llc.server.crt -days 1825 -sha256 -extfile server/example.llc.server.ext

echo -e "${BOLD}Generating RSA Private Key for Client Certificate${CLEAR}"
openssl genrsa -out client/example.llc.client.key 4096

echo -e "${BOLD}Generating Certificate Signing Request for Client Certificate${CLEAR}"
openssl req -new -key client/example.llc.client.key -out client/example.llc.client.csr

echo -e "${BOLD}Generating Certificate for Client Certificate${CLEAR}"
openssl x509 -req -days 1825 -in client/example.llc.client.csr -CA Root.CA.example.llc.pem -CAkey Root.CA.example.llc.key -set_serial 01 -out client/example.llc.client.crt

echo "Done!"

服务器加载这些凭据:
cntx = SSL.Context(...)
# ...
cntx.use_privatekey_file('example.llc.server.key')
cntx.use_certificate_file('example.llc.server.cert')
cntx.load_verify_locations('../Root.CA.example.llc.pem')

客户端加载这些凭据:
cntx = SSL.Context(...)
# ...
cntx.use_privatekey_file('example.llc.client.key')
cntx.use_certificate_file('example.llc.client.cert')
cntx.load_verify_locations('../Root.CA.example.llc.pem')

服务器启动如火箭

server = SSL.Connection(cntx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
server.bind(('localhost', 44000))
server.listen(1)
server.setblocking(1)
cli, addr = server.accept()

客户端尝试连接

SSL.Connection(cntx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sock.connect(('localhost', 44000))

然后我遭遇了这个疯狂的问题:
OpenSSL.SSL.Error: [('SSL routines', 'ssl3_read_bytes', 'tlsv1 alert unknown ca')]

目前,我不确定客户端和服务器证书是否应该由根CA签署,客户端证书是否应该由服务器证书签署,或者我是否在所有这些证书信任链SSL/TLS魔术巫师的疯狂中变得疯狂了。请帮忙。


1
我看不出你的代码有什么问题。但是回答你最后一个问题 - 客户端和服务器证书都应该由 CA 签名,这似乎是你正在做的。先用服务器证书测试 SSL,然后再用客户端证书,这样你就知道哪个证书引起了问题。 - Steve E.
哇!好的调用!原来我的客户端证书生成代码有问题。它是自签名证书,而不是使用CSR和根CA进行签名。我得到了一个错误18在0深度查找:自签名证书。我会编辑并重新测试。 - acpluspluscoder
1个回答

19

就这样了!

Steve E.指出需要验证证书,因此罪魁祸首被发现是自签名客户端证书。

openssl verify -verbose -CAfile Root.CA.example.llc.pem server/example.llc.server.crt
openssl verify -verbose -CAfile Root.CA.example.llc.pem client/example.llc.client.crt

这是新的自动生成代码:

#!/bin/bash

BOLD=$(tput bold)
CLEAR=$(tput sgr0)

iterate=(server/ client/)
for dir in "${iterate[@]}"; do
  [[ ! -d "$dir" ]] && mkdir -p "$dir" \
  && echo -e "${BOLD}directory '$dir' was created ${CLEAR}"
done

echo -e "${BOLD}Generating RSA AES-256 Private Key for Root Certificate Authority${CLEAR}"
openssl genrsa -aes256 -out Root.CA.example.llc.key 4096

echo -e "${BOLD}Generating Certificate for Root Certificate Authority${CLEAR}"
openssl req -x509 -new -nodes -key Root.CA.example.llc.key -sha256 -days 1825 -out Root.CA.example.llc.pem

echo -e "${BOLD}Generating RSA Private Key for Server Certificate${CLEAR}"
openssl genrsa -out server/example.llc.server.key 4096

echo -e "${BOLD}Generating Certificate Signing Request for Server Certificate${CLEAR}"
openssl req -new -key server/example.llc.server.key -out server/example.llc.server.csr

echo -e "${BOLD}Generating Certificate for Server Certificate${CLEAR}"
openssl x509 -req -in server/example.llc.server.csr -CA Root.CA.example.llc.pem -CAkey Root.CA.example.llc.key -CAcreateserial -out server/example.llc.server.crt -days 1825 -sha256 -extfile server/example.llc.server.ext

echo -e "${BOLD}Generating RSA Private Key for Client Certificate${CLEAR}"
openssl genrsa -out client/example.llc.client.key 4096

echo -e "${BOLD}Generating Certificate Signing Request for Client Certificate${CLEAR}"
openssl req -new -key client/example.llc.client.key -out client/example.llc.client.csr

echo -e "${BOLD}Generating Certificate for Client Certificate${CLEAR}"
openssl x509 -req -in client/example.llc.client.csr -CA Root.CA.example.llc.pem -CAkey Root.CA.example.llc.key -CAcreateserial -out client/example.llc.client.crt -days 1825 -sha256

echo "Done!"

祝愿任何试图为客户端/服务器系统创建双向身份验证的自签名根CA的人好运和快速成功!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接