主页 > 游戏开发  > 

openssl3.2-官方demo学习-test-certs


文章目录 openssl3.2 - 官方demo学习 - test - certs概述笔记.sh的执行语句打印的方法要修改的实际函数备注备注补充 - cygwin64环境下编译不过 openssl3.2补充 - vm16共享文件夹没有的问题.补充END

openssl3.2 - 官方demo学习 - test - certs 概述

官方demos目录有证书操作的例子 已经做了笔记 openssl3.2 - 官方demo学习 - certs 但是这个demos/certs目录的脚本, 并没有演示如何操作PKCS12证书.

在官方给的程序例子中, 有操作PKCS12证书的工程, 但是却没有配套的PKCS12证书. 这咋弄? 翻了一下openssl源码工程, 发现测试目录中有2个脚本, 非常精彩, 比官方demos目录给出的脚本能操作的证书详细多了. 里面也有PKCS12证书的例子. 将test/certs目录中除了2个.sh都删掉, 在cygwin64下执行setup.sh, 可以将证书全部生成出来. 不过有报错, 原因是cygwin64中带的openssl是3.0.12, 不是最新版的3.2. cygwin64升到最新的openssl也不是最新版的3.20. 这个目录是openssl自己测试用的, 证书的操作应该是最全的.

但是, 这2个.sh是bash脚本, 运行起来, 看不到执行了啥命令行(最终执行的都是openssl命令行). 想改一下.sh, 将最终执行的openssl命令行打印出来, 让人眼能看到. 然后我就可以在用windows下的openssl带相同命令行做相同的事情了.

笔记 .sh的执行语句打印的方法

在原有的这2个.sh上, 加了一个简单的测试函数, 测试了好使, 修改的思路就这么定了.

# this funciton test_exec() on mkcert.sh test_exec() { # 变量 - 赋值 TEST_CMD="ls -l" # 变量 - 打印 echo "TEST_CMD = $TEST_CMD" # 变量 - 执行 $TEST_CMD } # this call on setup.sh ./mkcert.sh test_exec

在cygwnwin64环境下, 执行如下语句, 可以执行到test_exec() 在程序执行的同时, 将执行的命令行也打印出来了. 这就是我想要的效果.

chenx@ls-Precision3561 /cygdrive/d/my_dev/my_local_git_prj/study/sh $ ./setup.sh TEST_CMD = ls -l total 20 -rwxrwx---+ 1 Administrators chenx 12465 Jan 17 18:24 mkcert.sh -rwxrwx---+ 1 Administrators chenx 138 Jan 17 18:25 setup.sh 要修改的实际函数

官方原始的脚本, 是执行 ./setup.sh, 间接的调用mkcert.sh(作为脚本库)来干活. setup.sh中, 都是调用mkcert.sh中的脚本函数, 看不到任何openssl相关的东西

./mkcert.sh genroot "Root CA" root-key root-cert

在mkcert.sh中, 先经过中间函数处理传入的参数, 最终会进入到有openssl最终调用的函数中. 包含openssl最终调用的函数有4个(cert(), req_nocn(), req(), key()), 如下.

key() { local key=$1; shift local alg=rsa if [ -n "$OPENSSL_KEYALG" ]; then alg=$OPENSSL_KEYALG fi local bits=2048 if [ -n "$OPENSSL_KEYBITS" ]; then bits=$OPENSSL_KEYBITS fi if [ ! -f "${key}.pem" ]; then args=(-algorithm "$alg") case $alg in rsa) args=("${args[@]}" -pkeyopt rsa_keygen_bits:$bits );; ec) args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits") args=("${args[@]}" -pkeyopt ec_param_enc:named_curve);; dsa) args=(-paramfile "$bits");; ed25519) ;; ed448) ;; *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;; esac stderr_onerror \ openssl genpkey "${args[@]}" -out "${key}.pem" fi } # Usage: $0 req keyname dn1 dn2 ... req() { local key=$1; shift key "$key" local errs stderr_onerror \ openssl req -new -"${OPENSSL_SIGALG}" -key "${key}.pem" \ -config <(printf "string_mask=%s\n[req]\n%s\n%s\n[dn]\n" \ "$REQMASK" "prompt = no" "distinguished_name = dn" for dn in "$@"; do echo "$dn"; done) } req_nocn() { local key=$1; shift key "$key" stderr_onerror \ openssl req -new -"${OPENSSL_SIGALG}" -subj / -key "${key}.pem" \ -config <(printf "[req]\n%s\n[dn]\nCN_default =\n" \ "distinguished_name = dn") } cert() { local cert=$1; shift local exts=$1; shift stderr_onerror \ openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \ -extfile <(printf "%s\n" "$exts") "$@" }

对sh编程不熟, 但是能看懂. 小动一下是可以的. 这4个函数最终调用openssl时, 参数给的比较复杂, 如果直接用echo来打印最终的命令行, 试过了, 不好使. 原因是, 这个命令行中有一些即时生成的参数, 如果用echo直接打印, 看不到真正的变量值.

准备将传给openssl的参数再复制给一些中间变量, 最后再将拼好的中间变量再传给openssl, 这样就能打印出命令行了.

准备改这4个函数, 将最终要执行的openssl命令行打印出来, 且能正常执行openssl命令.

备注

在windows下整理了证书操作的参数, 整理成windows命令行, 执行报错. 开始怀疑是这些证书命令是给旧版openssl用的. 为了验证这个问题, 装了一个debian12.4, 然后装了openssl3.2(自己从源码编译的). 执行.\test\certs\中的脚本(将setup.sh拷贝成副本, 改名, 在里面只有一条脚本), 执行时, 只是有警告, 但是执行结果是对的.

lostspeed@debian12d4x64:~/openssl/openssl-3.2.0/test/certs$ ./test2.h Warning: Reading cert request from stdin since no -in option is given // ! Certificate request self-signature ok subject=CN=Root CA

在openssl源码中, 也找到了这句警告.

int x509_main(int argc, char **argv) { // ... if (reqfile) { if (infile == NULL) BIO_printf(bio_err, "Warning: Reading cert request from stdin since no -in option is given\n"); req = load_csr_autofmt(infile, informat, vfyopts, "certificate request input"); if (req == NULL) goto end; // ... }

再研究一下, 看看p12证书怎么用openssl命令行操作. 要是官方例子中给了p12证书的操作例子, 就不用看源码编译, 测试中间操作用的脚本了.

备注

在debian12.4下搭建了环境, 运行setup.sh还是有警告. 这说明这脚本不大对劲, 有可能不是给openssl3.2用的. 也有可能是脚本写的不对(这2个脚本并不在make test中). 改了2个.sh, 验证了脚本函数genroot的入参和拼串过程, 改动如下:

#! /bin/bash # setup.sh # Primary root: root-cert ./mkcert.sh genroot "Root CA" root-key root-cert exit 0 # mkcert.sh genroot() { # $@ is param in 's ary printf "1. param in all = %s\n" "$@" local cn=$1; shift printf "2. param in all = %s\n" "$@" local key=$1; shift printf "3. param in all = %s\n" "$@" local cert=$1; shift printf "4. param in all = %s\n" "$@" local bcon="basicConstraints = critical,CA:true" local ku="keyUsage = keyCertSign,cRLSign" local skid="subjectKeyIdentifier = hash" local akid="authorityKeyIdentifier = keyid" printf "cn = %s\n" "$cn" printf "key = %s\n" "$key" printf "cert = %s\n" "$cert" printf "bcon = %s\n" "$bcon" printf "ku = %s\n" "$ku" printf "skid = %s\n" "$skid" printf "akid = %s\n" "$akid" exts=$(printf "%s\n%s\n%s\n" "$bcon" "$ku" "$skid" "$akid") printf "exts = %s\n" "$exts" printf "5. param in all = %s\n" "$@" for eku in "$@" do printf "eku = %s\n" "$eku" exts=$(printf "%s\nextendedKeyUsage = %s\n" "$exts" "$eku") done printf "1==========\n" csr=$(req "$key" "CN = $cn") || return 1 printf "csr = $csr\n" printf "2==========\n" echo "$csr" | cert "$cert" "$exts" -signkey "${key}.pem" -set_serial 1 -days "${DAYS}" }

运行setup.sh, 有警告.

1. param in all = Root CA 1. param in all = root-key 1. param in all = root-cert 2. param in all = root-key 2. param in all = root-cert 3. param in all = root-cert 4. param in all = cn = Root CA key = root-key cert = root-cert bcon = basicConstraints = critical,CA:true ku = keyUsage = keyCertSign,cRLSign skid = subjectKeyIdentifier = hash akid = authorityKeyIdentifier = keyid exts = basicConstraints = critical,CA:true keyUsage = keyCertSign,cRLSign subjectKeyIdentifier = hash authorityKeyIdentifier = keyid 5. param in all = 1========== csr = -----BEGIN CERTIFICATE REQUEST----- MIICVzCCAT8CAQAwEjEQMA4GA1UEAwwHUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAM7uRC+niKMwb1f1rlve6VCMckVJ8kINwYlOmI8xOnHk gSDfrc+SDE+rE6Fcui6qfvZ+Xq7ruIYOAS4BP/B5iR7kjjXrp+UUXFEjPB3BbQu5 ufIGFzEfWpBddU5Od9z73XoVPC6A0zWMTKISzbstsHnEVO6910hHgd73STP8Posa mpoZs7wt1NcIoODxs1WqGDADoKlLj9ZWo823vYca/748tOHitikdD8Wsm/A1oOFC MIXqmLIoRa/2rFdRfGGLUzTNqV+aTglCLy7vqUL3xOGaLC+Tok7o6zJtIyu3QYuW PCzATO5L3574JpVFyZVN3GL4LnmZ5zjRHHyp+03150cCAwEAAaAAMA0GCSqGSIb3 DQEBCwUAA4IBAQC5QtMtYkqP1ffYWYIN3Bk/A9H5fremxjmf4yuNguAwDXaX4dwO 8lqOVqRcYFVZWeLNRak1pgmP5lMgWVhj/3Wr49oLwyAGsvkghg+yIKXWBNVEJPR/ sDGa2RZwvIlMEdxM2O7SGcSGAkgCAmu4SPPid3b2ODhlLgkVM16aTqmwu3ATK3dH Yz5vd6SlKtXS0i77258dMGu4aLwp73PronT//jVVO4kD6cLFnno6JwcnuNge4XHC 41XO3mF5B9HayMP6qwM3MkXdJGzxgmPqNei5bjeXUFaUhXpAjF0jGZxRs4q2g42X 0hBdDiiik005jbx3ropq+VoRZVEXGS+9W+Mf -----END CERTIFICATE REQUEST----- 2========== Warning: Reading cert request from stdin since no -in option is given Certificate request self-signature ok subject=CN=Root CA

既然不是openssl3.2版本的问题, 那么就不需要在debian12.4下做实验了. 去cygwin64下还方便一些.

test/certs下的这2个脚本, 调用openssl时, 用stdin来传递文件, 这不标准啊. 准备将这2个.sh改一下, 用文件名来传递参数. 就在cygwin64下改.

刚才查了一下, openssl3.2源码目录下, 还有一些.sh, 不过都和证书无关. 就test/certs目录下的这2个.sh有用(里面要生成400~500个证书, 啥证书操作都有了, 而且每个证书操作都有注释, 感觉是个宝藏). 如果不研究一下, 真的可惜. 但是这2个.sh, 估计不是官方特意提供给用户看的, 所以才写的那么不严谨. 看看自己研究一下, 是否能改一个传文件名的版本. 官方给的demos/certs底下的脚本, 全部是用文件名来给openssl.exe做参数的, 一个警告都没有.

用stdin的流来传文件, 使用起来有限制. 至少命令行不好调用. 如果生成了啥内容(e.g. req), 生成的文件落地, 然后将落地的文件名传给openssl再继续干下一个活, 这多好. 和官方给的demos/certs目录的是记录一样, 适用性也广.

补充 - cygwin64环境下编译不过 openssl3.2

官方并没有对cygwin64下编译openssl3.2做说明. 就当linux环境下编译. make时出现上述报错. 网上有同学在cygwin64下编译旧版openssl成功过. 用他们的./Configure配置也不行, 都是在make时, 这行报错. 算了. 想在cygwin64下编译, 就是想省点事, 现在编译不过就认怂了. 还是在debian12.4下继续做实验, 争取将不同openssl命令行下用stdin传文件的做法, 改为让上一步的openssl操作的文件落地, 然后拿落地的文件名给第2步的openssl作为命令行参数, 这样就和官方给的demos/certs中的例子一样了. 如果能做到这步, test/certs中的这2个.sh就能学习了. 看起来也不难, 差那么一丢丢.

补充 - vm16共享文件夹没有的问题.

设置了共享文件夹后, 有/mnt/hgfs目录, 但是里面是空的.

sudo umount /mnt/hgfs lostspeed@debian12d4x64:~$ id uid=1000(lostspeed) gid=1000(lostspeed) 组=1000(lostspeed),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),100(users),106(netdev),111(bluetooth),113(lpadmin),116(scanner) sudo /usr/bin/vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other -o uid=1000 -o gid=1000 -o umask=022 sudo /usr/bin/vmhgfs-fuse .host:/ /mnt/hgfs -o nonempty -o allow_other -o uid=1000 -o gid=1000 -o umask=022

此时, 就可以用普通用户身份进入共享文件夹干活了.

补充

vmware的共享文件夹, 只能用来交互. 如果在共享文件夹内make, 是报错的.

lostspeed@debian12d4x64:/mnt/hgfs/crypt/openssl-3.2.0_debian$ sudo make [sudo] lostspeed 的密码: make depend && make _build_sw make[1]: Entering directory '/mnt/hgfs/crypt/openssl-3.2.0_debian' make[1]: Leaving directory '/mnt/hgfs/crypt/openssl-3.2.0_debian' make[1]: Entering directory '/mnt/hgfs/crypt/openssl-3.2.0_debian' rm -f libcrypto.so && \ ln -s libcrypto.so.3 libcrypto.so ln: failed to create symbolic link 'libcrypto.so': Operation not supported make[1]: *** [Makefile:5387: libcrypto.so] Error 1 make[1]: Leaving directory '/mnt/hgfs/crypt/openssl-3.2.0_debian' make: *** [Makefile:3550:build_sw] 错误 2 lostspeed@debian12d4x64:/mnt/hgfs/crypt/openssl-3.2.0_debian$ pwd /mnt/hgfs/crypt/openssl-3.2.0_debian lostspeed@debian12d4x64:/mnt/hgfs/crypt/openssl-3.2.0_debian$ END
标签:

openssl3.2-官方demo学习-test-certs由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“openssl3.2-官方demo学习-test-certs