OpenSSL:Basic

查看 openssl 的版本

$ openssl version
$ openssl version -a
$ openssl ciphers -v

base64 编码

$ openssl enc -base64/-a -in file.txt
$ openssl enc -base64 -in file.txt -out file.txt.enc
$ echo "encode me" | openssl enc -base64
$ echo -n "encode me" | openssl enc -base64
$ base64 file.txt
上面几个在最终效果上是一样的,实现的方式不同。选项 -a 跟 -base64 相同。
echo 后面加不加 -n 的区别,看下面这个:

$ echo "hello world" > h  ; echo -n "hello world" > h.bk
$ diff h h.bk
1c1
< hello world

> hello world
\ No newline at end of file

$ cat file.txt.enc | openssl enc -base64 -d
$ openssl enc -a -d -in file.txt.enc -out file.txt
解码

产生随机数据

$ openssl rand -base64 128
$ openssl rand -out randdata.bin 1024
$ head -c 32 /dev/urandom | openssl enc -base64
$ echo $(head -c 32 /dev/random | strings -1) | sed 's/[[:space:]]//g'

对称加密

对称加密的形式:
openssl enc [选项]…[选项]
后面接的主要是各种对称算法,如 AES,Blowfish,CAST5,DES,RC4 等。

列出所有对称加密算法:

$ openssl list-cipher-commands

$ openssl enc [-e] -des3 [-salt] [-a] -in plain.txt -out cipher.txt
-e:默认即为加密,可不加
-salt:加把盐,也就是随即送一个随即值,增加加密强度
-a:加密后使用 base64 编码,便于查看。若没有该选项,cipher.txt 为二进制乱码

$ file plain.txt cipher.txt
plain.txt:     ASCII text
cipher.txt:    ASCII text
加了 -a 选项后文件类型为 ASCII

$ openssl enc -d -des3 [-salt] [-a] -in cipher.txt -out p.txt
解密,-salt 可以忽略

将 file.txt 使用 256 比特的 AES 算法加密:

$ openssl enc -aes-256-cbc -salt -in file.txt -out file.enc

跟上面的类似,只不过加密后再做一次 base64 编码:

$ openssl enc -aes-256-cbc -a -salt -in file.txt -out file.enc

解密:

$ openssl enc -d -aes-256-cbc -in file.enc

解密以 base64 编码后的加密文件:

$ openssl enc -d -aes-256-cbc -a -in file.enc

以明文的方式加密:

$ openssl enc -aes-256-cbc -salt -in file.txt -out file.enc -pass pass:mySillyPassword

加密钥放在文件中:

$ openssl enc -aes-256-cbc -salt -in file.txt -out file.enc -pass file:/path/to/secret/password.txt

另外在对称加密中,还有 -K,-iv 表示从口令中提取加密密钥和初始向量;-S 指定 salt 值;-nosalt 等选项,用的不是很多。

非对称加密

非对称加密的指令形式:
openssl command [选项] … [选项]
其中 command 跟上面的对称加密稍有不同,支持下面几个:

genrsa:生成 RSA
rsa:处理 RSA 的密钥格式转换
resutl:使用 RSA 进行加密,解密,签名,验证等
gendh:生成 DH 算法的密钥参数
dhparam:处理 DH 的密钥参数
dh:处理 DH 的密钥格式转换
dsaparam:生成 DSA 密钥参数
dsa:处理 DSA 密钥的格式转换
gendsa:生成 DSA 密钥

产生 RSA 密钥

默认产生 512 比特的私钥至标准输出:

$ openssl genrsa

产生 1024 比特的私钥到 mykey.pem:

$ openssl genrsa -out mykey.pem 1024

跟上面类似,使用 DES-EDE3-CBC 加密私钥:

$ openssl genrsa -des3 -out mykey.pem 1024

或者这样:

$ openssl genrsa -out mykey.pem 1024 -des3 -passout pass:123456
注意:如果密钥用在服务器上,比如使用 https,建议不要使用对称密钥加密私钥,因为一旦服务需要接触密钥,就需要输入密码,很不方便。

产生 RSA 公钥至标准输出:

$ openssl rsa -in mykey.pem -pubout
$ openssl rsa -in mykey.pem -pubout > mykey.crt
$ openssl rsa -in key.pem -pubout -out pubkey.pem
$ openssl rsa -pubout < mykey.pem > mykey.crt
-in/-out:in 选项指定了存储输入密钥的文件名,输入文件默认应该使用 RSA 的私钥文件,但是如果使用了 -pubin 选项,则输入的是 RSA 公钥文件,文件的格式可以使用 -inform 来指定。-out 选项指定了输出文件名,默认的输出应该为 RSA 私钥,若使用了 -pubout,则输出的是 RSA 公钥。这也是上面第三条命令包含的意思。

将 RSA 私钥中的元素输出至标准输出:

$ openssl rsa -in key.pem -text -noout
-text:以明文的形式输出密钥到各个参数的值
-noout:不会输出任何密钥到文件中,即使使用了 -out 选项指定了输出文件

删除 RSA 私钥的密码:

$ openssl rsa -in key.pem -out keyout.pem

使用 DES3 给 RSA 私钥加密:

$ openssl rsa -in key.pem -des3 -out keyout.pem

将私钥有 PEM 格式转为 DER 格式:

$ openssl rsa -in key.pem -outform DER -out keyout.der
$ openssl x509 -in key.pem -inform PEM -out keyout.der -outform DER

将一个加密的 PEM 编码的 RSA 私钥转换成一个不加密 PEM 编码的 RSA 私钥:

$ openssl rsa -in key.pem [-passin pass:123456] -out keynopasswd.pem
-passin:表示获取 RSA 私钥解密口令的源
-passout:表示输出 RSA 私钥时进行加密的口令的源

使用 256 位的 AES 加密私钥,替换掉原来的 DES3 加密:

$ openssl rsa -in keydes.pem [-passin pass:123456] -out keyaes.pem [-passout pass:123456] -aes256

将一个 PKCS#12 格式的编的 RSA 私钥转换成 PEM 编码的 RSA 私钥,并进行加密:

$ openssl -rsa -in key.p12 -inform p12 [-passin pass:123456] -out key.pem [-passout pass:654321] -aes256

RSA 的加密/解密:

$ openssl rsautl -in plain.txt -out encrypt.txt -inkey pubkey.pem -pubin -encrypt
$ openssl rsautl -in encrypt.txt -out plain.new.txt -inkey privatekey.pem -decrypt
-inkey:选择加密解密过程中要使用的密钥文件,默认的是 PEM 格式,实际上,由于 PEM 编码中,RSA 私钥中默认包含了公钥参数,所以即使在执行公钥加密时输入 RSA 的私钥,也能争取的执行,因为程序会自动的使用私钥里面的公钥参数进行相应的加密操作
-pubin:如果执行的是加密或者是验证,那么可以从 -keyin 中输入一个公钥而不是私钥,此时要使用 -pubin 参数告诉系统输入的文件是公钥

或者像下面这样:

$ openssl rsautl -encrypt -pubin -inkey pubkey.pem < plain.txt > encrypt.txt
$ openssl rsautl -decrypt -inkey privatekey.pem < encrypt.txt > plain.new.txt

使用 PKCS#12 格式的证书,里面包含 RSA 私钥,进行签名:

$ openssl rsautl -in plain.txt -out signed.txt -inkey cert.pfx -keyform pkcs12 -sign
$ openssl rsautl -in signed.txt -out plain.new.txt -inkey cert.pfx -keyform pkcs12 -certin -verify
-certin:默认使用证书的私钥,通过该选项告诉系统使用的是证书的公钥,类比 -pubin

产生 DSA 密钥

$ openssl dsaparam –genkey noout -out dsakey.pem 1024
DSA 仅用于签名;DH 仅用于加密;而 RSA 二者均可,所以 RSA 的用途更广一些。

或者预先产生一个参数文件,以后就可以批量产生了:

$ openssl dsaparam -out dsaparam.pem 1024

将上述默认产生的 dsaparam.pem 的格式转换成 DER 格式:

$ openssl dsaparam -in dsaparam.pem -out dsaparam.der -outform d

产生第一个私钥:

$ openssl gendsa [-des3] -out key1.pem dsaparam.pem

第二个:

$ openssl gendsa -out key2.pem dsaparam.pem

用 256 位的 AES 算法加密 DSA 私钥:

$ openssl gendsa -out key3.pem -aes256 [-passout pass:123456] dsaparam.pem

得到 DSA 的公钥:

$ openssl dsa -in privatekey.pem -out pubkey.pem -pubout

更换 DSA 的私钥保护口令:

$ openssl dsa -in privatekey.pem [-passin pass:123456] -des3 -out privatekey.new.pem [-passout pass:654321]

增加/删除 DSA 私钥的密码,转换格式等跟上面的 RSA 大同小异。

单项加密

也就是做散列(哈希)了,个人认为它算不上一种加密吧,毕竟理论上是不可逆的。

$ openssl dgst -sha1 readme
SHA1(readme)= ee12e6451f402afb9d5f25297f9add79b88475f3
-sha1:使用 -SHA1 算法做哈希

下面这两条跟上面的等价:

$ openssl sha1 < readme
$ openssl dgst -sha1 < readme

还可以使用 sha1sum 这个工具得到同样的结果:

$ sha1sum readme
ee12e6451f402afb9d5f25297f9add79b88475f3  readme

使用 md5 算法做哈希的同理,s/sha1/md5/g 即可 ;-)

当我们使用 passwd username 时,系统会默认将我们提供的用户名密码以一定的方式存储在系统中,/etc/login.defs 默认以 MD5 的方式

$ openssl passwd -1
Password:
Verifying – Password:
$1$AlonUWoz$iOZWhF9d.9Pw4XGwPoXnC.

再做一次同样的操作:

$ openssl passwd -1
Password:
Verifying – Password:
$1$92o2TRxn$9HBNAwP/9iauqWe2Ea3tt/

最后得到的哈希值却不一样,显然是加盐(-salt)的了。

对摘要签名:

$ openssl dgst -sha1  -sign key.pem -out test.sha1 test

$ 验证签名:

openssl dgst -sha1  -verify pubkey.pem  -signature test.sha1 test

如上篇密码学理解所说,通常摘要是跟签名联系在一起的,下面分别演示使用 RSA 和 DSA 签名/验证。

RSA

生成密钥:

$ openssl genrsa -out private.pem -passout pass:123456 -des3 1024

从私钥中导出公钥:

$ openssl rsa -in private.pem -passin pass:123456 -out public.pem -pubout

签名:

$ openssl dgst -sha1 -sign private.pem -out file.sgn file.txt

验证:

$ openssl dgst -sha1 -verify public.pem -signature file.sgn file.txt

DSA

生成密钥参数:

$ openssl dsaparam -out dsaparam.pem 1024

由密钥参数生成密钥:

$ openssl gendsa -out private.pem -des3 -passout pass:123456 -des3 desparam.pem

有私钥导出公钥:

$ openssl dsa -in private.pem -passin pass:123456 -out public.pem -pubout

签名:

$ openssl dgst -sha1 -sign private.pem -out file.sgn file.txt

验证:

$ openssl dgst -sha1 -verify public -signature file.sgn file.txt

请先掌握上述的基本密钥生成指令,下篇才是重点:-)

参考:
http://www.openssl.org/
http://en.wikipedia.org/wiki/OpenSSL
http://www.madboa.com/geek/openssl