今天心血来潮突然想搞搞openssl了,趁着端午小假,刚好有空可以鼓捣孤岛自己喜欢的东西,出去东奔西跑的实在太造孽了,还是宅起来给自己充充电吧。下载openssl最新代码1.0.1g,修复了“心血漏洞”那个版本。编译安装那些小儿科的东西就不再浪费笔墨了,如果出现头文件或者库文件之类的错误,请在本人博客里寻找相关文章,应该主要集中在动态库那几篇博文。反正我在自己虚拟机里安装的时候是妥妥滴。
因为我主要对非对称加密的RSA算法比较感兴趣,网上最多的就是这么用的:
生成私钥文件(其中已经包含了公钥):
然后再从这个私钥文件里将公钥提取出来,保存到文件里:
RSA一般有两种应用场景:
1、公钥加密、私钥解密:这是数据安全通信领域最常见情形;
2、私钥加密、公钥解密:这主要用于数字签名。
两种方式,一通百通,本文只看第一种场景。
关于测试代码,网上到处都是,也都基本能用,我就先不摘抄了。大家问的最多的问题就是在读取公钥文件时, PEM_read_RSA_PUBKEY()函数和 PEM_read_RSAPublicKEY()的疑惑。为什么读取私钥文件用的PEM_read_RSAPrivateKey(),针对上述openssl命令生成的公钥文件,在读取其内容时用对称的 PEM_read_RSAPublicKEY()接口却会报错,必须要用 PEM_read_RSA_PUBKEY()才可以。
其实,我们要是看看一两个文件内容就明白了:
当我们在用 PEM_read_RSAPublicKEY()读取公钥文件plainPub.key时报的错误是酱紫滴:
所以我就天真地将公钥文件头和尾分别改成“-----BEGIN RSA PUBLIC KEY-----”和“-----BEGIN RSA PUBLIC KEY-----”,理想很丰满,显示很骨感。实践证明openssl是不能那么轻易就被忽悠过去的。没办法,查看openssl源码发现,提取公钥文件时除了-pubout参数可以设置外,还有有个参数叫做-RSAPublicKey_out,但是命令行提示和man手册里居然没有任何提及。幸好我还会读C代码,所以提取公钥时我改用下面的命令:
这样做完的结果是,首先公钥文件的内容有点变化:
其次,当我再用PEM_read_RSAPublicKEY()接口来读取公钥文件plainPub2.key时,居然成功了。说明RSA PUBLIC KEY和PUBLIC KEY的两种公钥文件其存储方式是不一样的,PEM_read_RSAPublicKEY()只能读取RSA PUBLIC KEY形式的公钥文件;而PEM_read_RSA_PUBKEY()只能读取PUBLIC KEY格式的公钥文件。由于本人密码学基础较薄弱,现在还不能说出两者的区别,请各位见谅,还望密码方面的大牛们予以点拨。演示代码如下:
因为我主要对非对称加密的RSA算法比较感兴趣,网上最多的就是这么用的:
生成私钥文件(其中已经包含了公钥):
[root@localhost release]#openssl genrsa -out plainPrv.key 1024 |
然后再从这个私钥文件里将公钥提取出来,保存到文件里:
[root@localhost release]#openssl rsa -in plainPrv.key -pubout -out plainPub.key |
RSA一般有两种应用场景:
1、公钥加密、私钥解密:这是数据安全通信领域最常见情形;
2、私钥加密、公钥解密:这主要用于数字签名。
两种方式,一通百通,本文只看第一种场景。
关于测试代码,网上到处都是,也都基本能用,我就先不摘抄了。大家问的最多的问题就是在读取公钥文件时, PEM_read_RSA_PUBKEY()函数和 PEM_read_RSAPublicKEY()的疑惑。为什么读取私钥文件用的PEM_read_RSAPrivateKey(),针对上述openssl命令生成的公钥文件,在读取其内容时用对称的 PEM_read_RSAPublicKEY()接口却会报错,必须要用 PEM_read_RSA_PUBKEY()才可以。
其实,我们要是看看一两个文件内容就明白了:
[root@localhost release]# cat plainPrv.key -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQDlGVxzTDVhnC16SW+D0WG8hvm1wztmr0vBh2VK6CU7k90mdrCx 4by1URcZ6iS6KxomxSqWmK9g2C0iRd8xx7OyykBHKttjIx5Diq3wLXDP2qU4mjSI vHP3MwgrOR2Jwa4mNr1veM2c1pyXn5xIfZs2IFnicMugj+0sXik1pLWwIwIDAQAB AoGBAKoB5OomfmJ92/2oKxmdsjKN0xY/13++y6/EgrVQifipJG5bm4mVI01F7Ket ai3AuHpWy+DPUy3BndSWFyfAsyatULiK3cJnIZumxmWP8G9odfO1pH/KcZB2Vi61 HcbioDuJRCcF3jpbGMun3lCwkdG/qVfsFmOElbzSbNMDbwkJAkEA/K9mOSKrP+lu 6bsIuD6/n2XQkz8XE2lPuPwKhVLX+ljXqRyxJZH0n+2EC8pUi694Q2Zhgn0uPdEl KCYtlBaLXQJBAOgawH01Xc0r63+XVif6rLZfwJGBAP8921e2dRDFYhYLP3riflY8 xvFQsh4n7kbAXt4xZ3pDA/J1INnE01Rk8X8CQCmzyOslDZ4+qE9qzsWZlYZ5BzNF 9kj92GpvLk1SntJyVyVR1uqcbAL48BICEnH7Q53cB7vBbSBGpBs8Mcl+7wECQQCF Dbjkze/sys2ggd+44WGa1n8sqhgpOYuA1656I7ybyGzmg+pKg2LEOS8yTE+yrVp0 4ztfggVEO1LOo59F1Ov/AkEApfUtgKHB4YCPy70syFaQoAWjiaxOWq/FLM7FBntP ikz1X7gNsRkb4I/be15ZN8E/2Z0Q95FOpsgqw76Bi4Yynw== -----END RSA PRIVATE KEY----- [root@localhost release]# cat plainPub.key -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlGVxzTDVhnC16SW+D0WG8hvm1 wztmr0vBh2VK6CU7k90mdrCx4by1URcZ6iS6KxomxSqWmK9g2C0iRd8xx7OyykBH KttjIx5Diq3wLXDP2qU4mjSIvHP3MwgrOR2Jwa4mNr1veM2c1pyXn5xIfZs2IFni cMugj+0sXik1pLWwIwIDAQAB -----END PUBLIC KEY----- |
当我们在用 PEM_read_RSAPublicKEY()读取公钥文件plainPub.key时报的错误是酱紫滴:
3077879432:error:0906D06C:lib(9):func(109):reason(108):pem_lib.c:698:Expecting: RSA PUBLIC KEY |
所以我就天真地将公钥文件头和尾分别改成“-----BEGIN RSA PUBLIC KEY-----”和“-----BEGIN RSA PUBLIC KEY-----”,理想很丰满,显示很骨感。实践证明openssl是不能那么轻易就被忽悠过去的。没办法,查看openssl源码发现,提取公钥文件时除了-pubout参数可以设置外,还有有个参数叫做-RSAPublicKey_out,但是命令行提示和man手册里居然没有任何提及。幸好我还会读C代码,所以提取公钥时我改用下面的命令:
[root@localhost release]#openssl rsa -in plainPrv.key -RSAPublicKey_out -out plainPub.key |
这样做完的结果是,首先公钥文件的内容有点变化:
[root@localhost test_openssl]# cat plainPub2.key -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAOUZXHNMNWGcLXpJb4PRYbyG+bXDO2avS8GHZUroJTuT3SZ2sLHhvLVR FxnqJLorGibFKpaYr2DYLSJF3zHHs7LKQEcq22MjHkOKrfAtcM/apTiaNIi8c/cz CCs5HYnBriY2vW94zZzWnJefnEh9mzYgWeJwy6CP7SxeKTWktbAjAgMBAAE= -----END RSA PUBLIC KEY-----
[root@localhost
release]# cat plainPub.key
----- BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlGVxzTDVhnC16SW+D0WG8hvm1 wztmr0vBh2VK6CU7k90mdrCx4by1URcZ6iS6KxomxSqWmK9g2C0iRd8xx7OyykBH KttjIx5Diq3wLXDP2qU4mjSIvHP3MwgrOR2Jwa4mNr1veM2c1pyXn5xIfZs2IFni cMugj+0sXik1pLWwIwIDAQAB ----- END PUBLIC KEY----- |
其次,当我再用PEM_read_RSAPublicKEY()接口来读取公钥文件plainPub2.key时,居然成功了。说明RSA PUBLIC KEY和PUBLIC KEY的两种公钥文件其存储方式是不一样的,PEM_read_RSAPublicKEY()只能读取RSA PUBLIC KEY形式的公钥文件;而PEM_read_RSA_PUBKEY()只能读取PUBLIC KEY格式的公钥文件。由于本人密码学基础较薄弱,现在还不能说出两者的区别,请各位见谅,还望密码方面的大牛们予以点拨。演示代码如下:
点击(此处)折叠或打开
- /* filename: tmp.c
- */
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<openssl/rsa.h>
- #include<openssl/pem.h>
- #include<openssl/err.h>
-
- void hexprint(char *str,int len)
- {
- int i=0;
- for(i=0;i<len;i++){
- printf("%s%02x%s"