RSA加密解密中pkcs1與pkcs8格式私鑰互相轉換


net,ios中rsa加解密使用的是pkcs1,而java使用的是pkcs8

如果是按1024取模(通常都是1024),pkcs1格式的私鑰長度應該是812。如果是pkcs8的格式的密鑰長度為861。

下載安裝openssl:https://pan.baidu.com/s/1ggQJIIR

我這邊使用的是Win64OpenSSL_Light-1_1_0g.exe

PKCS1私鑰生成:

OpenSSL> genrsa -out pkcs1_private.pem 1024
Generating RSA private key, 1024 bit long modulus
.........++++++
.............................++++++
e is 65537 (0x10001)

內容:

-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCYMTaH4NMw5fQsgx3pv8xaAxhOdtUz/m5nfl9XHtGboXNzUzx/
ehh8c3RgpGcig83JXOYOXafmx3OS28Ed3e2fmC5Yo5RD6DRHnBCid28EjQ5PgCTd
dNqDvcXU3YMH4sO1qNBx5MQpk92Kt/NdquIJmzhgpjP15MO5CFHcU90ZvQIDAQAB
AoGANlvdjkrPI/f+bqemV4caBkx0shHftOJ7rJuGkid/1oakJdzlDuMdO9ZBCwOt
krZhGjsEML1i6xryPNIg9/n8lSdQqIUW61HXYwKUK5xQWz/MstWbbIx3t5driQFR
Fv53NLdemeF/0AJiD5COO1fkoM+1By2LlI0ths8cQLcOpgECQQDIc46yV1N5IuS0
MYD0LgggaJ08WF0PrwjXgs+DRp3+ZE5WTs1JDkBQM9E598xbmy7AAFtdtR3L5CH8
5Qh+KfwJAkEAwl4MuRMdIjiHiw1YoIUliy6t3XPvxeOEiG/P15adKrxI5A5QylM0
TtbZT3YZurdy3nrJ75LxuU9cSYKzxtVFFQJAMboJElD7kjeHyPPm66xns7KAHzJE
k9l2NhBrbkOcejlj/aE65/6zEbJpGxpQBgGvTU5JXCvMIoKLs/MVckb0EQJASze+
ULkW4zFhMuy9SZF9T/mGi1bciYZcubgbhODifbFTu/3WQhYk/gWjH18i4eEwcOyv
zSjepsoRetk73UyXaQJAOfr3Gg1dGvoLiwZ3fXoDVupahnKg73SAd72+24qQs2AT
16T8FKop259xisLu+WSUTfSUhao5qOpZJ/PTwFRlzw==
-----END RSA PRIVATE KEY-----

PKCS1私鑰轉換為PKCS8(該格式一般Java調用)

OpenSSL>  pkcs8 -topk8 -inform PEM -in pkcs1_private.pem -outform pem -nocrypt -out pkcs8_private.pem

內容:

-----BEGIN PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJgxNofg0zDl9CyD
Hem/zFoDGE521TP+bmd+X1ce0Zuhc3NTPH96GHxzdGCkZyKDzclc5g5dp+bHc5Lb
wR3d7Z+YLlijlEPoNEecEKJ3bwSNDk+AJN102oO9xdTdgwfiw7Wo0HHkxCmT3Yq3
812q4gmbOGCmM/Xkw7kIUdxT3Rm9AgMBAAECgYA2W92OSs8j9/5up6ZXhxoGTHSy
Ed+04nusm4aSJ3/WhqQl3OUO4x071kELA62StmEaOwQwvWLrGvI80iD3+fyVJ1Co
hRbrUddjApQrnFBbP8yy1ZtsjHe3l2uJAVEW/nc0t16Z4X/QAmIPkI47V+Sgz7UH
LYuUjS2GzxxAtw6mAQJBAMhzjrJXU3ki5LQxgPQuCCBonTxYXQ+vCNeCz4NGnf5k
TlZOzUkOQFAz0Tn3zFubLsAAW121HcvkIfzlCH4p/AkCQQDCXgy5Ex0iOIeLDVig
hSWLLq3dc+/F44SIb8/Xlp0qvEjkDlDKUzRO1tlPdhm6t3LeesnvkvG5T1xJgrPG
1UUVAkAxugkSUPuSN4fI8+brrGezsoAfMkST2XY2EGtuQ5x6OWP9oTrn/rMRsmkb
GlAGAa9NTklcK8wigouz8xVyRvQRAkBLN75QuRbjMWEy7L1JkX1P+YaLVtyJhly5
uBuE4OJ9sVO7/dZCFiT+BaMfXyLh4TBw7K/NKN6myhF62TvdTJdpAkA5+vcaDV0a
+guLBnd9egNW6lqGcqDvdIB3vb7bipCzYBPXpPwUqinbn3GKwu75ZJRN9JSFqjmo
6lkn89PAVGXP
-----END PRIVATE KEY-----

生成公鑰:

PKCS1的私鑰生成公鑰:

OpenSSL> rsa -in pkcs1_private.pem -pubout -out pkcs1_public.pem
writing RSA key

內容:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYMTaH4NMw5fQsgx3pv8xaAxhO
dtUz/m5nfl9XHtGboXNzUzx/ehh8c3RgpGcig83JXOYOXafmx3OS28Ed3e2fmC5Y
o5RD6DRHnBCid28EjQ5PgCTddNqDvcXU3YMH4sO1qNBx5MQpk92Kt/NdquIJmzhg
pjP15MO5CFHcU90ZvQIDAQAB
-----END PUBLIC KEY-----

PKCS8的私鑰生成公鑰:

OpenSSL> rsa -in pkcs8_private.pem -pubout -out pkcs8_public.pem
writing RSA key

內容:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYMTaH4NMw5fQsgx3pv8xaAxhO
dtUz/m5nfl9XHtGboXNzUzx/ehh8c3RgpGcig83JXOYOXafmx3OS28Ed3e2fmC5Y
o5RD6DRHnBCid28EjQ5PgCTddNqDvcXU3YMH4sO1qNBx5MQpk92Kt/NdquIJmzhg
pjP15MO5CFHcU90ZvQIDAQAB
-----END PUBLIC KEY-----

結果發現兩個公鑰都是一樣的。

下面鏈接里面有在線生產地址:http://tool.chacuo.net/cryptrsapkcs1pkcs8

上面的轉換都沒有私鑰密碼

注意:

使用rsa進行加密的時候,如果報不正常長度,那么就要進行分段加解密。

RSA加解密:

1024位的證書,加密時最大支持117個字節,解密時為128;
2048位的證書,加密時最大支持245個字節,解密時為256。

加密時支持的最大字節數:證書位數/8 -11(比如:2048位的證書,支持的最大加密字節數:2048/8 - 11 = 245)

.NET中的RSA加密算法為了提高安全性,在待加密數據前要添加一些隨機數,因此,使用.NET中的RSA加密算法一次最多加密117字節數據(多於117字節需要拆分成多段分別加密再連接起來),經過加密后得到一個長度為128字節的加密數據。

RSA實際可加密的明文長度最大也是1024bits,但問題就來了:如果小於這個長度怎么辦?就需要進行padding,因為如果沒有padding,用戶無法區分解密后內容的真實長度,字符串之類的內容問題還不大,以0作為結束符,

但對二進制數據就很難理解,因為不確定后面的0是內容還是內容結束符。只要用到padding,那么就要占用實際的明文長度,於是才有117字節的說法。
我們一般使用的padding標准有NoPPadding、OAEPPadding、PKCS1Padding等,其中PKCS#1建議的padding就占用了11個字節。
如果大於這個長度怎么辦?很多算法的padding往往是在后邊的,但PKCS的padding則是在前面的,此為有意設計,有意的把第一個字節置0以確保m的值小於n。
這樣,128字節(1024bits)
-減去11字節正好是117字節,但對於RSA加密來講,padding也是參與加密的,所以,依然按照1024bits去理解,但實際的明文只有117字節了。

在對接中使用流程:

一共有兩組四個密鑰:A的公鑰(PUB_A),A的私鑰(PRI_A);B的公鑰(PUB_B),B的私鑰(PRI_B)。
公鑰一般用來加密,私鑰用來簽名。
通常公鑰是公開出去的,但是私鑰只能自己私密持有。
公鑰和私鑰唯一對應,用某個公鑰簽名過得內容只能用對應的私鑰才能解簽驗證;同樣用某個私鑰加密的內容只能用對應的公鑰才能解密。
這時A向B發送信息的整個簽名和加密的過程如下:
1、A先用自己的私鑰(PRI_A)對信息(一般是信息的摘要)進行簽名。
2、A接着使用B的公鑰(PUB_B)對信息內容和簽名信息進行加密。
這樣當B接收到A的信息后,獲取信息內容的步驟如下:
1、用自己的私鑰(PRI_B)解密A用B的公鑰(PUB_B)加密的內容;
2、得到解密后的明文后用A的公鑰(PUB_A)解簽A用A自己的私鑰(PRI_A)的簽名。
從而整個過程就保證了開始說的端到端的唯一確認。A的簽名只有A的公鑰才能解簽,這樣B就能確認這個信息是A發來的;A的加密只有B的私鑰才能解密,這樣A就能確認這份信息只能被B讀取。

但是在我的使用過程中,發現只能公鑰加密,私鑰解密,反之則不可以,私鑰可以用來加簽,對應的公鑰可以用來驗簽。(應該是我哪里沒搞懂,所以在不能私鑰加密,公鑰解密)

現在一般對接就是

1.用對方的私鑰對消息進行加簽生成sign,再將消息message跟sign使用對方的公鑰進行加密

2.對方接收到數據以后,先用自己的私鑰進行解密,再用私鑰對解密出來的message進行加簽,與傳遞過來的sign進行對比

 

RSA只是一個加密的算法,加簽需要先對內容進行HASH然后再加密,比如SHA1WithRSA就是一個常用的RSA加簽算法。

https://www.jianshu.com/p/08e41304edab

https://www.cnblogs.com/littleatp/p/5878763.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM