ssl - 生成弱 X509 证书

标签 ssl openssl cryptography ssl-certificate x509certificate

我需要使用 RSA 和小模数为 CTF 挑战生成弱证书,因此它是可分解的。它应该是大约 64 位。
我尝试使用 OpenSSL 来生成它,但出于安全原因,它禁止创建模数低于 512 位的证书。因此,我更改了 OpenSSL 的源文件,因此它不会检查位长度并再次重新编译。然后我能够使用较小的模数创建私钥,但尝试使用该 key (或新的小 key )创建证书会引发我不完全理解的新错误。我什至想用 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:
我发现这个线程可能会有所帮助,因为我什至可以选择自己的数字,但该方法对我不起作用:
How to Generate rsa keys using specific input numbers in openssl?
这是来自 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-----

最佳答案

I need to generate weak certificate for CTF challenge using RSA and small modulus so it's factorable. It should be about 64 bits.


作为 是不可能做到的。自签证书,因为正确的 RSA 签名不能使用这么小的 key 。
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)
因此,使用我们的空哈希,我们需要继续:
  1. If emLen < tLen + 11, output "intended encoded message length too short" and stop.
emLen是模数的长度(以字节为单位),tLen是我们编码结构的长度(9 个字节+)。
这使得 20 个字节(160 位)成为最短的 RSA key ,可以做任何可能被视为 RSA 签名的事情……这会产生一个毫无意义的签名(因为一切都在 0 位哈希下发生冲突)。
如果您愿意为您的 CTF 使用 1 字节 OID,则您的 RSA key 模数需要为 20 字节 + 预期哈希的长度(以字节为单位)。由于没有标识现有哈希算法的 1 字节 OID(并且没有定义的哈希算法用于这么小的证书),因此没有现有的易于使用的工具可以为您做到这一点。

当然,您可以发明一种新形式的 RSA 签名填充,使用类似 64 位 key 直接处理的 60 位散列。这将需要您做进一步的工作。
您基本上只能使用 DER 编写器(或自己编写)来手工制作证书。

Here's sample certificate from PicoCTF. I would like to create similar one.


该证书不是自签名的。它具有 2048 位证书签名,来自 RSA-SSA-PKCS1_v1.5 和 MD2。因此,虽然它描述了一个简短的 RSA key (53 位模数),但它是用“正确”的东西签名的。如果这就是您所追求的,那么一般流程将类似于
  • 创建一个普通的自签名证书
  • 创建您的小型 RSA key
  • 建立一个新的证书,由第一个证书签名,包含小的 RSA key 。

  • 很难为小 key 编码 CSR(因为它不能对请求进行自签名),但也许有一种方法可以获得 openssl req -new做除自签名以外的其他事情,这将允许跳过中间 CSR。 (或者使用.NET 的 CertificateRequest 之类的库工具,或者 OpenSSL 的 API,而不是他们的 CLI 工具,等等。)

    关于ssl - 生成弱 X509 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71798413/

    相关文章:

    java - 使用 Cloudflare 进行 Tomcat/TomEE SSL 配置

    apache - Apache 如何使用现有的 IIS 证书?

    security - 如何从 HAPROXY 中禁用特定的密码套件 - 我可以这样做吗 "ssl-default-bind-ciphers no RC4-MD5"

    c# - 由该代码生成的 ID 的安全性如何?

    math - 带圆圈的加号是什么意思?

    python - 如何找到 EC key python-cryptography 的 ASN.1 组件

    SSL 证书不是来自托管服务提供商

    python - ssl.SSLError : [SSL: SSLV3_ALERT_BAD_RECORD_MAC] sslv3 alert bad record mac

    java - OpenSSL 和 Java 产生不同的 SHA256 RSA 签名

    java - OpenSSL AES/CBC 256 命令输出与 java 代码输出不匹配