RSA根據已有的公私鑰參數 E D N 求 p q invQ dp dQ,可轉pkcs#8密鑰文件格式base64編碼


前幾天領導找我要一個base64編碼的RSA密鑰(之前某個項目的),即pkcs#1或pkcs#8密鑰格式,解析密鑰格式的der編碼后,發現需要 e n d p q dQ dp invQ 共八個參數,而我只有 e n d 三個參數,一下子有點束手無策,今天突發奇想,之前在python應用rsa密碼算法時,我不也只給了 e n d 就能計算么,是否就說明我遺漏了解題的重要部分,於是,隨着這一靈感進行摸索,最終我實現了領導的需求。

准備RSA密鑰對

利用網站工具生成 RSA 密鑰對,http://web.chacuo.net/netrsakeypair

pubkey:30819f300d06092a864886f70d010101050003818d0030818902818100cd39d6697f1f09b44663065ab02fa8693e80df3cc42682494f43d48b54bd3d8b9439bfaf93f84ecd9938359f355a7e1d50e0de9144813b7402299793e11e1a8eb8ae78a62c94827fb648244aa5ebb62d6b5e1d297379147e4484bf882457404351a3791405d0d1627eff035f82fd79bf15cef4b00cfc1e92e5787937e5d3f1c70203010001
prikey:30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100cd39d6697f1f09b44663065ab02fa8693e80df3cc42682494f43d48b54bd3d8b9439bfaf93f84ecd9938359f355a7e1d50e0de9144813b7402299793e11e1a8eb8ae78a62c94827fb648244aa5ebb62d6b5e1d297379147e4484bf882457404351a3791405d0d1627eff035f82fd79bf15cef4b00cfc1e92e5787937e5d3f1c702030100010281804fed5aa833ae2ee55b146e011be533bde96ddf8397113864bcce3a1519a7aa349641f779b6335add8ff2e84f5d442521ddc1f66cb5356fa63ac1601b63ed8981a1b94f0e5295362309ecc8a698d66a491392b60984d810f3efce4803c89c391a1b22afd2bfefc41d2b4b25fde10130f50e02a069e9053c14cee7bd9d2a9a4081024100e5e8e966a5f8e0c8dea885ad5a46919694f86a25a1d6b3b2c035084ed7da37c8b45a5b75c378ecbb4b9d269deec9c1c84f67ed10a77045f6ea06346ea273c537024100e483d62eb31088135b3748b9c3df343da25325e9e9c524b2507ed13d8b8e3a1f806453af311b649faa0d28735b528cef0ad94e06baa5c08471454a3bb8877ff1024100874854c66cd51457be04c59beaa9e993049763c63f0399fb8d73e72e957eb72267555fc9dcba73fa0595341aec5e55a36b6e08a5ab10ba6a7eec25c00fe1356302406fd8ab638e17605301096d1a2769bf3b0f915cf4418c51aac945590aa39cc88c149e866b3040f51e44f04dc5308496208611d863e8c52a16690e7e07ff08ab31024006e310c6765f86e53cbf05d0db79a9e28e12c1737152650acb7963d9660193b97daf96d1e4b545d5754b8d34a708016a23399a99e1cb811d2e6f4c204ae218c6

解析 pkcs#8 得到 e n d p q u dp dq qp u

30 820276
	0201 // Version
		00
	300d // PrivateKeyAlgorithmIdentifier
		06092a864886f70d0101010500
	04820260 // PrivateKey
		3082025c
			0201
				00 
			028181 // n
				00cd39d6697f1f09b44663065ab02fa8693e80df3cc42682494f43d48b54bd3d8b9439bfaf93f84ecd9938359f355a7e1d50e0de9144813b7402299793e11e1a8eb8ae78a62c94827fb648244aa5ebb62d6b5e1d297379147e4484bf882457404351a3791405d0d1627eff035f82fd79bf15cef4b00cfc1e92e5787937e5d3f1c7
			0203 // e
				010001
			028180 // d
				4fed5aa833ae2ee55b146e011be533bde96ddf8397113864bcce3a1519a7aa349641f779b6335add8ff2e84f5d442521ddc1f66cb5356fa63ac1601b63ed8981a1b94f0e5295362309ecc8a698d66a491392b60984d810f3efce4803c89c391a1b22afd2bfefc41d2b4b25fde10130f50e02a069e9053c14cee7bd9d2a9a4081
			0241 // q
				00e5e8e966a5f8e0c8dea885ad5a46919694f86a25a1d6b3b2c035084ed7da37c8b45a5b75c378ecbb4b9d269deec9c1c84f67ed10a77045f6ea06346ea273c537
			0241 // p
				00e483d62eb31088135b3748b9c3df343da25325e9e9c524b2507ed13d8b8e3a1f806453af311b649faa0d28735b528cef0ad94e06baa5c08471454a3bb8877ff1
			0241 // dq
				00874854c66cd51457be04c59beaa9e993049763c63f0399fb8d73e72e957eb72267555fc9dcba73fa0595341aec5e55a36b6e08a5ab10ba6a7eec25c00fe13563
			0240 // dp
				6fd8ab638e17605301096d1a2769bf3b0f915cf4418c51aac945590aa39cc88c149e866b3040f51e44f04dc5308496208611d863e8c52a16690e7e07ff08ab31
			0240 // Qinv(u)
				06e310c6765f86e53cbf05d0db79a9e28e12c1737152650acb7963d9660193b97daf96d1e4b545d5754b8d34a708016a23399a99e1cb811d2e6f4c204ae218c6

根據 e n d 生成 p q u

依賴 pycrypto 庫

from Crypto.PublicKey import RSA

key_para = (int('cd39d6697f1f09b44663065ab02fa8693e80df3cc42682494f43d48b54bd3d8b9439bfaf93f84ecd9938359f355a7e1d50e0de9144813b7402299793e11e1a8eb8ae78a62c94827fb648244aa5ebb62d6b5e1d297379147e4484bf882457404351a3791405d0d1627eff035f82fd79bf15cef4b00cfc1e92e5787937e5d3f1c7', 16),
            int('010001', 16),
            int('4fed5aa833ae2ee55b146e011be533bde96ddf8397113864bcce3a1519a7aa349641f779b6335add8ff2e84f5d442521ddc1f66cb5356fa63ac1601b63ed8981a1b94f0e5295362309ecc8a698d66a491392b60984d810f3efce4803c89c391a1b22afd2bfefc41d2b4b25fde10130f50e02a069e9053c14cee7bd9d2a9a4081', 16))
a = RSA.construct(key_para)
print('p = ' + hex(a.key.p))
print('q = ' + hex(a.key.q))
print('u = ' + hex(a.key.u))

輸出結果

p = 0xe483d62eb31088135b3748b9c3df343da25325e9e9c524b2507ed13d8b8e3a1f806453af311b649faa0d28735b528cef0ad94e06baa5c08471454a3bb8877ff1
q = 0xe5e8e966a5f8e0c8dea885ad5a46919694f86a25a1d6b3b2c035084ed7da37c8b45a5b75c378ecbb4b9d269deec9c1c84f67ed10a77045f6ea06346ea273c537
u = 0x6e310c6765f86e53cbf05d0db79a9e28e12c1737152650acb7963d9660193b97daf96d1e4b545d5754b8d34a708016a23399a99e1cb811d2e6f4c204ae218c6

總結

(1)通過該接口生成 p q 后(原理后續再研究),再通過兩個公式即可生成 dp dq,這樣一來,就可以實現僅有 e d n 的情況下,組裝為 pkcs#8 格式的key文件了。

dp=d(mod(p-1))
dq=d(mod(q-1))

(2)我是屬於誤打誤撞實現的,在撰寫該文章的過程中,在谷歌搜索 rsa dp dq 發現一個名為《Key Recovery Method for CRT Implementation of RSA》的pdf文檔,在里面看到計算 dp dq 的公式,這才解決了最終的轉pkcs#8的問題,說明我在遇到問題的時候沒有先整理頭緒的習慣,這樣不好,會浪費時間,因為我能遇到的問題基本都已有前輩遇到甚至解決,在密碼學中,我遇到的問題其實是涉及了密鑰恢復的研究,之所以叫恢復而不是攻擊,是根據我是否擁有私鑰為准,沒有私鑰,那就是密鑰攻擊。


免責聲明!

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



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