分类 OpenSSL 下的文章

“OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连线者的身份。这个包广泛被应用在互联网的网页服务器上。 其主要库是以C语言所写成,实现了基本的加密功能,实现了SSL与TLS协议。”

使用openssl 生成rsa-pss 密钥

openssl genpkey -algorithm rsa-pss          \
    -pkeyopt rsa_keygen_bits:2048           \
    -pkeyopt rsa_pss_keygen_md:sha256       \
    -pkeyopt rsa_pss_keygen_mgf1_md:sha256  \
    -pkeyopt rsa_pss_keygen_saltlen:32      \
    -out rsa-pss-privateKey.pem

cat rsa-pss-privateKey.pem

-----BEGIN PRIVATE KEY-----
MIIE7gIBADA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3
DQEBCDALBglghkgBZQMEAgGiAwIBIASCBKgwggSkAgEAAoIBAQCVDnc3tuB3do2g
I2V08eEAMF1pJd5nUJ6SYnBOqKEQ2ZNsU6OV51WGx3leN9gjEdkKjErUi8N0YMo9
TMK0cXpZzHmn/lU6HY3qe/i5ZGhSWWPtC1jE6Tt1BgnfXR9jc9S/+lxfZm9UFSsc
JMwBivbvPEXIyauWA3ww7A7oDh6oC4J5u7clgfbzRGJKLBD2raEMmnTVJoiVTshn
9Wyrm+B/mJK2YhG5pxAQ7pwaK6/eMDn1hLWAJIIS5USz50AC04T9fpenz14ITiWd
9lbKOVBzjHmo67UnhhrNoB8Kf8W6Ti4XEOBwdg/Kaa4hFofk8mV2ymJYYZ6scHbd
2pFcJQWlAgMBAAECggEAded7ZhbCd7zPSly1ZEvwLrYTLZlG03Jx/FjhfVbmEO4K
LyX5wBm9DV+8IUsLLLJxfGZ8yqPDd8sYLmUJnrIkleOoV7pWsCGwoEpv9DX4Tytm
X5saHKhg37BnHsgKjCCTqUfgyZW9ekVEVH7G4HGL4rFKggkEMSWQlyIiqGyC02kS
PEdPcMuBx1AKHWVjtQLc5E4v2lYmhlqVX1N97XcNrbNRdTjOpL4eyf6zkb0IJjuu
9FZYVIDjRe+HI0xMUxTobJXuP5amL9upegCF5hiL0oxUM7kK/UVwPK+SjtV0T3sC
BImxfCAefzOX9K7IGbtECSDPxh+UEIYXv2p+YwEQAQKBgQDF2vcU75Rbv4hgy/iP
16n7XfzZ0+kmfoxetiMM6s/LX3kv85KFyu3+Zm4NZG9gATjs412GoP4YcHzfF9O5
pRNAMaGxBAVzDUG0QGxuwqBPImkKhPBHp46R19UzBuoOKD2N6U3ko0sv567H0+wJ
10dknIn3urNCSeJiTYouxL3y+QKBgQDA3EWGHwod9B7X3brEoBaFkVOM5gemh+ZO
OngnzsH+MDx3a4fIyLvlYQh4gVjx0oR4ctaHJ2acfBKu1xTetIAiBgYrv5Ov2Of4
1/VdF+HEG0pu0wISNZ08dzdAaDT9jRctI5caHQqBjFv4bvMzG466WhHVkH0+cFT+
GNYVuYnnDQKBgENWp9tPQv4K7P6MzTcfnnG35lO4xNReI6YkdT9zN2+vOc6xJoA0
tdVsxS33rdRN9jLhmzYz2uc0ebtwH5ZCcY/alH5rsPMcYu1XM9Bqmybzvi5fWmv4
whQvEhfA1a4l0fVXnzQew3s1bg4CuYYL5/d9M5PFzjbUcKEmZM5QFZn5AoGBAK+7
xuoIfIqAuF4Qn6+tA/ifTJd1v4DiElwz8Oqs/p2kzGQwqmCtcHD5suNDUY3AOo8a
bRpoL5rlf4yrVUv9A0h9XsAcZ/Fy3yUje2NhcInmKDPFt/xpuCWxp7nbenWTS4wJ
AxV7Yuhawi8kwhxOvwZVLi0A5O6xIvEKJoFTODI9AoGBAIF9u17oUZK59dnxA1v1
kv06VvC8JxB95lbc5FlK8ZOeNxxvPf6Y2DqbtkmK8Mc2gfTFH1e6+i6Qr0AE5MBC
2icqlbWAyCbuwlLr9cvbG8Pp/qTrs4dTXWVE4+JRaYytpEt/0395ohAjH+9uvfxr
WuP6176mGPZ4FF1/cIqesl/N
-----END PRIVATE KEY-----

openssl rsa -in rsa-pss-privateKey.pem -pubout -out rsa-pss-publicKey.pem

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlQ53N7bgd3aNoCNldPHh
ADBdaSXeZ1CekmJwTqihENmTbFOjledVhsd5XjfYIxHZCoxK1IvDdGDKPUzCtHF6
Wcx5p/5VOh2N6nv4uWRoUllj7QtYxOk7dQYJ310fY3PUv/pcX2ZvVBUrHCTMAYr2
7zxFyMmrlgN8MOwO6A4eqAuCebu3JYH280RiSiwQ9q2hDJp01SaIlU7IZ/Vsq5vg
f5iStmIRuacQEO6cGiuv3jA59YS1gCSCEuVEs+dAAtOE/X6Xp89eCE4lnfZWyjlQ
c4x5qOu1J4YazaAfCn/Fuk4uFxDgcHYPymmuIRaH5PJldspiWGGerHB23dqRXCUF
pQIDAQAB
-----END PUBLIC KEY-----

echo -n "hello world" > tbs.txt
openssl dgst -sha256 -sign rsa-pss-privateKey.pem -out tbs.sign tbs.txt 
hexdump -C tbs.sign 

00000000 10 34 d7 ae 8d 29 b3 bb 81 b1 24 f8 e7 b5 55 95 |.4...)....$...U.|
00000010 8c 60 4b 70 1d 66 c8 e1 99 8a cb 7c 77 e9 dd 6e |.`Kp.f.....|w..n|
00000020 39 8c b7 91 1d a0 a3 f6 2c ef ee 1d 9f 4c e1 ae |9.......,....L..|
00000030 4c 78 10 37 cb aa 11 c8 cd 2a f7 a4 91 8a 6c 83 |Lx.7.....*....l.|
00000040 2c 32 fa 37 42 71 1d 5a bc 8d 2c d2 54 74 38 f5 |,2.7Bq.Z..,.Tt8.|
00000050 ca 33 a3 e9 54 f2 1b a2 72 71 9f 3c aa 7c c2 1c |.3..T...rq.<.|..|
00000060 e8 33 9f f8 a6 9a 9d ac f5 c4 cb e6 a9 da 66 7b |.3............f{|
00000070 6f f2 a9 cf 6b 9f 91 d8 f7 3d ec 74 f0 77 76 07 |o...k....=.t.wv.|
00000080 ec 60 32 bd cf 7f 22 f1 94 66 be 03 c3 1b 8d b3 |.`2..."..f......|
00000090 8c 21 a9 da d1 72 3c a0 f0 91 1d ae 05 18 13 ab |.!...r<.........|
000000a0 e6 3e c0 44 ea b6 43 f5 e2 8d 57 a7 8a 1d e3 75 |.>.D..C...W....u|
000000b0 bd b1 0e aa 4e b9 16 a9 56 67 4c 11 75 da b2 08 |....N...VgL.u...|
000000c0 bc bc 9a 1a 98 60 2b cc 51 6a b8 4d 2d 07 5c 61 |.....`+.Qj.M-.a|
000000d0 c3 89 00 a4 0a cd aa 17 50 ac 2a 3c 4d 28 3b 8d |........P.*<M(;.|
000000e0 32 29 75 f9 d6 79 72 34 f4 07 db 9f 42 25 ef 7a |2)u..yr4....B%.z|
000000f0 9c d2 b0 24 fd e0 91 d9 be 02 d3 ae da 38 28 f8 |...$.........8(.|

openssl dgst -sha256 -verify rsa-pss-publicKey.pem  -signature  tbs.sign -sigopt rsa_padding_mode:pss tbs.txt 

Verified OK

使用不带pkeyopt的rsa密钥实现rsa-pss签名与验签时,使用

openssl dgst -sign [private_key_file] -sha256 -sigopt rsa_padding_mode:pss -out [output_file] [input_file]
openssl dgst -verify [public_key_file] -signature [signature_file] -sigopt rsa_padding_mode:pss [signature_message_file]

参考:https://linuxcommandlibrary.com/man/openssl-dgst

使用openssl pkeyutl 签名验签

openssl dgst -sha256 -binary -out tbs.sha256 tbs.txt
openssl pkeyutl -sign \
  -in tbs.sha256 -inkey rsa-pss-privateKey.pem \
  -out tbs.sign \
  -pkeyopt digest:sha256 \
  -pkeyopt rsa_padding_mode:pss \
  -pkeyopt rsa_pss_saltlen:-1

  openssl pkeyutl -verify \
  -in tbs.sha256 -sigfile tbs.sign \
  -pkeyopt rsa_padding_mode:pss \
  -pubin -inkey rsa-pss-publicKey.pem \
  -pkeyopt rsa_pss_saltlen:-1 \
  -pkeyopt digest:sha256

Signature Verified Successfully

GO 读取带pkeyopt的密钥

func pem_to_pri(pripem string) *rsa.PrivateKey {

    block, _ := pem.Decode([]byte(pripem))
    if block == nil || (block.Type != "PRIVATE KEY" && block.Type != "RSA PRIVATE KEY") {
        log.Fatal("failed to decode PEM", block)
        return nil
    }
    var oidPrivateKeyRsaPss = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
    type pkcs8 struct {
        Version    int
        Algo       pkix.AlgorithmIdentifier
        PrivateKey []byte
    }
    var privKey pkcs8
    if _, err := asn1.Unmarshal(block.Bytes, &privKey); err != nil {
        return nil
    }

    if privKey.Algo.Algorithm.Equal(oidPrivateKeyRsaPss) {
        rsaPrivKey, err := x509.ParsePKCS1PrivateKey(privKey.PrivateKey)
        if err == nil {
            return rsaPrivKey
        }
    }
    rsaPrivKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)

    if err != nil {
        log.Println(err)
        return nil
    }

    return rsaPrivKey
}

parsing the rsa pss key manually

func loadPrivateKey(pemEncodedPK string) (crypto.PrivateKey, error) {
    var oidPrivateKeyRsaPss = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
    block, _ := pem.Decode([]byte(pemEncodedPK))
    if block == nil {
        return nil, errors.New("empty block")
    }

    // taken from crypto/x509/pkcs8.go
    type pkcs8 struct {
        Version    int
        Algo       pkix.AlgorithmIdentifier
        PrivateKey []byte
        // optional attributes omitted.
    }
    var privKey pkcs8
    if _, err := asn1.Unmarshal(block.Bytes, &privKey); err != nil {
        return nil, err
    }

    if privKey.Algo.Algorithm.Equal(oidPrivateKeyRsaPss) {
        rsaPrivKey, err := x509.ParsePKCS1PrivateKey(privKey.PrivateKey)
        if err == nil {
            return rsaPrivKey, nil
        }
    }

    return nil, errors.New("unknown algorithm")
}

1. Create CA Key Pair
Run as administrator the following command:

openssl genrsa -out m2mqtt_ca.key 2048

2. Create CA Certificate
Next I’m creating a certificate for the CA, using the key pair I have created in step 1:

openssl req -new -x509 -days 3650 -key m2mqtt_ca.key -out m2mqtt_ca.crt

3. Create Mosquitto Broker Key Pair
Next, I’m creating a private key for the server (m2mqtt_srv.key) with:

openssl genrsa -out m2mqtt_srv.key 2048

4. Create Certificate Request from CA
That key we need to be certified, so we create a certificate request for it, and the certificate needs to be signed by the CA:

openssl req -new -out m2mqtt_srv.csr -key m2mqtt_srv.key

5. Verify and Sign the Certificate Request
The last step is to sign the server request through the CA to get the broker certificate:

openssl x509 -req -in m2mqtt_srv.csr -CA m2mqtt_ca.crt -CAkey m2mqtt_ca.key -CAcreateserial -out m2mqtt_srv.crt -days 3650

文件清单

m2mqtt_ca.crt : CA Certificate
m2mqtt_ca.key : CA key pair (private, public)
m2mqtt_ca.srl : CA serial number file
m2mqtt_srv.crt : server certificate
m2mqtt_srv.csr : certificate sign request, not needed any more
m2mqtt_srv.key : server key pair

将证书和密钥文件复制到下面目录
/etc/mosquitto/certs
最后目录内容应该类似这样
/etc/mosquitto/certs/m2mqtt_ca.crt
/etc/mosquitto/certs/m2mqtt_srv.crt
/etc/mosquitto/certs/m2mqtt_srv.key

修改/etc/mosquitto/mosquitto.conf配置文件
默认端口号

port 8883

指定证书文件与路径信息

#capath
cafile /etc/mosquitto/certs/m2mqtt_ca.crt

# Path to the PEM encoded server certificate.
certfile /etc/mosquitto/certs/m2mqtt_srv.crt

# Path to the PEM encoded keyfile.
keyfile /etc/mosquitto/certs/m2mqtt_srv.key

# This option defines the version of the TLS protocol to use for this listener.
# The default value allows v1.2, v1.1 and v1.0, if they are all supported by
# the version of openssl that the broker was compiled against. For openssl >=
# 1.0.1 the valid values are tlsv1.2 tlsv1.1 and tlsv1. For openssl < 1.0.1 the
# valid values are tlsv1.
tls_version tlsv1.2

配置文件最终结果

 cat /etc/mosquitto/conf.d/tls.conf 

port 8883
cafile /etc/mosquitto/certs/m2mqtt_ca.crt
certfile /etc/mosquitto/certs/m2mqtt_srv.crt
keyfile /etc/mosquitto/certs/m2mqtt_srv.key
tls_version tlsv1.2

运行测试

mosquitto -c mosquitto.conf -v

systemd服务查看

sudo systemctl status mosquitto

● mosquitto.service - LSB: mosquitto MQTT v3.1 message broker
Loaded: loaded (/etc/init.d/mosquitto; generated)
Active: active (running) since Wed 2022-10-19 09:53:21 CST; 2min 32s ago