我需要使用 RSA 和小模數為 CTF 挑戰生成弱證書,因此它是可分解的。它應該是大約 64 位。
我嘗試使用 OpenSSL 來生成它,但出于安全原因,它禁止創建模數低于 512 位的證書。因此,我更改了 OpenSSL 的源檔案,因此它不會檢查位長度并再次重新編譯。然后我能夠使用較小的模數創建私鑰,但嘗試使用該密鑰(或新的小密鑰)創建證書會引發我不完全理解的新錯誤。我什至想用 Python 完全避開 OpenSSL 問題,但這只是表明它也使用了 OpenSSL 并且存在完全相同的問題。
生成小私鑰:
$ openssl genrsa -out acn.pem 64
-----BEGIN PRIVATE KEY-----
MFQCAQAwDQYJKoZIhvcNAQEBBQAEQDA AgEAAgkAlz0xJ3uUx5UCAwEAAQIIR1Zs
1Wo4EQECBQDHPJNVAgUAwlPjQQIFAKqNunkCBClt4QECBHlHx1Q=
-----END PRIVATE KEY-----
生成證書:
$ openssl req -key acn.pem -new -out domain.csr
...
140561480598848:error:04075070:rsa routines:RSA_sign:digest too big for rsa key:../crypto/rsa/rsa_sign.c:100:
140561480598848:error:0D0DC006:asn1 encoding routines:ASN1_item_sign_ctx:EVP lib:../crypto/asn1/a_sign.c:224:
我發現這個執行緒可能會有所幫助,因為我什至可以選擇自己的數字,但該方法對我不起作用:
如何使用 openssl 中的特定輸入數字生成 rsa 密鑰?
這是來自 PicoCTF 的示例證書。我想創建一個類似的。
-----BEGIN CERTIFICATE-----
MIIB6zCB1AICMDkwDQYJKoZIhvcNAQECBQAwEjEQMA4GA1UEAxMHUGljb0NURjAe
Fw0xOTA3MDgwNzIxMThaFw0xOTA2MjYxNzM0MzhaMGcxEDAOBgNVBAsTB1BpY29D
VEYxEDAOBgNVBAoTB1BpY29DVEYxEDAOBgNVBAcTB1BpY29DVEYxEDAOBgNVBAgT
B1BpY29DVEYxCzAJBgNVBAYTAlVTMRAwDgYDVQQDEwdQaWNvQ1RGMCIwDQYJKoZI
hvcNAQEBBQADEQAwDgIHEaTUUhKxfwIDAQABMA0GCSqGSIb3DQEBAgUAA4IBAQAH
al1hMsGeBb3rd/Oq 7uDguueopOvDC864hrpdGubgtjv/hrIsph7FtxM2B4rkkyA
eIV708y31HIplCLruxFdspqvfGvLsCynkYfsY70i6I/dOA6l4Qq/NdmkPDx7edqO
T/zK4jhnRafebqJucXFH8Ak G6ASNRWhKfFZJTWj5CoyTMIutLU9lDiTXng3rDU1
BhXg04ei1jvAf0UrtpeOA6jUyeCLaKDFRbrOm35xI79r28yO8ng1UAzTRclvkORt
b8LMxw7e vdIntBGqf7T25PLn/MycGPPvNXyIsTzvvY/MXXJHnAqpI5DlqwzbRHz
q16/S1WLvzg4PsElmv1f
-----END CERTIFICATE-----
uj5u.com熱心網友回復:
我需要使用 RSA 和小模數為 CTF 挑戰生成弱證書,因此它是可分解的。它應該是大約 64 位。
作為自簽名證書不可能做到這一點,因為正確的 RSA 簽名不能使用這么小的密鑰。
RSA-SSA-PKCS1_v1.5 是最短的結構化 RSA 簽名填充,其結構如下(根據https://datatracker.ietf.org/doc/html/rfc8017#section-9.2):
DigestInfo ::= SEQUENCE {
digestAlgorithm AlgorithmIdentifier,
digest OCTET STRING
}
該結構的最短可能編碼是 9 位元組......這是使用 0 位元組哈希演算法:
30 07 // SEQUENCE (7 content bytes)
30 03 // digestAlgorithm: SEQUENCE (3 bytes)
06 01 00 // OBJECT IDENTIFIER 0.0 ({itu-t(0) recommendation(0)})
// omit implicit NULL
04 00 // digest (empty)
因此,使用我們的空哈希,我們需要繼續:
- 如果 emLen < tLen 11,則輸出“預期編碼訊息長度太短”并停止。
emLen是模數的長度(以位元組為單位),tLen是我們編碼結構的長度(9 個位元組 )。
這使得 20 位元組(160 位)成為最短的 RSA 密鑰,可以做任何可能被視為 RSA 簽名的事情......這會產生一個毫無意義的簽名(因為一切都在 0 位哈希下發生沖突)。
如果您愿意為您的 CTF 使用 1 位元組 OID,則您的 RSA 密鑰模數需要為 20 位元組 預期哈希的長度(以位元組為單位)。由于沒有標識現有哈希演算法的 1 位元組 OID(并且沒有定義的哈希演算法用于這么小的證書),因此沒有現有的易于使用的工具可以為您做到這一點。
當然,您可以發明一種新形式的 RSA 簽名填充,使用類似 64 位密鑰直接處理的 60 位散列。這將需要您做進一步的作業。
您基本上只能使用 DER 撰寫器(或自己撰寫)來手工制作證書。
這是來自 PicoCTF 的示例證書。我想創建一個類似的。
該證書不是自簽名的。它具有 2048 位證書簽名,來自 RSA-SSA-PKCS1_v1.5 和 MD2。因此,雖然它描述了一個簡短的 RSA 密鑰(53 位模數),但它是用“正確”的東西簽名的。如果這就是您所追求的,那么一般流程將類似于
- 創建一個普通的自簽名證書
- 創建您的小型 RSA 密鑰
- 建立一個新的證書,由第一個證書簽名,包含小的 RSA 密鑰。
It's hard to encode a CSR for the small key (because it can't self-sign the request), but maybe there's a way to get openssl req -new to do something other than self-sign, which would allow skipping the intermediate CSR. (Or use library tools like .NET's CertificateRequest, or OpenSSL's APIs instead of their CLI tool, or whatever.)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/457757.html
