5 ruby ssl openssl ruby-on-rails hsm
我在阅读了 StackOverflow、密码学、信息安全和 CloudHSM 论坛上的所有 CloudHSM 主题后提出这个问题,但找不到任何有用的内容。任何想法或代码片段都有帮助。
\n\n我们有一个 Ruby 应用程序,它通过 X.509 证书向 Web 服务器请求,我们应该在 CloudHSM 内生成/托管私钥。
\n\n我逐步按照CloudHSM 文档进行操作,并通过 NGINX 和 Apache HTTPD 配置了 TLS 卸载,以了解其工作原理,现在我正在使用 CloudHSM 进行双向 TLS 工作。
\n\n我的网络服务器需要客户端证书,我可以通过 cURL 进行验证:
\n\ncurl --cert app-selfsigned.crt --key app-selfsigned.key -k https://127.0.0.1/index.html\nRun Code Online (Sandbox Code Playgroud)\n\n我还可以使用此 Ruby 代码通过磁盘上的认证进行身份验证:
\n\nrequire \'faraday\'\nrequire \'openssl\'\n\ndef ssl_options\n cert_file = File.read "app-selfsigned.crt"\n key_file = File.read "app-selfsigned.key"\n ssl_options = {\n verify: false,\n client_cert: OpenSSL::X509::Certificate.new(cert_file),\n client_key: OpenSSL::PKey::RSA.new(key_file)\n }\nend\n\ndef connection\n dest = "https://127.0.0.1/"\n connection = Faraday::Connection.new(dest, ssl: ssl_options)\n connection.get\nend\nRun Code Online (Sandbox Code Playgroud)\n\nirb -I . -r rubytest.rb\nconnection\nRun Code Online (Sandbox Code Playgroud)\n\ncURL 和 Ruby 通过磁盘上的认证进行测试:
\n\n\n\napp-selfsigned.key在 CloudHSM 内托管密钥,该怎么做?1) 我可以通过CloudHSM OpenSSL 动态引擎执行此操作吗?如果是,即使在安装了cloudhsm引擎(/opt/cloudhsm/lib/libcloudhsm_openssl.so)之后,我是否应该每次在我的代码中加载并安装引擎?
2) 或者我应该通过p11-kit or pkcs11-openssl包和p11tool命令使用 PKCS#11 还是 Ruby PKCS#11?
3) 我应该在 Ruby 应用程序中添加与我的 Ruby 应用程序相关的任何内容吗n3fips_password?
以下是我尝试使用 CloudHSM 的 Ruby 代码(我使用 FAKE PEM 密钥而不是真正的私钥来指向带有nginx-selfsigned_imported_keyCloudHSM 内标签的真实私钥):
require \'faraday\'\nrequire \'openssl\'\n\ndef initialize_openssl\n key_label = "nginx-selfsigned_imported_key"\n # OpenSSL Engine:\n OpenSSL::Engine.load\n e = OpenSSL::Engine.by_id(\'cloudhsm\')\n e.ctrl_cmd("SO_PATH", "/opt/cloudhsm/lib/libcloudhsm_openssl.so")\n e.ctrl_cmd("ID", "cloudhsm")\n e.ctrl_cmd("LOAD")\n e.load_private_key("CKA_LABEL=#{ key_label }")\nend\n\ndef ssl_options\n cert_file = File.read "app-selfsigned.crt"\n key_file = File.read "app-selfsigned_fake_PEM.key"\n {\n verify: false,\n client_cert: OpenSSL::X509::Certificate.new(cert_file),\n client_key: OpenSSL::PKey::RSA.new(key_file)\n }\nend\n\ndef connection\n dest = "https://127.0.0.1/"\n Faraday::Connection.new(dest, ssl: ssl_options)\nend\n\ndef connect\n initialize_openssl\n c = connection\n c.get\nend\nRun Code Online (Sandbox Code Playgroud)\n\nirb -I . -r rubytest_cloudhsm.rb\ninitialize_openssl\nRun Code Online (Sandbox Code Playgroud)\n\n但我收到此错误:
\n\nOpenSSL::Engine::EngineError: invalid cmd name\nfrom /root/self-signed/app-selfsigned/rubytest_cloudhsm.rb:9:in `ctrl_cmd\'\nfrom /root/self-signed/app-selfsigned/rubytest_cloudhsm.rb:9:in `initialize_openssl\'\nfrom (irb):1\nfrom /bin/irb:12:in `<main>\'\nRun Code Online (Sandbox Code Playgroud)\n\n逐行添加它们:
\n\n\n\nCloudHSM 的 Ruby 错误:
\n\n\n\nOpenSSL动态引擎已成功安装:
\n\nOpenSSL::Engine::EngineError: invalid cmd name\nfrom /root/self-signed/app-selfsigned/rubytest_cloudhsm.rb:9:in `ctrl_cmd\'\nfrom /root/self-signed/app-selfsigned/rubytest_cloudhsm.rb:9:in `initialize_openssl\'\nfrom (irb):1\nfrom /bin/irb:12:in `<main>\'\nRun Code Online (Sandbox Code Playgroud)\n\nOpenSSL CloudHSM 动态引擎共享对象位于正确的位置:
\n\nexport n3fips_password=<Crypto User Username>:<CU Password>\nopenssl engine -tt cloudhsm\n# (cloudhsm) CloudHSM hardware engine support\n# SDK Version: 2.03\n# [ available ]\nopenssl engine -vvvv dynamic -pre SO_PATH:/opt/cloudhsm/lib/libcloudhsm_openssl.so -pre ID:cloudhsm -pre LOAD\n# (dynamic) Dynamic engine loading support\n# [Success]: SO_PATH:/opt/cloudhsm/lib/libcloudhsm_openssl.so\n# [Success]: ID:cloudhsm\n# [Success]: LOAD\n# Loaded: (cloudhsm) CloudHSM hardware engine support\nopenssl speed -engine cloudhsm\n# SDK Version: 2.03\n# engine "cloudhsm" set.\n# Doing md2 for 3s on 16 size blocks:\n# 557992 md2\'s in 2.99s\nopenssl version\n# OpenSSL 1.0.2k-fips 26 Jan 2017\nrpm -qa | grep -i openssl\n# openssl-1.0.2k-16.amzn2.1.1.x86_64\n# openssl-libs-1.0.2k-16.amzn2.1.1.x86_64\nRun Code Online (Sandbox Code Playgroud)\n\nlibcloudhsm_openssl.so:
\n\n\n\n操作系统:
\n\ncat /etc/os-release\n# NAME="Amazon Linux"\n# VERSION="2"\n# ID="amzn"\n# ID_LIKE="centos rhel fedora"\n# VERSION_ID="2"\n# PRETTY_NAME="Amazon Linux 2"\n# ANSI_COLOR="0;33"\n# CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"\n# HOME_URL="https://amazonlinux.com/"\nuname -a\n# Linux hsm.example.net 4.14.133-113.112.amzn2.x86_64 #1 SMP Tue Jul 30 18:29:50 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux\nRun Code Online (Sandbox Code Playgroud)\n\nrpm -qa | grep -i cloudhsm-client\n# cloudhsm-client-2.0.3-3.el7.x86_64\n# cloudhsm-client-dyn-2.0.3-3.el6.x86_64\nRun Code Online (Sandbox Code Playgroud)\n\n我可以在有或没有 CloudHSM 引擎的情况下检查私钥和公钥:
\n\napp-selfsigned.crt: Public Key\napp-selfsigned.key: Private key has been exported from CloudHSM \napp-selfsigned_fake_PEM.key: Fake private key pointing to real private key inside CloudHSM generated by getCaviumPrivKey -k 14 -out app-selfsigned_fake_PEM.key\nRun Code Online (Sandbox Code Playgroud)\n\nls -ltrha /usr/lib64/openssl/engines/libcloudhsm.so\nlrwxrwxrwx 1 root root 40 Aug 7 09:56 /usr/lib64/openssl/engines/libcloudhsm.so -> /opt/cloudhsm/lib/libcloudhsm_openssl.so\nRun Code Online (Sandbox Code Playgroud)\n\napp-selfsigned.crtTLSapp-selfsigned_fake_PEM.key卸载:/etc/nginx/nginx.conf:
\n\nssl_engine cloudhsm;\nssl_certificate "/etc/pki/nginx/app-selfsigned.crt";\nssl_certificate_key "/etc/pki/nginx/private/app-selfsigned_fake_PEM.key";\nRun Code Online (Sandbox Code Playgroud)\n\nnginx -t\n# SDK Version: 2.03\n# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok\n# nginx: configuration file /etc/nginx/nginx.conf test is successful\nsystemctl start nginx && systemctl status nginx\n# Aug 13 11:21:33 hsm.example.net nginx[13046]: SDK Version: 2.03\nRun Code Online (Sandbox Code Playgroud)\n\n通过 OpenSSL 检查证书文件:
\n\nopenssl x509 -in app-selfsigned.crt -text -noout\n# Serial Number: c7:c4:07:a6:78:22:2e:ff\n# Subject: C=AA, ST=AA, L=AA, O=AA, OU=AA, CN=a.com/emailAddress=a@a.com\nRun Code Online (Sandbox Code Playgroud)\n\n通过 Firefox 检查证书:
\n\n\n\ncat /etc/os-release\n# NAME="Amazon Linux"\n# VERSION="2"\n# ID="amzn"\n# ID_LIKE="centos rhel fedora"\n# VERSION_ID="2"\n# PRETTY_NAME="Amazon Linux 2"\n# ANSI_COLOR="0;33"\n# CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"\n# HOME_URL="https://amazonlinux.com/"\nuname -a\n# Linux hsm.example.net 4.14.133-113.112.amzn2.x86_64 #1 SMP Tue Jul 30 18:29:50 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux\nRun Code Online (Sandbox Code Playgroud)\n\nrpm -qa | grep -i cloudhsm-client\n# cloudhsm-client-2.0.3-3.el7.x86_64\n# cloudhsm-client-dyn-2.0.3-3.el6.x86_64\nRun Code Online (Sandbox Code Playgroud)\n\n如果您使用其他语言的 CloudHSM 双向 TLS,请将您的代码粘贴到此处,以便我了解想法并在 Ruby 中实现它。
\n\n提前致谢。
\n小智 3
对于稍后看到此问题的任何人,以下是与 Amazon CloudHSM 配合使用的示例 Ruby 代码:
require 'openssl'
require 'base64'
FAKE_KEY = "/root/ruby/ruby_key_inside_hsm/ruby_hsm_fake_private.key"
REAL_KEY = "/root/ruby/ruby_key_inside_hsm/ruby_hsm_real_private_exported.key"
PUB_KEY = "/root/ruby/ruby_key_inside_hsm/pubkey.pem"
STR = "test string"
def encrypt(str)
pubkey = OpenSSL::PKey::RSA.new(File.read(PUB_KEY))
Base64.encode64(pubkey.public_encrypt(str))
end
def decrypt(str, key)
OpenSSL::Engine.load
privkey = OpenSSL::PKey::RSA.new(File.read(key))
privkey.private_decrypt(Base64.decode64(str))
end
def estr
encrypt(STR)
end
def real_dec
decrypt(estr, REAL_KEY)
end
def hsm_dec
OpenSSL::Engine.load
OpenSSL::Engine.by_id('cloudhsm')
decrypt(estr, FAKE_KEY)
end
Run Code Online (Sandbox Code Playgroud)
目前我们正在努力将其添加到生产环境中。