pem文件的生成

0702pem文件的生成

刚刚的笔记没了,因为电脑蓝屏了,我又没保存。现在再补回。

一开始问题是出在没理解demo里面引用的pem文件。拿来测试)(在demo里先签名,然后紧接着就验签),结果发现,验签失败。
后面想想,私钥是银联自己的,而公钥则是对方提供给银联的。因此,用银联的私钥去签名,而用对方的公钥进行验签,验签当然会失败。

然后,就要想办法自己去生成公私钥的pem文件。一开始很排斥,不想自己去生成,感觉好麻烦,事实上,也花了好长时间去理解。

找了很久,找到了一篇生成pem文件的文章(找了很多篇,有些生成的pem文件不对,当时被误导了很久)。(前面也花了好一些时间,才意识到自己要百度的内容:openssl如何生成pem公私钥),文章连接为:https://blog.csdn.net/m0_38080126/article/details/77609304

一开始直接copy paste。

为了防止链接失败,就把文章内容拷下来了:

1、生成RSA密钥的方法 

openssl genrsa -des3 -out privkey.pem 2048 
这个命令会生成一个2048位的密钥,同时有一个des3方法加密的密码,如果你不想要每次都输入密码,可以改成: 
openssl genrsa -out privkey.pem 2048 
建议用2048位密钥,少于此可能会不安全或很快将不安全。 

2、生成一个证书请求 
openssl req -new -key privkey.pem -out cert.csr 
这个命令将会生成一个证书请求,当然,用到了前面生成的密钥privkey.pem文件 
这里将生成一个新的文件cert.csr,即一个证书请求文件,你可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacert.pem,那才是你的数字证书。 

如果是自己做测试,那么证书的申请机构和颁发机构都是自己。就可以用下面这个命令来生成证书: 
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 
这个命令将用上面生成的密钥privkey.pem生成一个数字证书cacert.pem 

3、使用数字证书和密钥 
有了privkey.pem和cacert.pem文件后就可以在自己的程序中使用了,比如做一个加密通讯的服务器

一开始直接copy生成私钥pem,然后走第二步,再走第三步。没去看文字,没去理解。

后来,理解了,第一步是生成pem文件,第二步是生成证书申请(用于向CA申请证书用的),第三步是通过私钥pem生成公钥pem。

也才明白,公钥pem是通过私钥pem生成的。

拿到两个pem文件就去测试了,结果出现了异常,在签名那里就死掉了。对比我自己创建的pem文件和demo里的pem文件,我发现,我的pem文件里面有多余的头和尾,如:

公钥pem的头和尾:

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

私钥pem的头和尾:

-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

这里卡了很久。一直想不懂,为什么我的pem文件会有头和尾的部分,而demo的pem文件里面却没有。我在想是不是我生成pem的方式不对。去掉头和尾,运行程序,出错。吓得我赶紧回头,补上头和尾。

卡了很久,最后明白,原来没所谓,有头和尾没关系,在读取的时候,只要在代码中解析文件的时候跳过头和尾就可以了。我一开始以为直接修改文件会影响里面的内容。后来证实我是错的。可能我被那个异常信息吓到了。

只要在读取文件时,发现第一个符号是’-‘,就跳过这一行,就可以读取到正式的内容了。

对了,如果把头和尾都读进去,那么在签名那一步就会出错,错误信息忘了。如果把头尾去掉,那么还是会出现异常,出错的地方是在验签那里。

还有一个问题卡了我很久,Demo里是这样读取pem文件的:

//从私钥文件中读取私钥
File file = new File(System.getProperty("user.dir") + "\\src\\myPrivateKey.pem");
InputStreamReader read = new InputStreamReader(new FileInputStream(file), "UTF-8");//考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String str = null;
while((str = bufferedReader.readLine()) != null) {
    HttpServer.myPrivateKey += str + "\n";
}
read.close();

我在想,是不是错在换行这里???是不是不应该换行,直接拼接就好。我就改了(这是银联的人提供的demo,我竟然质疑他的),结果还是会出错。顿时没有了方向,到底问题是出在哪里。

百度的时候,有的人是通过key文件来生成两个pem文件。懵逼。。。

又看到有人说,通过openssl genrsa -out privkey.pem 2048生成的私钥pem并不是能直接拿来用的,得把RSA私钥转换成PKCS8格式:

pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocrypt

然后,控制台就输出了一个新的pem文件的内容,一看,发现,它的头尾是这样的:

-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----

这个才是对的把。我赶紧拷贝一份,作为新的pem文件,然后测试。

还是出错。然后百度继续查,最后查到一篇解决了这个问题的网址:

https://blog.csdn.net/weiyuefei/article/details/76269790

这篇生成两个pem文件的做法和开头提到的那个网址的做法不一样,这个才是有效的。

开头的网址生成的public.pem文件,头和尾专这样的:

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

而这篇文章生成的public.pem的头尾是这样的:

-----BEGIN PUBLIC KEY-----
-----END PUBLIC KEY-----

一看到这个,我想,这次应该对了!果然!

测试,输出:

验签结果:true

感想

总算成功了。从上午10点多弄到下午5点。对pem文件,是第一次接触。对公私钥也是弄这项目才开始接触。努力吧!也算是学到了新东西啊。可能从文章上来看,好像没什么难度,但是事实上,就我而言,弄了很久。新东西,对背景什么的都不了解,所以说,以后在接触新东西之前,要理解好,理解好了再动手!!!

事实证明,银联提供的demo是没问题的,问题是出在我生成pem文件的生成。理解好公钥私钥,demo里的公钥私钥并不是一对的,demo是银联的,那么说明私钥是银联的,公钥是与银联交互的那一方的。理解这点很重要。

正确生成pem文件很重要,生成pem文件的操作为:

1、生成RSA密钥的方法 

openssl genrsa -des3 -out privkey.pem 2048 
这个命令会生成一个2048位的密钥,同时有一个des3方法加密的密码,如果你不想要每次都输入密码,可以改成: 
openssl genrsa -out privkey.pem 2048 
建议用2048位密钥,少于此可能会不安全或很快将不安全。 

2、生成一个证书请求 
openssl req -new -key privkey.pem -out cert.csr 
这个命令将会生成一个证书请求,当然,用到了前面生成的密钥privkey.pem文件 
这里将生成一个新的文件cert.csr,即一个证书请求文件,你可以拿着这个文件去数字证书颁发机构(即CA)申请一个数字证书。CA会给你一个新的文件cacert.pem,那才是你的数字证书。 

如果是自己做测试,那么证书的申请机构和颁发机构都是自己。就可以用下面这个命令来生成证书: 
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 
这个命令将用上面生成的密钥privkey.pem生成一个数字证书cacert.pem 

3、使用数字证书和密钥 
有了privkey.pem和cacert.pem文件后就可以在自己的程序中使用了,比如做一个加密通讯的服务器

你可能感兴趣的:(工作总结,记录)