1. linux 下编译

源码地址为:https://www.openssl.org/source/old/;当前最新版本为 1.1.0f,https://www.openssl.org/source/old/1.1.0/openssl-1.1.0f.tar.gz

源码编译

解压之后,进入源码目录openssl-1.1.0f,执行如下命令。因为只需要编译静态库,也没有特殊要求,所以使用的编译选项配置很简单:

1

2

./config -fPIC no-shared

make

其中,-fPIC:指示生成位置无关的代码,这个选项是在把openssl生成的静态库链接到动态库的时候提示错误添加的;no-shared:指示生成静态库。

最终在当前目录下会编译出libssl.a和libcrypto.a两个库文件,在开发的时候只需要包含头件并链接这两个库就可以了。

开发使用

有一点需要注意的是编译生成的库libssl.a和libcrypto.a存在依赖关系,要把libssl.a放在libcrypto.a前面,不然可能出现未定义的错误。库的头文件在openssl-1.1.0f/include/openssl目录中。

将openssl-1.1.0f/include/openssl目录拷贝到自己模块的头文件目录(./inc)下,将libssl.a和libcrypto.a静态库拷贝到自己模块的库文件目录(./lib)下,在makefile中添加头文件目录和lib库:

1

2

INCLUDE += ******** -I./inc

LIB += ******* -L./lib -lssl -lcrypto

在使用openssl库函数时,添加如下头文件(按需添加)即可:

1

2

3

#include <openssl/bio.h>

#include <openssl/ssl.h>

#include <openssl/err.h>

<二> android 下如何编译

armeabi-v7a:

export ANDROID_NDK=/home/share/android-ndk-r14b
export PATH=$ANDROID_NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH

./Configure android-arm -D__ANDROID_API__=23

make

android-arm64:

export ANDROID_NDK=/home/share/android-ndk-r14b
export PATH=$ANDROID_NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin:$PATH

./Configure android-arm64 -D__ANDROID_API__=23

make

<三> windows 上如何编译

参考:https://blog.csdn.net/u010333084/article/details/104985398

需要注意事项:以上链接是使用vs2017编译的,我的编译器 是vs2013.

编译64bit方法如下:

VS2013 x64 Cross Tools Command Prompt

Perl Configure VC-WIN64A no-asm --prefix=C:/OpenSSL1   //编译64bit库

编译报错:

fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'

解决办法:

nmake clean

make

编译32bit库的方法如下:

Perl Configure VC-WIN32 no-asm --prefix=C:/OpenSSL1   //编译32bit库

编译32bit的库报错:

解决方法:

4. PKCS1与PKCS8的小知识

转自:https://www.jianshu.com/p/a428e183e72e

简介

最近有小伙伴们搞不清楚RSA的私钥PKCS1与PKCS8到底是什么区别。在应用中会有各种各样的疑问。这边文章就稍微详细的讲一下这两种格式的区别。
PKCS1:全名《Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications》最新版本2.2 (rfc8017, 有兴趣的同学可以读一下) ,从名称上可以看出它是针对RSA算法的一个规范。里面包含了RSA加密、解密、签名验签等所有的内容,当然也包含了私钥的格式。PKCS1的1.1版本是1991年发布的。
PKCS8:全名《Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification》最新版本1.2,从名称上可以看出它是一个专门用来存储私钥的文件格式规范。PKCS1的1.2版本是2008年发布的。
刚好它们两个有重合的部分,都定义了私钥的存储,那他们到底有什么关系呢?我们下面实际验证一下。

验证

产生RSA私钥

bash# openssl genrsa -out pkcs1.pem 1024

此时当前目录下就有一个pkcs1.pem文件,查看文件内容可以看到

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCss7fSp+qZaACgW+rFStHODx8Z7Hr1bFMxnqde61SmcF6dbuc/
C1lgJY/FyrTPxlu4wGNpThVn1lPfvQKCNn492kd8kl0863fhU3rk+7/18R+uQCrp
sz9RGz1zSSmRH2m3igwzNafjiu9vAJ7emZ5QmTGIGqAao62w7waXx8gfIwIDAQAB
AoGAKJj+x2htv64xJ4E0CTjzZQss9n0e0n6qd+mh0rBjb9TOiRe/CJT0Z6OszoQ+
SPGKMj4XoHOYmJZLlTbrVgzVU/XgMFuz92IDPhaSafHpk143BVu6fc0Hvt+KIfUq
tj0hSHInW1tICQRA3OJoUDWTNTNbD+iNQx+6T53AGY3nZpECQQDggckjDYKB9SDB
8tG4oiC3H/rHcW9Iy9cVKFIqKy+1kHiFJjsGaY8JWpNr4e0xSaVyC9oi7ICJJkWw
e94RCdE1AkEAxO2T3U9YNOQoqOt4DgzURClzJtbD1lXmcb5MPKkLxcgBPzGVor21
19vCgGmMk/n162vys5YHfixeg8XLINfR9wJAP6itdtIC2oS+SCBpFThrnGFmA52H
l5WtJCOtwKVEPvB7LA4eGIBf/aAAQ0vprNscHY18ygBTphADHLrSyfQFrQJAduth
F4wKoCYHx7oqTZHBvUeqmhGnQY+uEZHxR9Bto4ob9qViz1vwq+GxmwoiMloH/5q4
fWpkK/VvPfP7rmGmEQJBAIdhwWNOhIml+6bS3MxLwFklwWALBzZMvOKWfKTQ9vA6
X27ZNTBt0ij25MI26sD7dtuFq277Ns99+Qdwr5FVjng=
-----END RSA PRIVATE KEY-----

将私钥转为PKCS8

bash# openssl pkcs8 -topk8 -inform PEM -in pkcs1.pem -outform PEM -nocrypt -out pkcs8.pem

此时当前目录下会多出一个pkcs8.pem文件,查看文件内容可以看到

-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKyzt9Kn6ploAKBb
6sVK0c4PHxnsevVsUzGep17rVKZwXp1u5z8LWWAlj8XKtM/GW7jAY2lOFWfWU9+9
AoI2fj3aR3ySXTzrd+FTeuT7v/XxH65AKumzP1EbPXNJKZEfabeKDDM1p+OK728A
nt6ZnlCZMYgaoBqjrbDvBpfHyB8jAgMBAAECgYAomP7HaG2/rjEngTQJOPNlCyz2
fR7Sfqp36aHSsGNv1M6JF78IlPRno6zOhD5I8YoyPhegc5iYlkuVNutWDNVT9eAw
W7P3YgM+FpJp8emTXjcFW7p9zQe+34oh9Sq2PSFIcidbW0gJBEDc4mhQNZM1M1sP
6I1DH7pPncAZjedmkQJBAOCBySMNgoH1IMHy0biiILcf+sdxb0jL1xUoUiorL7WQ
eIUmOwZpjwlak2vh7TFJpXIL2iLsgIkmRbB73hEJ0TUCQQDE7ZPdT1g05Cio63gO
DNREKXMm1sPWVeZxvkw8qQvFyAE/MZWivbXX28KAaYyT+fXra/Kzlgd+LF6Dxcsg
19H3AkA/qK120gLahL5IIGkVOGucYWYDnYeXla0kI63ApUQ+8HssDh4YgF/9oABD
S+ms2xwdjXzKAFOmEAMcutLJ9AWtAkB262EXjAqgJgfHuipNkcG9R6qaEadBj64R
kfFH0G2jihv2pWLPW/Cr4bGbCiIyWgf/mrh9amQr9W898/uuYaYRAkEAh2HBY06E
iaX7ptLczEvAWSXBYAsHNky84pZ8pND28Dpfbtk1MG3SKPbkwjbqwPt224Wrbvs2
z335B3CvkVWOeA==
-----END PRIVATE KEY-----

区别

那么之间有什么区别呢?我们先将两个PEM格式的文件转换为DER格式,这个二进制的数据容易做对比。

bash# openssl rsa -in pkcs1.pem -out pkcs1.der -outform DER
bash# openssl pkcs8 -topk8 -inform PEM -in pkcs1.pem -outform DER -nocrypt -out pkcs8.der
bash# ls
pkcs1.der pkcs1.pem pkcs8.der pkcs8.pem

现在我们得到了两个DER格式的文件,我们可以先用hexdemp看看两个文件的内容:

bash# cat pkcs1.der | hexdump
0000000 30 82 02 5c 02 01 00 02 81 81 00 ac b3 b7 d2 a7
0000010 ea 99 68 00 a0 5b ea c5 4a d1 ce 0f 1f 19 ec 7a
0000020 f5 6c 53 31 9e a7 5e eb 54 a6 70 5e 9d 6e e7 3f
0000030 0b 59 60 25 8f c5 ca b4 cf c6 5b b8 c0 63 69 4e
0000040 15 67 d6 53 df bd 02 82 36 7e 3d da 47 7c 92 5d
0000050 3c eb 77 e1 53 7a e4 fb bf f5 f1 1f ae 40 2a e9
0000060 b3 3f 51 1b 3d 73 49 29 91 1f 69 b7 8a 0c 33 35
0000070 a7 e3 8a ef 6f 00 9e de 99 9e 50 99 31 88 1a a0
0000080 1a a3 ad b0 ef 06 97 c7 c8 1f 23 02 03 01 00 01
0000090 02 81 80 28 98 fe c7 68 6d bf ae 31 27 81 34 09
00000a0 38 f3 65 0b 2c f6 7d 1e d2 7e aa 77 e9 a1 d2 b0
00000b0 63 6f d4 ce 89 17 bf 08 94 f4 67 a3 ac ce 84 3e
00000c0 48 f1 8a 32 3e 17 a0 73 98 98 96 4b 95 36 eb 56
00000d0 0c d5 53 f5 e0 30 5b b3 f7 62 03 3e 16 92 69 f1
00000e0 e9 93 5e 37 05 5b ba 7d cd 07 be df 8a 21 f5 2a
00000f0 b6 3d 21 48 72 27 5b 5b 48 09 04 40 dc e2 68 50
0000100 35 93 35 33 5b 0f e8 8d 43 1f ba 4f 9d c0 19 8d
0000110 e7 66 91 02 41 00 e0 81 c9 23 0d 82 81 f5 20 c1
0000120 f2 d1 b8 a2 20 b7 1f fa c7 71 6f 48 cb d7 15 28
0000130 52 2a 2b 2f b5 90 78 85 26 3b 06 69 8f 09 5a 93
0000140 6b e1 ed 31 49 a5 72 0b da 22 ec 80 89 26 45 b0
0000150 7b de 11 09 d1 35 02 41 00 c4 ed 93 dd 4f 58 34
0000160 e4 28 a8 eb 78 0e 0c d4 44 29 73 26 d6 c3 d6 55
0000170 e6 71 be 4c 3c a9 0b c5 c8 01 3f 31 95 a2 bd b5
0000180 d7 db c2 80 69 8c 93 f9 f5 eb 6b f2 b3 96 07 7e
0000190 2c 5e 83 c5 cb 20 d7 d1 f7 02 40 3f a8 ad 76 d2
00001a0 02 da 84 be 48 20 69 15 38 6b 9c 61 66 03 9d 87
00001b0 97 95 ad 24 23 ad c0 a5 44 3e f0 7b 2c 0e 1e 18
00001c0 80 5f fd a0 00 43 4b e9 ac db 1c 1d 8d 7c ca 00
00001d0 53 a6 10 03 1c ba d2 c9 f4 05 ad 02 40 76 eb 61
00001e0 17 8c 0a a0 26 07 c7 ba 2a 4d 91 c1 bd 47 aa 9a
00001f0 11 a7 41 8f ae 11 91 f1 47 d0 6d a3 8a 1b f6 a5
0000200 62 cf 5b f0 ab e1 b1 9b 0a 22 32 5a 07 ff 9a b8
0000210 7d 6a 64 2b f5 6f 3d f3 fb ae 61 a6 11 02 41 00
0000220 87 61 c1 63 4e 84 89 a5 fb a6 d2 dc cc 4b c0 59
0000230 25 c1 60 0b 07 36 4c bc e2 96 7c a4 d0 f6 f0 3a
0000240 5f 6e d9 35 30 6d d2 28 f6 e4 c2 36 ea c0 fb 76
0000250 db 85 ab 6e fb 36 cf 7d f9 07 70 af 91 55 8e 78
0000260
bash# cat pkcs8.der | hexdump
0000000 30 82 02 76 02 01 00 30 0d 06 09 2a 86 48 86 f7
0000010 0d 01 01 01 05 00 04 82 02 60 30 82 02 5c 02 01
0000020 00 02 81 81 00 ac b3 b7 d2 a7 ea 99 68 00 a0 5b
0000030 ea c5 4a d1 ce 0f 1f 19 ec 7a f5 6c 53 31 9e a7
0000040 5e eb 54 a6 70 5e 9d 6e e7 3f 0b 59 60 25 8f c5
0000050 ca b4 cf c6 5b b8 c0 63 69 4e 15 67 d6 53 df bd
0000060 02 82 36 7e 3d da 47 7c 92 5d 3c eb 77 e1 53 7a
0000070 e4 fb bf f5 f1 1f ae 40 2a e9 b3 3f 51 1b 3d 73
0000080 49 29 91 1f 69 b7 8a 0c 33 35 a7 e3 8a ef 6f 00
0000090 9e de 99 9e 50 99 31 88 1a a0 1a a3 ad b0 ef 06
00000a0 97 c7 c8 1f 23 02 03 01 00 01 02 81 80 28 98 fe
00000b0 c7 68 6d bf ae 31 27 81 34 09 38 f3 65 0b 2c f6
00000c0 7d 1e d2 7e aa 77 e9 a1 d2 b0 63 6f d4 ce 89 17
00000d0 bf 08 94 f4 67 a3 ac ce 84 3e 48 f1 8a 32 3e 17
00000e0 a0 73 98 98 96 4b 95 36 eb 56 0c d5 53 f5 e0 30
00000f0 5b b3 f7 62 03 3e 16 92 69 f1 e9 93 5e 37 05 5b
0000100 ba 7d cd 07 be df 8a 21 f5 2a b6 3d 21 48 72 27
0000110 5b 5b 48 09 04 40 dc e2 68 50 35 93 35 33 5b 0f
0000120 e8 8d 43 1f ba 4f 9d c0 19 8d e7 66 91 02 41 00
0000130 e0 81 c9 23 0d 82 81 f5 20 c1 f2 d1 b8 a2 20 b7
0000140 1f fa c7 71 6f 48 cb d7 15 28 52 2a 2b 2f b5 90
0000150 78 85 26 3b 06 69 8f 09 5a 93 6b e1 ed 31 49 a5
0000160 72 0b da 22 ec 80 89 26 45 b0 7b de 11 09 d1 35
0000170 02 41 00 c4 ed 93 dd 4f 58 34 e4 28 a8 eb 78 0e
0000180 0c d4 44 29 73 26 d6 c3 d6 55 e6 71 be 4c 3c a9
0000190 0b c5 c8 01 3f 31 95 a2 bd b5 d7 db c2 80 69 8c
00001a0 93 f9 f5 eb 6b f2 b3 96 07 7e 2c 5e 83 c5 cb 20
00001b0 d7 d1 f7 02 40 3f a8 ad 76 d2 02 da 84 be 48 20
00001c0 69 15 38 6b 9c 61 66 03 9d 87 97 95 ad 24 23 ad
00001d0 c0 a5 44 3e f0 7b 2c 0e 1e 18 80 5f fd a0 00 43
00001e0 4b e9 ac db 1c 1d 8d 7c ca 00 53 a6 10 03 1c ba
00001f0 d2 c9 f4 05 ad 02 40 76 eb 61 17 8c 0a a0 26 07
0000200 c7 ba 2a 4d 91 c1 bd 47 aa 9a 11 a7 41 8f ae 11
0000210 91 f1 47 d0 6d a3 8a 1b f6 a5 62 cf 5b f0 ab e1
0000220 b1 9b 0a 22 32 5a 07 ff 9a b8 7d 6a 64 2b f5 6f
0000230 3d f3 fb ae 61 a6 11 02 41 00 87 61 c1 63 4e 84
0000240 89 a5 fb a6 d2 dc cc 4b c0 59 25 c1 60 0b 07 36
0000250 4c bc e2 96 7c a4 d0 f6 f0 3a 5f 6e d9 35 30 6d
0000260 d2 28 f6 e4 c2 36 ea c0 fb 76 db 85 ab 6e fb 36
0000270 cf 7d f9 07 70 af 91 55 8e 78
000027a

此时如果从后往前看的话,其实可以发现PKCS8仅比PKCS1多了一个26自己的头,剩余的内容均完全一致。
我们可以使用以下的命令进行验证:

bash# openssl asn1parse -i -in pkcs8.der -inform DER0:d=0  hl=4 l= 630 cons: SEQUENCE4:d=1  hl=2 l=   1 prim:  INTEGER           :007:d=1  hl=2 l=  13 cons:  SEQUENCE9:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption20:d=2  hl=2 l=   0 prim:   NULL22:d=1  hl=4 l= 608 prim:  OCTET STRING      [HEX DUMP]:3082025C02010002818100ACB3B7D2A7EA996800A05BEAC54AD1CE0F1F19EC7AF56C53319EA75EEB54A6705E9D6EE73F0B5960258FC5CAB4CFC65BB8C063694E1567D653DFBD0282367E3DDA477C925D3CEB77E1537AE4FBBFF5F11FAE402AE9B33F511B3D734929911F69B78A0C3335A7E38AEF6F009EDE999E509931881AA01AA3ADB0EF0697C7C81F2302030100010281802898FEC7686DBFAE312781340938F3650B2CF67D1ED27EAA77E9A1D2B0636FD4CE8917BF0894F467A3ACCE843E48F18A323E17A0739898964B9536EB560CD553F5E0305BB3F762033E169269F1E9935E37055BBA7DCD07BEDF8A21F52AB63D214872275B5B48090440DCE26850359335335B0FE88D431FBA4F9DC0198DE76691024100E081C9230D8281F520C1F2D1B8A220B71FFAC7716F48CBD71528522A2B2FB5907885263B06698F095A936BE1ED3149A5720BDA22EC80892645B07BDE1109D135024100C4ED93DD4F5834E428A8EB780E0CD444297326D6C3D655E671BE4C3CA90BC5C8013F3195A2BDB5D7DBC280698C93F9F5EB6BF2B396077E2C5E83C5CB20D7D1F702403FA8AD76D202DA84BE48206915386B9C6166039D879795AD2423ADC0A5443EF07B2C0E1E18805FFDA000434BE9ACDB1C1D8D7CCA0053A610031CBAD2C9F405AD024076EB61178C0AA02607C7BA2A4D91C1BD47AA9A11A7418FAE1191F147D06DA38A1BF6A562CF5BF0ABE1B19B0A22325A07FF9AB87D6A642BF56F3DF3FBAE61A6110241008761C1634E8489A5FBA6D2DCCC4BC05925C1600B07364CBCE2967CA4D0F6F03A5F6ED935306DD228F6E4C236EAC0FB76DB85AB6EFB36CF7DF90770AF91558E78

可以看到 22:d=1 hl=4 l= 608 prim: OCTET STRING 这一行的输出就是pkcs1.der的内容。而上面的内容就是pkcs8比pkcs1多的内容。其实最主要的就是算法信息,这也是pkcs8能存储各种算法私钥的原因。

总结

从时间顺序上可以看出来,PKCS标准也是在不断发展的,PKCS1的标准是先于PKCS8出来的,那时候甚至非对称算法还只有RSA是成熟的,在计算机领域刚刚得到应用,PKCS专门将RSA的算法作为一个标准输出就不难理解了。随着加密算法的发展才有了PKCS8出来专门做存储密钥这样一件事情。

小知识:关于PEM与DER格式

PEM与DER有什么区别呢?其实PEM就是对DER的内容做了base64的编码并做了一下格式化的输出而已。
DER格式的存储使用了一种叫asn1的数据存储格式来存储各个数据项。我们可以看一下pkcs1.der的输出:

bash# openssl asn1parse -i -in pkcs1.der -inform DER0:d=0  hl=4 l= 604 cons: SEQUENCE4:d=1  hl=2 l=   1 prim:  INTEGER           :007:d=1  hl=3 l= 129 prim:  INTEGER           :ACB3B7D2A7EA996800A05BEAC54AD1CE0F1F19EC7AF56C53319EA75EEB54A6705E9D6EE73F0B5960258FC5CAB4CFC65BB8C063694E1567D653DFBD0282367E3DDA477C925D3CEB77E1537AE4FBBFF5F11FAE402AE9B33F511B3D734929911F69B78A0C3335A7E38AEF6F009EDE999E509931881AA01AA3ADB0EF0697C7C81F23139:d=1  hl=2 l=   3 prim:  INTEGER           :010001144:d=1  hl=3 l= 128 prim:  INTEGER           :2898FEC7686DBFAE312781340938F3650B2CF67D1ED27EAA77E9A1D2B0636FD4CE8917BF0894F467A3ACCE843E48F18A323E17A0739898964B9536EB560CD553F5E0305BB3F762033E169269F1E9935E37055BBA7DCD07BEDF8A21F52AB63D214872275B5B48090440DCE26850359335335B0FE88D431FBA4F9DC0198DE76691275:d=1  hl=2 l=  65 prim:  INTEGER           :E081C9230D8281F520C1F2D1B8A220B71FFAC7716F48CBD71528522A2B2FB5907885263B06698F095A936BE1ED3149A5720BDA22EC80892645B07BDE1109D135342:d=1  hl=2 l=  65 prim:  INTEGER           :C4ED93DD4F5834E428A8EB780E0CD444297326D6C3D655E671BE4C3CA90BC5C8013F3195A2BDB5D7DBC280698C93F9F5EB6BF2B396077E2C5E83C5CB20D7D1F7409:d=1  hl=2 l=  64 prim:  INTEGER           :3FA8AD76D202DA84BE48206915386B9C6166039D879795AD2423ADC0A5443EF07B2C0E1E18805FFDA000434BE9ACDB1C1D8D7CCA0053A610031CBAD2C9F405AD475:d=1  hl=2 l=  64 prim:  INTEGER           :76EB61178C0AA02607C7BA2A4D91C1BD47AA9A11A7418FAE1191F147D06DA38A1BF6A562CF5BF0ABE1B19B0A22325A07FF9AB87D6A642BF56F3DF3FBAE61A611541:d=1  hl=2 l=  65 prim:  INTEGER           :8761C1634E8489A5FBA6D2DCCC4BC05925C1600B07364CBCE2967CA4D0F6F03A5F6ED935306DD228F6E4C236EAC0FB76DB85AB6EFB36CF7DF90770AF91558E78

里面讲RSA私钥的所有数据都输出了。

<四> PEM格式的公私钥转换成16进制

转自:https://blog.csdn.net/zh852/article/details/53097720

在一些情况下,我们需要将公私钥由pem格式转换成十六进制来提供给第三方进行使用,openssl没有提供命令行的转换方式,其中实现接口如下:

私钥转换为16进制为:

bool ConvertPriPEMtoHex(const std::string& pem_private_key, std::string& HexKey)
{EVP_PKEY *pri_key = NULL;BIO *bio_private_key = NULL;bio_private_key = BIO_new_mem_buf((char*)pem_private_key.c_str(), pem_private_key.size());PEM_read_bio_PrivateKey(bio_private_key, &pri_key, NULL, NULL);EC_KEY *ec_key = pri_key->pkey.ec;if (!ec_key)return false;BIGNUM *private_key;private_key = BN_new();private_key = (BIGNUM*)EC_KEY_get0_private_key(ec_key);HexKey = BN_bn2hex(private_key);BN_free(private_key);BIO_free(bio_private_key);return true;
}

公钥转换为16进制如下:

bool ConvertPubPEMtoHex(const std::string& pem_public_key, std::string& HexKey)
{EVP_PKEY *pri_key = NULL;BIO *bio_cert = NULL;X509 *encrypt_cert = NULL;EVP_PKEY *key = NULL;bio_cert = BIO_new_mem_buf((char *)pem_public_key.c_str(), pem_public_key.size());PEM_read_bio_X509(bio_cert, &encrypt_cert, NULL, NULL);if (!encrypt_cert)return false;key = X509_get_pubkey(encrypt_cert);if (!key)return false;EC_KEY *ec_key = key->pkey.ec;if (!ec_key)return false;EC_POINT *pub_key;unsigned char pubbuf[1024] = { 0 };pub_key = (EC_POINT*)EC_KEY_get0_public_key(ec_key);EC_GROUP* group = (EC_GROUP*)EC_KEY_get0_group(ec_key);int buflen = EC_POINT_point2oct(group, pub_key, EC_KEY_get_conv_form(ec_key), pubbuf, sizeof(pubbuf), NULL);BIGNUM *pub_key_BIGNUM;pub_key_BIGNUM = BN_new();BN_bin2bn(pubbuf, buflen, pub_key_BIGNUM);HexKey = BN_bn2hex(pub_key_BIGNUM);BN_free(pub_key_BIGNUM);BIO_free(bio_cert);return true;
}

《5》16进制的公钥转 openssl RSA数据结构

网上的都是读pem文件,进行加解密的,而我们实际工作中,传递的密钥可能是RSA 16进制表示的,而我们加解密需要转到 openssl的RSA结构。下面是我自己实现的转换函数。

///
//函数参数:
//入参:pPublicKey:公钥;
//入参:nKeyLen:公钥长度;
//入参:pExponent:公钥指数;
//入参:nExplen:指数长度;
//入参/出参:rsa:返回RSA的指针,加密解密用,调用者负责释放内存
//入参/出参:bne设置模数,调用者负责释放内存
//入参/出参:bnn设置公钥,调用者负责释放内存
bool ConvertPubKeyToRSA(char *pPublicKey, int nKeyLen, char *pExponent, int nExplen, RSA* &rsa, BIGNUM* &bne, BIGNUM * &bnn)
{if (bne == NULL || bnn == NULL || rsa == NULL){return false;}int AsiiLen = nKeyLen * 2;unsigned char * AsiiKey = new unsigned char[AsiiLen];memset(AsiiKey, 0, AsiiLen);//16进制转Asii码Bin2HexAscii((unsigned char *)pPublicKey, nKeyLen, (unsigned char *)AsiiKey, AsiiLen, true);unsigned long e = 0;for (int i = 0; i < nExplen; i++){e += (pExponent[i] << 8*(nExplen - i-1));}/* 设置模数 */BN_set_word(bne, e);BN_hex2bn(&bnn, (const char*)AsiiKey);//给rsa赋值int ret = RSA_set0_key(rsa, bnn, bne, NULL);if (ret ==1){delete[]AsiiKey;return true;}else{delete[]AsiiKey;return false;}}

10. hisi平台签名与验签注意事项

注意:HI_UNF_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA256 这个签名算法就是sha256withrsa算法。

签名时:先要对待签名的字符串做sha256,生成摘要信息;然后使用rsa的私钥对摘要信息进行签名,在海思上就能验签了。

int sample_rsa_sign(HI_VOID)
{HI_S32 s32Ret = HI_SUCCESS;s32Ret = RSA_SIGN_VERIFY(HI_UNF_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA256);if (s32Ret != HI_SUCCESS){return s32Ret;}s32Ret = RSA_SIGN_VERIFY(HI_UNF_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA256);if (s32Ret != HI_SUCCESS){return s32Ret;}return HI_SUCCESS;
}

static HI_S32 RSA_SIGN_VERIFY(HI_UNF_CIPHER_RSA_SIGN_SCHEME_E enScheme)
{HI_S32 ret = HI_SUCCESS;HI_U8  u8Sign[256];HI_U32 u32SignLen;HI_UNF_CIPHER_RSA_SIGN_S stRsaSign;HI_UNF_CIPHER_RSA_VERIFY_S stRsaVerify;ret = HI_UNF_CIPHER_Init();if ( HI_SUCCESS != ret ){return HI_FAILURE;}memset(&stRsaSign, 0, sizeof(HI_UNF_CIPHER_RSA_SIGN_S));stRsaSign.enScheme = enScheme;stRsaSign.stPriKey.pu8N = N;stRsaSign.stPriKey.pu8D = D;stRsaSign.stPriKey.u16NLen = sizeof(N);stRsaSign.stPriKey.u16DLen = sizeof(D);ret = HI_UNF_CIPHER_RsaSign(&stRsaSign, test_data, sizeof(test_data) - 1, sha256_sum, u8Sign, &u32SignLen);
//  ret = HI_UNF_CIPHER_RsaSign(&stRsaSign, test_data, sizeof(test_data) - 1, HI_NULL, u8Sign, &u32SignLen);if ( HI_SUCCESS != ret ){HI_ERR_CIPHER("HI_UNF_CIPHER_RsaSign failed\n");return HI_FAILURE;}switch(enScheme){case HI_UNF_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA256:if(memcmp(u8Sign, RES, sizeof(RES)) != 0){HI_ERR_CIPHER("HI_UNF_CIPHER_RsaSign failed\n");printBuffer("sign", u8Sign, u32SignLen);printBuffer("golden", RES, sizeof(RES));return HI_FAILURE;}break;default:break;}//    printBuffer("sign", u8Sign, u32SignLen);memset(&stRsaVerify, 0, sizeof(HI_UNF_CIPHER_RSA_VERIFY_S));stRsaVerify.enScheme = enScheme;stRsaVerify.stPubKey.pu8N = N;stRsaVerify.stPubKey.pu8E = E;stRsaVerify.stPubKey.u16NLen = sizeof(N);stRsaVerify.stPubKey.u16ELen = sizeof(E);//  ret = HI_UNF_CIPHER_RsaVerify(&stRsaVerify, test_data, sizeof(test_data) - 1, HI_NULL, u8Sign, u32SignLen);ret = HI_UNF_CIPHER_RsaVerify(&stRsaVerify, test_data, sizeof(test_data) - 1, sha256_sum, u8Sign, u32SignLen);if ( HI_SUCCESS != ret ){HI_ERR_CIPHER("HI_UNF_CIPHER_RsaVerify failed\n");return HI_FAILURE;}TEST_END_PASS();HI_UNF_CIPHER_DeInit();return HI_SUCCESS;
}

12. PKCS1和PKCS8类型的公私钥对

openssl默认生成的是PKCS1类型的公私钥对,生成的函数如下:


///
//生成RSA key --生成PKCS1类型的公钥,Java默认的是 PKCS8类型的公私钥
bool MakeRsaKeySSL(const char *savePrivateKeyFilePath, const  char *savePublicKeyFilePath) {int             ret = 0;RSA             *r = NULL;BIGNUM          *bne = NULL;BIO             *bp_public = NULL, *bp_private = NULL;int             bits = 2048;unsigned long   e = RSA_F4;// 1. generate rsa keybne = BN_new();ret = BN_set_word(bne, e);if (ret != 1) {fprintf(stderr, "MakeLocalKeySSL BN_set_word err \n");goto free_all;}r = RSA_new();ret = RSA_generate_key_ex(r, bits, bne, NULL);if (ret != 1) {fprintf(stderr, "MakeLocalKeySSL RSA_generate_key_ex err \n");goto free_all;}// 2. save public keyif (savePublicKeyFilePath != NULL) {bp_public = BIO_new_file(savePublicKeyFilePath, "w+");ret = PEM_write_bio_RSAPublicKey(bp_public, r);if (ret != 1) {fprintf(stderr, "MakeLocalKeySSL PEM_write_bio_RSAPublicKey err \n");goto free_all;}}// 3. save private keyif (savePrivateKeyFilePath != NULL) {bp_private = BIO_new_file(savePrivateKeyFilePath, "w+");ret = PEM_write_bio_RSAPrivateKey(bp_private, r, NULL, NULL, 0, NULL, NULL);}// 4. free
free_all:BIO_free_all(bp_public);BIO_free_all(bp_private);RSA_free(r);BN_free(bne);return (ret == 1);
}/

openssl库编译-及16进制的key转Rsa数据结构相关推荐

  1. STM32串口发送16进制数据

    方法一(用printf函数) 下面演示两个示例 //说明:用u8或unsigned char都能正常发送//示例 1 u8 send1=0x55; printf("%c",send ...

  2. MFC中将用户输入的表示16进制数的字符串转换成16进制数输出显示(包含1.wstring转成string的方法函数2.用boost库拆分字符串的函数3.字符转16进制数值的函数)

    前期准备: 1.电脑中安装好boost库,我的电脑中安装在C盘根目录下,如下图所示: 2.配置好boost环境变量,如下图所示: 3.开发环境VS2015,工程为MFC应用程序 需要的头文件如下: # ...

  3. openssl sha1 16进制数据

    在线计算sha1工具一般只支持字符串计算杂凑值,利用openssl 计算任意数据杂凑值 利用openssl计算16进制数据(0102030405060708)sha1值. echo -en " ...

  4. C语言实现ASCII字符、压缩BCD码值与BIN码(16进制)互转 - (已编译,亲试可用)

    目录 1.将压缩BCD码转为BIN码 2.将压缩BCD码数组转为BIN码数组 3.将BIN码转为压缩BCD码 4.将BIN码数组转为压缩BCD码数组 5.将ASCII码转为BIN码 6.将ASCII码 ...

  5. 火焰纹章16进制是怎么算_火焰是值得你的时间

    火焰纹章16进制是怎么算 Back in September, Microsoft released .NET Core 3 to much (deserved) fanfare. Included ...

  6. 计算机十六进制4BH表示多大,【转】windows消息16进制对应表

    windows mobile编程,无论使用eVC还是.net CF,都脱不开windows消息机制这个框架.在日常的程序编写过程中,windows消息也是很常用的,windows消息常用的api函数也 ...

  7. linux socket接收不到16进制数据,C下通过socket收发十六进制数据解决办法

    C下通过socket收发十六进制数据 系统是在LINUX下,下位机发送十六进制数据过来 上位机怎么解析 把数据以十六进制的形式显示出来,发送十六进制又如何实现 ------解决方案---------- ...

  8. java php des加密 byte数组16进制 DESTools

    大家好,我是烤鸭: 今天分享的是java 和 php des 加密. 因为接口对接,难免不同语言,加密又是必不可少的. 作为接口的提供方,必须把加密规则写好,最好有不同语言的加密demo. 1.    ...

  9. 8位16进制频率计设计实验--VHDL

    一.实验目的 (1)学习并掌握Quartus II的使用方法 (2)学习简单时序电路的设计和硬件测试. (3)学习使用VHDL 语言方法进行逻辑设计输入 (4)学习设计8位16进制频率计,学习较复杂的 ...

最新文章

  1. ashx导出dataTable为Excel
  2. defaultdict python_Python使用defaultdict读取文件各列的方法
  3. openshift_Openshift源中的高可用性Drools无状态服务
  4. 《SQL高级应用和数据仓库基础(MySQL版)》作业 ·007
  5. 评课用计算器计算机,《用计算器计算》教学反思
  6. Centos安装Clion
  7. HTML+JS实现可编辑表格
  8. 6.exports、module.exports、export、export defalut
  9. 浏览器插件检测淘宝订单是否淘客下单
  10. AAAI 2020对抗样本论文
  11. Jdon框架(JdonFramework)应用系统
  12. 转:用迅雷下载Android SDK全系列
  13. 渣基础:比照Hawstein学Cracking the coding interview(4)
  14. HTML基础(六)---列表和表单标签
  15. 【SSH】MyEclipse卸载干净的方法
  16. Mimicking Very Efficient Network for Object Detection
  17. 如何获取iOS 设备的 UDID
  18. 就业技术书文件表格_毕业生就业协议书表格范本
  19. 骁龙780G​和骁龙888哪个好 高通骁龙780G​和骁龙888区别参数对比
  20. create-react-app项目打包后遇到问题

热门文章

  1. 【Python】如何对列表进行减法操作?
  2. 数据分析里常用的五个统计学概念,你知道几个?
  3. imageNet 的 top1-error和 top5-accuracy
  4. 未来8亿人或被AI无情替代,美国这家创业公司能当好“救火队长”?
  5. Kubernetes 工作实践内容总结-收藏版
  6. vue项目使用高德地图的定位及关键字搜索功能
  7. oracle数据库数值函数,五、oracle数据库常用函数
  8. 我的新工具计算机教案,三年级上册信息技术教案-第1课 我的新工具——计算机丨冀教版 (1)...
  9. 上海线下沙龙|与专家面对面,畅聊如何打造高效能研发团队
  10. Android GreenDao框架使用 基础篇