OpenSSL 介绍(4)--非对称加密

本文主要介绍如何使用 OpenSSL 来进行非对称加解密,使用的算法为 RSA,DSA 算法的使用方法类似;文中所使用到的软件版本:OpenSSL 1.1.1s、CentOS 7.9.2009。

1、非对称加密算法

非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将公钥公开,需要向甲方发送信息的其他角色(乙方)使用该密钥(甲方的公钥)对机密信息进行加密后再发送给甲方;甲方再用自己私钥对加密后的信息进行解密。甲方想要回复乙方时正好相反,使用乙方的公钥对数据进行加密,同理,乙方使用自己的私钥来进行解密。

另一方面,甲方可以使用自己的私钥对机密信息进行签名后再发送给乙方;乙方再用甲方的公钥对甲方发送回来的数据进行验签。

甲方只能用其私钥解密由其公钥加密后的任何信息。 非对称加密算法的保密性比较好,它消除了最终用户交换密钥的需要。

非对称密码体制的特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。对称密码体制中只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。所以保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,其中一个是公开的,这样就可以不需要像对称密码那样传输对方的密钥了。这样安全性就大了很多。

非对称加密算法主要有:RSA、DSA、DH(Diffie-Hellman密钥交换算法) 和 ECC(椭圆曲线加密算法)。

2、用法

2.1、生成 RSA 私钥

通过 openssl genrsa -help 命令查看用法:

shell> /home/mongo/soft/openssl-1.1.1s/bin/openssl genrsa -help
Usage: genrsa [options]
Valid options are:
 -help               Display this summary
 -3                  Use 3 for the E value
 -F4                 Use F4 (0x10001) for the E value
 -f4                 Use F4 (0x10001) for the E value
 -out outfile        Output the key to specified file
 -rand val           Load the file(s) into the random number generator
 -writerand outfile  Write random data to the specified file
 -passout val        Output file pass phrase source
 -*                  Encrypt the output with any supported cipher
 -engine val         Use engine, possibly a hardware device
 -primes +int        Specify number of primes

参数说明:

参数 说明
-out outfile 指定私钥输出文件
-* 指定对私钥进行加密的对称加密算法

2.2、RSA 密钥操作

OpenSSL 中可以通过 openssl rsa 命令进行密钥的相关操作,包括从公钥提取私钥;通过 openssl rsa -help 命令查看用法:

shell> /home/mongo/soft/openssl-1.1.1s/bin/openssl rsa -help
Usage: rsa [options]
Valid options are:
 -help              Display this summary
 -inform format     Input format, one of DER PEM
 -outform format    Output format, one of DER PEM PVK
 -in val            Input file
 -out outfile       Output file
 -pubin             Expect a public key in input file
 -pubout            Output a public key
 -passout val       Output file pass phrase source
 -passin val        Input file pass phrase source
 -RSAPublicKey_in   Input is an RSAPublicKey
 -RSAPublicKey_out  Output is an RSAPublicKey
 -noout             Don't print key out
 -text              Print the key in text
 -modulus           Print the RSA key modulus
 -check             Verify key consistency
 -*                 Any supported cipher
 -pvk-strong        Enable 'Strong' PVK encoding level (default)
 -pvk-weak          Enable 'Weak' PVK encoding level
 -pvk-none          Don't enforce PVK encoding
 -engine val        Use engine, possibly a hardware device

参数说明:

参数 说明
-inform format 指定输入格式:DER,PEM
-outform format 指定输出格式:DER,PEM,PVK
-in val 指定密钥输入文件
-out outfile 指定密钥输出文件
-pubout 输出公钥
-noout 不输出私钥信息
-text 以文本格式打印私钥信息
-* 对私钥进行加密的对称加密算法

2.3、RSA 加解操作

通过 openssl genrsa -help 命令查看用法:

shell> /home/mongo/soft/openssl-1.1.1s/bin/openssl rsautl -help
Usage: rsautl [options]
Valid options are:
 -help                    Display this summary
 -in infile               Input file
 -out outfile             Output file
 -inkey val               Input key
 -keyform PEM|DER|ENGINE  Private key format - default PEM
 -pubin                   Input is an RSA public
 -certin                  Input is a cert carrying an RSA public key
 -ssl                     Use SSL v2 padding
 -raw                     Use no padding
 -pkcs                    Use PKCS#1 v1.5 padding (default)
 -oaep                    Use PKCS#1 OAEP
 -sign                    Sign with private key
 -verify                  Verify with public key
 -asn1parse               Run output through asn1parse; useful with -verify
 -hexdump                 Hex dump output
 -x931                    Use ANSI X9.31 padding
 -rev                     Reverse the order of the input buffer
 -encrypt                 Encrypt with public key
 -decrypt                 Decrypt with private key
 -passin val              Input file pass phrase source
 -rand val                Load the file(s) into the random number generator
 -writerand outfile       Write random data to the specified file
 -engine val              Use engine, possibly a hardware device

参数说明:

参数 说明
-in infile 指定待加解密的文件
-out outfile 指定输出文件
-inkey val 指定密钥输入文件
-pubin 输入密钥为公钥
-encrypt 使用公钥加密
-decrypt 使用私钥解密

3、具体使用

3.1、生成私钥

shell> /home/mongo/soft/openssl-1.1.1s/bin/openssl genrsa -out test.key 2048

生成一个 2048 位的私钥并保存到 test.key 文件中,文件内容如下:

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAwyPpByJekg7LbQge8qORTPl72llYxlpMvXqCGO7VN2xuOdxw
zXTQ9/B/3MOTmS7rOVU0IpcYTt6C0SMTzoKjRCR1FdM81YFecL8litilC85GIktp
dWralQawIvMkZ4pv3sGth4PHiYqsTMlx984/TDOFXQ5vgT9VceXJ3KXZ8mVzyptw
egIRN/OzBjY9KgrbIf7qgyuzjX1zXQMqgBl9LmUdWaETBYfDfSzuxBooeOYRXTYz
vqm7GJzmnWGBskc3pytai1G7TopRNjuWBroIQqP11nUPyMVpGJ5U5WYGZg95rqw6
zsNaAmauN6xqiEmvCENdvAixW6j8P36h0MIfNwIDAQABAoIBAFlsC00Jouyreuzr
28K00dDEQs08REIg/ymVCikCyRIszhYVvltoPJphyzYPKYP4zDHpqYpwUuNRdAEC
YgEwPEDts/ncYvQz5GMmNL37qSZP0DPG+vyjiqbf+bcKVJReDAW4Gx0OdlHBClPl
vCQijz8MHQEXrGE99JnNA0PpfIZmyLvbq3mj+npDvMWq3aDPy0swdbjMUDJnCdUJ
3X/RajtPgZYSQuJDflfh6GbYk6fUSMP+FDF+SbH7MwNZe86A92poSFc8HzaGPwwU
66UmFYr6EXAMKZ816IpYNIRhgLPKPLJ/3PboES0D8PuB+VUfAvxCEelC4UJCs6k5
gHuPs4ECgYEA/am2cOhOBJyWCpmeFRTCQDp9aJbwwTpUtPKesnmFcLXgkqTqWH90
YCY8OC9ola5kJXH1nPFRy3s3u/eXyvJbRZVmhTrTBXWt5fwcGfCAnT2P2HlJBXka
fZhSaLNcSOurDFrz/8AOLLhLMv2XiS3kwjNcUm3EPL6115oTR8pRABMCgYEAxPAq
oUemPS0LFVFjWKyPSYYGV21fSRQWFzzOsX+zMiRIjsAATT0Nynz9h/96HEQ78xOz
foda+kAzV6sAI8q5S5RLbLWFM7XmMPg2vb1ryliNHwz/FhR6tX1KKMfggffGn0XW
YIGjyWkGFeU5HkILy3T6kC/yzk/+RschnpXIsM0CgYA4b6rkofrBsej8AMOYIx84
1QqT24lDJGw2Ogiu4rSaqAyH8+Mjv2+v+LHLOlkFfGBRqHIh8drl78stqd9+yr8d
0yiVGcpbW5xOH/JMnyKuWUUIv6tMaW5IZTxoiQdOPgi3XgENdLhyoKoydRNi9PAB
eRXgTQWtEi05A9GoVk4BOwKBgQClBCCUVzcCV7XLvRCjgqPllXnG1AxdbYk9G2SN
8lSylRh/FH6sOZZOrwC5beZhvQMGoOFsCfq/agAbW1uYogs1OyMgCdF9DNO/AJzN
y+R//kbxV7B+TdasMDlthl2mSXmSh7Aj2TzmTSweOJ3trqW3a2NwYdzv5rNHlx+i
hBtPmQKBgQCbFZQs2DSyULaoh9HJTh+xsU9MZkoTD8J0JAR026IjcltgFHGXI7QH
CtHttO6POMYK+krOcsc5JPfiB6yfDjWnCqQ+bw/kMH5C/2CuhYC4aZRdmJJ4d0ds
r0BsH5zhRzPRP2OyMuOUNK+YLwfHfTv2yEJM5KBPguKyfHrr4SjHfw==
-----END RSA PRIVATE KEY-----

3.2、打印私钥

/home/mongo/soft/openssl-1.1.1s/bin/openssl rsa -in test.key -noout -text

3.3、根据私钥生成公钥

shell> /home/mongo/soft/openssl-1.1.1s/bin/openssl rsa -in test.key -pubout -out test.pem

生成的公钥保存到 test.pem 文件中,文件内容如下:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwyPpByJekg7LbQge8qOR
TPl72llYxlpMvXqCGO7VN2xuOdxwzXTQ9/B/3MOTmS7rOVU0IpcYTt6C0SMTzoKj
RCR1FdM81YFecL8litilC85GIktpdWralQawIvMkZ4pv3sGth4PHiYqsTMlx984/
TDOFXQ5vgT9VceXJ3KXZ8mVzyptwegIRN/OzBjY9KgrbIf7qgyuzjX1zXQMqgBl9
LmUdWaETBYfDfSzuxBooeOYRXTYzvqm7GJzmnWGBskc3pytai1G7TopRNjuWBroI
QqP11nUPyMVpGJ5U5WYGZg95rqw6zsNaAmauN6xqiEmvCENdvAixW6j8P36h0MIf
NwIDAQAB
-----END PUBLIC KEY-----

3.4、使用公钥加密

A、通过管道符指定输入

echo -n 123456 | /home/mongo/soft/openssl-1.1.1s/bin/openssl rsautl -encrypt -inkey test.pem -pubin -out test.encrypt

使用公钥加密 "123456",结果保存到 test.encrypt 文件中。

B、输入为文件

新建文件 a.txt,在文件中输入内容:

123456

使用 a.txt 作为输入:

/home/mongo/soft/openssl-1.1.1s/bin/openssl rsautl -encrypt -inkey test.pem -pubin -in a.txt -out test.encrypt

 

注:标准输入(结束方法:先输入回车,然后输入 ctrl+D)会把换行符也带入计算;使用文件输入时,也会在文件内容最后增加换行作为 OpenSSL 的计算输入;这会导致加密的结果用其他加密工具(如:Java)解密后会多出一个换行,所以使用 echo -n 来去除换行。

3.5、使用私钥解密

/home/mongo/soft/openssl-1.1.1s/bin/openssl rsautl -decrypt -inkey test.key -in test.encrypt

3.5、私钥转为 PKCS8 格式

OpenSSL 生成的私钥默认为 PKCS1 格式,如果需要使用 Java 来加解密,则需要转成 PKCS8 格式;使用 openssl pkcs8 命令来进行转换:

/home/mongo/soft/openssl-1.1.1s/bin/openssl pkcs8 -topk8 -in test.key -nocrypt -out test_pkcs8.key

转换后的结果保存到 test_pkcs8.key 中。

 

posted @ 2023-02-26 10:12  且行且码  阅读(1097)  评论(0编辑  收藏  举报