CSR上的phpseclib $ X509-> setDomain?

时间:2015-02-18 21:47:49

标签: x509 phpseclib

是否可以在CSR上为subjectAltName设置x509 v3扩展属性?

我能够成功生成CSR,然后将其传递给CA进行签名。

CA可以调用X509-> setDomain(" bob.com"," * .bob.com"," asdf.org&#34)等功能);并且它们出现在最终证书中没有问题(注意:我正在执行签名,重新加载,设置扩展,为phpseclib重新签名解决方法)。

CSR流程调用相同的函数$ X509-> setExtension(" id-ce-subjectAltName",array(" names"," here") )或$ X509-> setDomain(" domain1"," domain2");似乎没有在CSR本身设置一些X509扩展属性(openssl可以),我只能在第二次签名之前重新导入后由CA添加SAN。

谢谢!

编辑:我创建了一个示例CSR(签名,重新加载,x509v3扩展,重新签名解决方法),似乎可以设置SOME扩展属性(CA:false,密钥用法等),但不是subjectAltName信息:

-----BEGIN CERTIFICATE REQUEST-----
MIIC1TCCAb8CAQAwVDELMAkGA1UEBgwCU1MxEDAOBgNVBAgMB09ic2N1cmUxDzAN
BgNVBAcMBlNlY3VyZTEQMA4GA1UECgwHYm9iY29ycDEQMA4GA1UEAwwHYm9iLmNv
bTCCASAwCwYJKoZIhvcNAQEBA4IBDwAwggEKAoIBAQCunNrjxEOILsESZ1osUkT3
zSeAHlzNiCBQnc/Xf+oW7Ir7wKfbHkV10cM583mw3Zy8rlCT/lUq0H+f3Uoc5/FA
dsYWhatlJRlTjv+yjSsxyB9i/hZ/KliP3Ix2O+Pq1wZIWfvk40hmCHHSB6YDtqt0
vXqUTIhH3SfyLtK9nd/6WG8bgIq9jgL6xvF3h44ynEwkuOnHt4a9WrflGX4KKcwo
OM98M/TAntDgSXBEYoLxenIbl3ypa7gtghVHHls3QOSay5QM87K3PJ3kSWVlZ3tN
tZGfbFdLiS+3MH8G3ujSX8XYeBnUj5jXi4SzpzQ9o5pyArL8DD8kC/Q9P/el1aZb
AgMBAAGgQDA+BgkqhkiG9w0BCQ4xMTAvMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/
BAwwCgYIKwYBBQUHAwEwBwYDVR0RBAAwCwYJKoZIhvcNAQELA4IBAQAUIhgLf6LH
WwhncU+yrNy6yHPHjFbipehUaS/Wa6FBbANpLyEdslqNwFD2FyXofSQVCB0L6VnH
NNXHcfZqWOT8+Xd0yNmfr/w+vg+s1yY4S0VAG6mxGsqwdIJqgXm2jaw0rMpzRs/k
wfOpJ+gyRTrQz9VJrn4xC4Uv6zTGNj56qZehDievW74SGISbGzj7AGmCxpp5/qZD
LN4Ls3wZ7I4TfuYZDh7qWuFwEAEEv40JPF2qO3VitvyAYrKg3bnUlFzQrOsfs4Ot
xzihLwkFEobih1bOEhzTnSv+lMckfw0DQ5Eb8mtFTC+/KOqEMMU5Hq1fm3B9Bkgs
FmqQZk4QlerY
-----END CERTIFICATE REQUEST-----

4 个答案:

答案 0 :(得分:1)

我想通了,phpseclib中的SignCSR函数没有重新启动setDomain函数,或者$ this->域数组中的任何内容,但是可以手动编码并强制设置主题alt名称:

$OPTIONS["altnames"] = array(
                                "bob.com",
                                "10.123.123.123",
                                "*.bob.com",
                                "asdf.fdsa",
                            );

        $ALTNAMES = $this->altnames($OPTIONS["altnames"]);
        if ( count($ALTNAMES) )
        { 
            $CSR->setExtension("id-ce-subjectAltName"   , $ALTNAMES );
        }

protected function altnames($ALTNAMES)
{ 
    //Sort names and IPs into two different arrays
    $DOMAINS = array(); $IPS = array();
    foreach ($ALTNAMES as $ALTNAME)
    { 
        if ( filter_var($ALTNAME, FILTER_VALIDATE_IP) )
        {
            array_push($IPS,$ALTNAME);
        }else{
            array_push($DOMAINS,$ALTNAME);
        }
    }
    // Create our altname array for the subjectAltName parser
    $RETURN = array();
    foreach ($DOMAINS as $DOMAIN)   { array_push($RETURN, array("dNSName"   => $DOMAIN  ) ); }
    foreach ($IPS as $IP)           { array_push($RETURN, array("iPAddress" => $IP      ) ); }
    return $RETURN;
}

现在,我发现的一个警告(这是phpseclib要考虑的一个功能问题)是缺乏IPv6支持。如果您在altnames数组(2620:153 :: 1234)中提供有效的IPv6地址,它将转换为IP地址:0.0.0.0,因为使用了X509代码中嵌入的IP2LONG和LONG2IP。

虽然不是我的用例的一个showstopper,但这是一个小麻烦,我已经尝试使用自定义IP2BIN和BIN2IP功能替换库中IP的编码和解码逻辑,但没有取得很大成功。

使用上面的代码生成的CSR示例:

-----BEGIN CERTIFICATE REQUEST-----
MIIC/DCCAeYCAQAwVDELMAkGA1UEBgwCU1MxEDAOBgNVBAgMB09ic2N1cmUxDzAN
BgNVBAcMBlNlY3VyZTEQMA4GA1UECgwHYm9iY29ycDEQMA4GA1UEAwwHYm9iLmNv
bTCCASAwCwYJKoZIhvcNAQEBA4IBDwAwggEKAoIBAQDOGLdjEr2IyW27e08hmRN+
Bcu4uOWAWEvxvY3+5pHdBQQEXhww5YQuEvpmgbKtav0j7aqFPDYNSXTv+aQNe9fq
cP3nZmKAWU+qbQMjWxwV9mEJOlWI214v7C8lLbMvBlny141J7KTvv1TGGLCBH/V2
EnQSdJzGDwXmJ2k0iChlQ7zl1TlonamYX9gefzp3N/DDp6kNhuPSX9zRorYIp5CC
WEIRmDdegwxHACrNu0K4xwuPjTRJf0oUkRsfBuDxqvBalQ0bzd/23fiQ51MEVla3
fUWL/+b2SKOlvgfu0XbfZ+Qx21DeyRQpqIWnv0gR4AM8qltxUgRjZloUfK5IQ8rp
AgMBAAGgZzBlBgkqhkiG9w0BCQ4xWDBWMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/
BAwwCgYIKwYBBQUHAwEwLgYDVR0RBCcwJYIHYm9iLmNvbYIJKi5ib2IuY29tgglh
c2RmLmZkc2GHBAp7e3swCwYJKoZIhvcNAQELA4IBAQAf1Vlt09ZBhVpxlmi+n93u
Gm8fNrd5afeIzWj0h4dFGJSOg5T8SkfL5txk2C9tQEdayQWB1kllx5rIqXAPe6gz
kbcjJn8l2IB3khIoKYmylmtV8Yo0Fl/Xba1oLCAsixbK+UxiSLgXqMryz9DBy40s
5oYXpy5JOnqL7BRC7b+Lk/chw7CcncPZI4rei6HM8WATymTySdrPoQegvBj0VIar
qHBZrMV9lsjTREJ9hvA/FycA/PNlP9y8N+eTF9SBrnTi8ix+v+Iirc43xeD2EVLG
6uqXecClji6OEOKcdDsH0D0HD1PMFmKB0FWvq71dt7eVIHkTPwTLFG2XAjfn6Fb8
-----END CERTIFICATE REQUEST-----

解码为:

Certificate Request:
Data:
    Version: 0 (0x0)
    Subject: C=SS, ST=Obscure, L=Secure, O=bobcorp, CN=bob.com
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
            Public-Key: (2048 bit)
            Modulus:
                00:ce:18:b7:63:12:bd:88:c9:6d:bb:7b:4f:21:99:
                13:7e:05:cb:b8:b8:e5:80:58:4b:f1:bd:8d:fe:e6:
                91:dd:05:04:04:5e:1c:30:e5:84:2e:12:fa:66:81:
                b2:ad:6a:fd:23:ed:aa:85:3c:36:0d:49:74:ef:f9:
                a4:0d:7b:d7:ea:70:fd:e7:66:62:80:59:4f:aa:6d:
                03:23:5b:1c:15:f6:61:09:3a:55:88:db:5e:2f:ec:
                2f:25:2d:b3:2f:06:59:f2:d7:8d:49:ec:a4:ef:bf:
                54:c6:18:b0:81:1f:f5:76:12:74:12:74:9c:c6:0f:
                05:e6:27:69:34:88:28:65:43:bc:e5:d5:39:68:9d:
                a9:98:5f:d8:1e:7f:3a:77:37:f0:c3:a7:a9:0d:86:
                e3:d2:5f:dc:d1:a2:b6:08:a7:90:82:58:42:11:98:
                37:5e:83:0c:47:00:2a:cd:bb:42:b8:c7:0b:8f:8d:
                34:49:7f:4a:14:91:1b:1f:06:e0:f1:aa:f0:5a:95:
                0d:1b:cd:df:f6:dd:f8:90:e7:53:04:56:56:b7:7d:
                45:8b:ff:e6:f6:48:a3:a5:be:07:ee:d1:76:df:67:
                e4:31:db:50:de:c9:14:29:a8:85:a7:bf:48:11:e0:
                03:3c:aa:5b:71:52:04:63:66:5a:14:7c:ae:48:43:
                ca:e9
            Exponent: 65537 (0x10001)
    Attributes:
    Requested Extensions:
        X509v3 Basic Constraints: critical
            CA:FALSE
        X509v3 Extended Key Usage: critical
            TLS Web Server Authentication
        X509v3 Subject Alternative Name: 
            DNS:bob.com, DNS:*.bob.com, DNS:asdf.fdsa, IP Address:10.123.123.123
Signature Algorithm: sha256WithRSAEncryption
     1f:d5:59:6d:d3:d6:41:85:5a:71:96:68:be:9f:dd:ee:1a:6f:
     1f:36:b7:79:69:f7:88:cd:68:f4:87:87:45:18:94:8e:83:94:
     fc:4a:47:cb:e6:dc:64:d8:2f:6d:40:47:5a:c9:05:81:d6:49:
     65:c7:9a:c8:a9:70:0f:7b:a8:33:91:b7:23:26:7f:25:d8:80:
     77:92:12:28:29:89:b2:96:6b:55:f1:8a:34:16:5f:d7:6d:ad:
     68:2c:20:2c:8b:16:ca:f9:4c:62:48:b8:17:a8:ca:f2:cf:d0:
     c1:cb:8d:2c:e6:86:17:a7:2e:49:3a:7a:8b:ec:14:42:ed:bf:
     8b:93:f7:21:c3:b0:9c:9d:c3:d9:23:8a:de:8b:a1:cc:f1:60:
     13:ca:64:f2:49:da:cf:a1:07:a0:bc:18:f4:54:86:ab:a8:70:
     59:ac:c5:7d:96:c8:d3:44:42:7d:86:f0:3f:17:27:00:fc:f3:
     65:3f:dc:bc:37:e7:93:17:d4:81:ae:74:e2:f2:2c:7e:bf:e2:
     22:ad:ce:37:c5:e0:f6:11:52:c6:ea:ea:97:79:c0:a5:8e:2e:
     8e:10:e2:9c:74:3b:07:d0:3d:07:0f:53:cc:16:62:81:d0:55:
     af:ab:bd:5d:b7:b7:95:20:79:13:3f:04:cb:14:6d:97:02:37:
     e7:e8:56:fc

答案 1 :(得分:1)

好吧,我想我找到了一个"功能"在phpseclib的X509签名功能中:

function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption')

如果您对CSR签名,则sign函数中的代码声称要复制X509 v3扩展属性,但是当它执行此行时:

$csrexts = $subject->getAttribute('pkcs-9-at-extensionRequest', 0);

结果总是空白(空数组),$ THIS(新)证书中的属性被覆盖在前30行代码中的某处。

我将csrexts行移到了Sign函数的顶部,现在正在将属性正确复制到CSR中具有X509扩展属性的生成证书中(必须手动计算并由我之前的答案设置)

我将使用sourceforge尝试发布错误请求以保存其他人的希望。

答案 2 :(得分:0)

好的,所以我使用PHPSecLib文档中的示例并使用它好几个小时来完成这项工作。也许这是2月份之后添加的内容,但无论如何,这里是如何使用主题备用名称生成CSR:

    $privKey = new Crypt_RSA();
    extract($privKey->createKey());
    $privKey->loadKey($privatekey);

    $x509 = new File_X509();
    $x509->setPrivateKey($privKey);
    $x509->setDNProp('id-at-organizationName', 'Company');
    $x509->setDNProp('id-at-organizationalUnitName', 'CompanyDepartment');
    $x509->setDNProp('id-at-commonName', 'myurl.com');
    $x509->setDNProp('id-at-localityName', $this->application);

    $x509->loadCSR($x509->saveCSR($x509->signCSR()));

    // Set extension request.
    $x509->setExtension("id-ce-subjectAltName", [
        ['dNSName' => 'myalternativename.com', 'iPAddress' => 127.0.0.1]
    ]);

    echo $x509->saveCSR($x509->signCSR());

这应该用myalternativename.com作为SAN打印出CSR。

答案 3 :(得分:0)

该错误在2020年仍然存在。

此错误的原因是需要有效的$ x509-> currentCert数组。 setExtension()函数对空的currentCert数组无效。 currentCert数组结构等于signCSR()函数的结果。因此,您可以将其初始化如下:#@splits = map {exists $oneshot_replacement{$_} ? $oneshot_replacement{$_} : $_} @splits ; @splits = map {exists $oneshot_replacement{$_} ? $oneshot_replacement{$_} : exists $pattern2replacement{$_} ? $pattern2replacement{$_} : $_} @splits ; 现在,您可以调用setExtension()函数。

以下是如何使用SAN属性生成CSR的完整示例:

$x509->currentCert = $x509->signCSR();